[Solução]: Quirk para NovaDigital TS0601 4 botões funcionando perfeitamente no ZHA

EDITANDO PARA INCLUIR UMA ATUALIZAÇÃO DAS ENTIDADES FALTANTES.
EDITANDO PARA INCLUIR UMA ATUALIZAÇÃO DAS ENTIDADES FALTANTES.

:tada: Problema Resolvido: NovaDigital TS0601 no ZHA

Pessoal, depois de muito teste consegui fazer funcionar os interruptores NovaDigital TS0601 de 4 botões no ZHA do Home Assistant!

O Problema

  • Dispositivo pareava normalmente no ZHA
  • Apareciam apenas entidades de diagnóstico (LQI/RSSI)
  • Nenhum switch funcionava
  • Funcionava perfeitamente no Zigbee2MQTT, mas não no ZHA

Modelos Testados

  • _TZE284_8jqvnitg
  • _TZE204_wskr3up8

A Solução: Quirk Customizado
Criei um quirk usando o método moderno TuyaQuirkBuilder que funciona 100%:

  • Passo 1: Criar a pasta custom_zha_quirks na raiz do HA
  • Passo 2: Criar arquivo ts0601_novadigital.py com este código:

““Quirk customizado para NovaDigital TS0601 6-gang (4 switches + 2 tomadas).””

from zigpy.quirks.v2 import EntityType
import zigpy.types as t
from zhaquirks.tuya.builder import TuyaQuirkBuilder

class PowerOnBehavior(t.enum8):
““Enum para comportamento após queda de energia.””
Desligado = 0x00 # Sempre desligado
Ligado = 0x01 # Sempre ligado
Ultimo_Estado = 0x02 # Restaura estado anterior

class IndicatorMode(t.enum8):
““Enum para modo do LED indicador.””
Desligado = 0x00 # LED sempre desligado
Sincronizado = 0x01 # LED sincronizado com switch
Invertido = 0x02 # LED invertido (para encontrar no escuro)

Quirk para NovaDigital TS0601 6-gang - Modelo _TZE284_8jqvnitg

(
TuyaQuirkBuilder(“_TZE284_8jqvnitg”, “TS0601”)
# Switches principais (DPs 1-4)
.tuya_switch(
dp_id=1,
attribute_name=“on_off_1”,
entity_type=EntityType.STANDARD,
translation_key=“switch_1”,
fallback_name=“Interruptor 1”,
)
.tuya_switch(
dp_id=2,
attribute_name=“on_off_2”,
entity_type=EntityType.STANDARD,
translation_key=“switch_2”,
fallback_name=“Interruptor 2”,
)
.tuya_switch(
dp_id=3,
attribute_name=“on_off_3”,
entity_type=EntityType.STANDARD,
translation_key=“switch_3”,
fallback_name=“Interruptor 3”,
)
.tuya_switch(
dp_id=4,
attribute_name=“on_off_4”,
entity_type=EntityType.STANDARD,
translation_key=“switch_4”,
fallback_name=“Interruptor 4”,
)
# Tomadas (DPs 5-6)
.tuya_switch(
dp_id=5,
attribute_name=“socket_1”,
entity_type=EntityType.STANDARD,
translation_key=“socket_1”,
fallback_name=“Tomada 1”,
)
.tuya_switch(
dp_id=6,
attribute_name=“socket_2”,
entity_type=EntityType.STANDARD,
translation_key=“socket_2”,
fallback_name=“Tomada 2”,
)
# Modo ao Ligar Global (DP 14)
.tuya_enum(
dp_id=14,
attribute_name=“power_on_behavior”,
enum_class=PowerOnBehavior,
entity_type=EntityType.CONFIG,
translation_key=“power_on_behavior”,
fallback_name=“Modo ao Ligar”,
)
# Modo do LED Indicador (DP 15)
.tuya_enum(
dp_id=15,
attribute_name=“indicator_mode”,
enum_class=IndicatorMode,
entity_type=EntityType.CONFIG,
translation_key=“indicator_mode”,
fallback_name=“Modo do LED Indicador”,
)
.skip_configuration()
.add_to_registry()
)

Quirk para modelo alternativo _TZE204_wskr3up8

(
TuyaQuirkBuilder(“_TZE204_wskr3up8”, “TS0601”)
# Switches principais (DPs 1-4)
.tuya_switch(
dp_id=1,
attribute_name=“on_off_1”,
entity_type=EntityType.STANDARD,
translation_key=“switch_1”,
fallback_name=“Interruptor 1”,
)
.tuya_switch(
dp_id=2,
attribute_name=“on_off_2”,
entity_type=EntityType.STANDARD,
translation_key=“switch_2”,
fallback_name=“Interruptor 2”,
)
.tuya_switch(
dp_id=3,
attribute_name=“on_off_3”,
entity_type=EntityType.STANDARD,
translation_key=“switch_3”,
fallback_name=“Interruptor 3”,
)
.tuya_switch(
dp_id=4,
attribute_name=“on_off_4”,
entity_type=EntityType.STANDARD,
translation_key=“switch_4”,
fallback_name=“Interruptor 4”,
)
# Tomadas (DPs 5-6)
.tuya_switch(
dp_id=5,
attribute_name=“socket_1”,
entity_type=EntityType.STANDARD,
translation_key=“socket_1”,
fallback_name=“Tomada 1”,
)
.tuya_switch(
dp_id=6,
attribute_name=“socket_2”,
entity_type=EntityType.STANDARD,
translation_key=“socket_2”,
fallback_name=“Tomada 2”,
)
# Modo ao Ligar Global (DP 14)
.tuya_enum(
dp_id=14,
attribute_name=“power_on_behavior”,
enum_class=PowerOnBehavior,
entity_type=EntityType.CONFIG,
translation_key=“power_on_behavior”,
fallback_name=“Modo ao Ligar”,
)
# Modo do LED Indicador (DP 15)
.tuya_enum(
dp_id=15,
attribute_name=“indicator_mode”,
enum_class=IndicatorMode,
entity_type=EntityType.CONFIG,
translation_key=“indicator_mode”,
fallback_name=“Modo do LED Indicador”,
)
.skip_configuration()
.add_to_registry()
)

1 curtida

Obrigado. Resolveu legal para o de 6 botoes fisicos.

Olá.

Eu comprei um Interruptor Zigbee de 6 teclas físicas da Nova Digital, e estou passando pelo mesmo erro.
Você pode mostrar qual o conteúdo completo do seu arquivo personalizado py, e também o que incluiu no configuration.yaml?


Ah, uma informação importante…
Eu também tenho 2 módulos 3-gang (teclas físicas) e 1 módulo 2-gang+1outlet (teclas físicas), todos também da Nova Digital.

Esses outros 3 estão funcionando sem problemas, todos adicionados com sucesso no ZHA nativo do HAss, com o dongle da Sonoff versão E com última versão do firmware.
Mas ao adicionar somente esse 6gang, não funciona.

Quero saber como devo configurar propriamente somente para esse sem interferir nos já existentes.

Baseado em outros posts e em outros fóruns, estava colocando dessa forma:

File: /custom_zha_quirks/ts0601_novadigital.py

"""Tuya DP based switches."""

from zigpy.profiles import zgp, zha
from zigpy.zcl.clusters.general import Basic, GreenPowerProxy, Groups, Ota, Scenes, Time

from zhaquirks.const import (
    DEVICE_TYPE,
    ENDPOINTS,
    INPUT_CLUSTERS,
    MODELS_INFO,
    OUTPUT_CLUSTERS,
    PROFILE_ID,
)
from zhaquirks.quirk_ids import TUYA_PLUG_MANUFACTURER
from zhaquirks.tuya import TuyaSwitch
from zhaquirks.tuya.mcu import (
    MoesSwitchManufCluster,
    TuyaOnOff,
    TuyaOnOffManufCluster,
    TuyaOnOffNM,
)

class TuyaSextupleSwitchTO(TuyaSwitch):
    """Tuya sextuple channel switch time on out cluster device."""

    quirk_id = TUYA_PLUG_MANUFACTURER

    signature = {
        # <SimpleDescriptor endpoint=1 profile=260 device_type=81
        # input_clusters=[0x0000,0x0004,0x0005,0xEF00]
        # output_clusters=[0x000A,0x0019]>
        MODELS_INFO: [
            ("_TZE204_g4au0afs", "TS0601"),
        ],
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaOnOffManufCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            }
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaOnOffManufCluster,
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
            2: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            3: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            4: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            5: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            6: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
        }
    }


class TuyaSextupleSwitchTOGP(TuyaSwitch):
    """Tuya sextuple channel switch time on out cluster device with GreenPowerProxy cluster device."""

    quirk_id = TUYA_PLUG_MANUFACTURER

    signature = {
        MODELS_INFO: [
            ("_TZE204_g4au0afs", "TS0601"),
        ],
        ENDPOINTS: {
            # <SimpleDescriptor endpoint=1 profile=260 device_type=81
            # input_clusters=[0x0000,0x0004,0x0005,0xEF00]
            # output_clusters=[0x000A,0x0019]>
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaOnOffManufCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
            # <SimpleDescriptor endpoint=242 profile=41440 device_type=97
            # input_clusters=[]
            # output_clusters=[33]
            242: {
                PROFILE_ID: zgp.PROFILE_ID,
                DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
                INPUT_CLUSTERS: [],
                OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
            },
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaOnOffManufCluster,
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
            2: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            3: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            4: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            5: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            6: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            242: {
                PROFILE_ID: zgp.PROFILE_ID,
                DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
                INPUT_CLUSTERS: [],
                OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
            },
        }
    }



    """Tuya x16 channels switch with GreenPowerProxy cluster device."""

    signature = {
        MODELS_INFO: [
            ("_TZE204_vmcgja59", "TS0601"),
        ],
        ENDPOINTS: {
            # <SimpleDescriptor endpoint=1 profile=260 device_type=81
            # input_clusters=[0x0000,0x0004,0x0005,0xEF00]
            # output_clusters=[0x000A,0x0019]>
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaOnOffManufCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
            # <SimpleDescriptor endpoint=242 profile=41440 device_type=97
            # input_clusters=[]
            # output_clusters=[33]
            242: {
                PROFILE_ID: zgp.PROFILE_ID,
                DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
                INPUT_CLUSTERS: [],
                OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
            },
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaOnOffManufCluster,
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
            2: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            3: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            4: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            5: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            6: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            7: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            8: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            9: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            10: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            11: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            12: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            13: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            14: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            15: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            16: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [],
            },
            242: {
                PROFILE_ID: zgp.PROFILE_ID,
                DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
                INPUT_CLUSTERS: [],
                OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
            },
        }
    }

Configuration file: configuration.py

# Nova Digital
zha:
    enable_quirks: true
    custom_quirks_path: custom_zha_quirks/

Ele até habilita o switch de 6 botões, mas ae falha 1 dos de 3gang switch, e todos meus endpoints (sensores) falham também.

Alguém conseguiu fazer funcionar o Nova digital 4 botões? Meu modelo é _TZE284_tayx2ud6 TS0601. Alguém sabe como entender o que fazer para criar certo o quirk? Como sei quais valores colocar? Como descobrir isso?