Bonjour
J’ai finalement trouvé une heure.
En dupliquant la classe Switch_2G_GPP pour 3 et 4, ça fonctionne parfaitement aussi pour les références indiquées plus haut.
Ci après le fichier ( j’ai conservé le nom ts000xv2.py ):
import asyncio
from zigpy.profiles import zha
from zigpy.quirks import CustomDevice
from zigpy.zcl.clusters.general import (
Basic,
GreenPowerProxy,
Groups,
Identify,
OnOff,
Ota,
Scenes,
Time,
)
from zhaquirks.const import (
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
MODEL,
OUTPUT_CLUSTERS,
PROFILE_ID,
)
from zhaquirks.tuya import (
TuyaZBE000Cluster,
TuyaZBExternalSwitchTypeCluster,
TuyaZBOnOffAttributeCluster,
# modifs GP: ajout
TuyaZBElectricalMeasurement,
TuyaZBMeteringCluster,
# fin ajout
)
class TuyaMagicSpell(CustomDevice):
"""Cast a magic spell for Tuya devices that needed."""
def __init__(self, *args, **kwargs):
"""Initialize with task."""
super().__init__(*args, **kwargs)
# cast_tuya_magic_spell(self, tries=3)
self._init_plug_task = asyncio.create_task(self.spell())
async def spell(self) -> None:
"""Initialize device so that all endpoints become available."""
basic_cluster = self.endpoints[1].in_clusters[0]
self.debug("Device class will cast Tuya Magic Spell")
attr_to_read = [4, 0, 1, 5, 7, 0xFFFE]
await basic_cluster.read_attributes(attr_to_read)
class Switch_2G_GPP(TuyaMagicSpell, CustomDevice):
"""Tuya 2 gang switch module with restore power state support."""
signature = {
MODEL: "TS0002",
ENDPOINTS: {
# <SimpleDescriptor endpoint=1 profile=260 device_type=256
# device_version=1
# modifs GP : input_clusters=[3, 4, 5, 6, 1794, 2820,57344, 57345, 0]
# old : input_clusters=[0, 3, 4, 5, 6, 57344, 57345]
# output_clusters=[10, 25]>
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
#Modifs GP: ajout
TuyaZBMeteringCluster.cluster_id,
TuyaZBElectricalMeasurement.cluster_id,
#fin ajout
TuyaZBE000Cluster.cluster_id,
TuyaZBExternalSwitchTypeCluster.cluster_id,
#modif GP: basic déplacé à la fin
Basic.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
# <SimpleDescriptor endpoint=2 profile=260 device_type=256
# device_version=1
# input_clusters=[4, 5, 6, 57345]
# output_clusters=[]>
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
#modif GP: ligne suivante supprimée
#TuyaZBExternalSwitchTypeCluster.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
# <SimpleDescriptor endpoint=242 profile=41440 device_type=97
# device_version=0
# input_clusters=[]
# output_clusters=[33]>
242: {
PROFILE_ID: 41440,
DEVICE_TYPE: 97,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaZBOnOffAttributeCluster,
TuyaZBE000Cluster,
TuyaZBExternalSwitchTypeCluster,
#Modifs GP: ajout
TuyaZBMeteringCluster.cluster_id,
TuyaZBElectricalMeasurement.cluster_id,
#fin ajout
Basic.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
TuyaZBOnOffAttributeCluster,
#modif GP: ligne suivante supprimée
#TuyaZBExternalSwitchTypeCluster,
],
OUTPUT_CLUSTERS: [],
},
242: {
PROFILE_ID: 41440,
DEVICE_TYPE: 97,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
class Switch_3G_GPP(TuyaMagicSpell, CustomDevice):
"""Tuya 3 gang switch module with restore power state support."""
signature = {
MODEL: "TS0003",
ENDPOINTS: {
# <SimpleDescriptor endpoint=1 profile=260 device_type=256
# device_version=1
# modifs GP : input_clusters=[3, 4, 5, 6, 1794, 2820,57344, 57345, 0]
# old : input_clusters=[0, 3, 4, 5, 6, 57344, 57345]
# output_clusters=[10, 25]>
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
#Modifs GP: ajout
TuyaZBMeteringCluster.cluster_id,
TuyaZBElectricalMeasurement.cluster_id,
#fin ajout
TuyaZBE000Cluster.cluster_id,
TuyaZBExternalSwitchTypeCluster.cluster_id,
#modif GP: basic déplacé à la fin
Basic.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
# <SimpleDescriptor endpoint=2 profile=260 device_type=256
# device_version=1
# input_clusters=[4, 5, 6, 57345]
# output_clusters=[]>
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
#modif GP: ligne suivante supprimée
#TuyaZBExternalSwitchTypeCluster.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
# <SimpleDescriptor endpoint=3 profile=260 device_type=256
# device_version=1
# input_clusters=[4, 5, 6, 57345]
# output_clusters=[]>
3: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
#modif GP: ligne suivante supprimée
#TuyaZBExternalSwitchTypeCluster.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
# <SimpleDescriptor endpoint=242 profile=41440 device_type=97
# device_version=0
# input_clusters=[]
# output_clusters=[33]>
242: {
PROFILE_ID: 41440,
DEVICE_TYPE: 97,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaZBOnOffAttributeCluster,
TuyaZBE000Cluster,
TuyaZBExternalSwitchTypeCluster,
#Modifs GP: ajout
TuyaZBMeteringCluster.cluster_id,
TuyaZBElectricalMeasurement.cluster_id,
#fin ajout
Basic.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
TuyaZBOnOffAttributeCluster,
#modif GP: ligne suivante supprimée
#TuyaZBExternalSwitchTypeCluster,
],
OUTPUT_CLUSTERS: [],
},
3: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
TuyaZBOnOffAttributeCluster,
#modif GP: ligne suivante supprimée
#TuyaZBExternalSwitchTypeCluster,
],
OUTPUT_CLUSTERS: [],
},
242: {
PROFILE_ID: 41440,
DEVICE_TYPE: 97,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
class Switch_4G_GPP(TuyaMagicSpell, CustomDevice):
"""Tuya 4 gang switch module with restore power state support."""
signature = {
MODEL: "TS0004",
ENDPOINTS: {
# <SimpleDescriptor endpoint=1 profile=260 device_type=256
# device_version=1
# modifs GP : input_clusters=[3, 4, 5, 6, 1794, 2820,57344, 57345, 0]
# old : input_clusters=[0, 3, 4, 5, 6, 57344, 57345]
# output_clusters=[10, 25]>
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
#Modifs GP: ajout
TuyaZBMeteringCluster.cluster_id,
TuyaZBElectricalMeasurement.cluster_id,
#fin ajout
TuyaZBE000Cluster.cluster_id,
TuyaZBExternalSwitchTypeCluster.cluster_id,
#modif GP: basic déplacé à la fin
Basic.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
# <SimpleDescriptor endpoint=2 profile=260 device_type=256
# device_version=1
# input_clusters=[4, 5, 6, 57345]
# output_clusters=[]>
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
#modif GP: ligne suivante supprimée
#TuyaZBExternalSwitchTypeCluster.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
# <SimpleDescriptor endpoint=3 profile=260 device_type=256
# device_version=1
# input_clusters=[4, 5, 6, 57345]
# output_clusters=[]>
3: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
#modif GP: ligne suivante supprimée
#TuyaZBExternalSwitchTypeCluster.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
# <SimpleDescriptor endpoint=4 profile=260 device_type=256
# device_version=1
# input_clusters=[4, 5, 6, 57345]
# output_clusters=[]>
4: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
#modif GP: ligne suivante supprimée
#TuyaZBExternalSwitchTypeCluster.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
# <SimpleDescriptor endpoint=242 profile=41440 device_type=97
# device_version=0
# input_clusters=[]
# output_clusters=[33]>
242: {
PROFILE_ID: 41440,
DEVICE_TYPE: 97,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaZBOnOffAttributeCluster,
TuyaZBE000Cluster,
TuyaZBExternalSwitchTypeCluster,
#Modifs GP: ajout
TuyaZBMeteringCluster.cluster_id,
TuyaZBElectricalMeasurement.cluster_id,
#fin ajout
Basic.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
TuyaZBOnOffAttributeCluster,
#modif GP: ligne suivante supprimée
#TuyaZBExternalSwitchTypeCluster,
],
OUTPUT_CLUSTERS: [],
},
3: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
TuyaZBOnOffAttributeCluster,
#modif GP: ligne suivante supprimée
#TuyaZBExternalSwitchTypeCluster,
],
OUTPUT_CLUSTERS: [],
},
4: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
TuyaZBOnOffAttributeCluster,
#modif GP: ligne suivante supprimée
#TuyaZBExternalSwitchTypeCluster,
],
OUTPUT_CLUSTERS: [],
},
242: {
PROFILE_ID: 41440,
DEVICE_TYPE: 97,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
Je pense que la résolution définitive et stable serait l’inclusion de ce code dans le package zhaquirks. Si un dev passe par là … je ne sais pas trop ou publier, c’est une dépendance du plugin zigbee, pas dans le plugin lui-même …