Hello tout le monde,
Je suis déjà passé par la case présentation, mais c’est la première fois que je viens demander un peu d’aide.
Mon système est composé d’équipements zigbee. J’étais d’abord sous zigbee2mqtt mais trop instable et surtout niveau RAM trop limite. Je suis donc passé sous zha. Mais un équipement (OWON pc321) n’est pas reconnu correctement.
J’ai beaucoup parcouru les docs, et les différents exemple de quirk.
Je suis parvenu à en faire un qui fonctionne. J’accède à tous les attributs et j’arrive à les lire manuellement.
Par contre, si je fais une inclusion sans mon quirk, 2 capteurs sont détectés, et donc utilisable comme entité. Voilà une image.
Lorsque j’utilise mon quirk personnalisé, je n’ai rien du tout. Et là je cale. J’ai tenté beaucoup de choses mais ça ne fonctionne pas.
Pour l’instant, j’utilise zha toolkit, ce qui avec un script me permets de récupérer des valeurs, mais c’est pas le top.
Si quelqu’un a une idée, je suis preneur .
Voilà mon quirk :
import logging
import zigpy.types as t
from zigpy.profiles import zha
from zigpy.quirks import CustomCluster, CustomDevice
from zigpy.zcl.foundation import ZCLAttributeDef, ZCLCommandDef
from zigpy.zcl.clusters.general import (
Basic,
Identify,
)
from zigpy.zcl.clusters.smartenergy import (
Metering,
)
from zhaquirks.const import (
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
MODELS_INFO,
OUTPUT_CLUSTERS,
PROFILE_ID,
SKIP_CONFIGURATION,
)
from zhaquirks import Bus, LocalDataCluster
_LOGGER = logging.getLogger(__name__)
""" definitions cluster """
class SimpleMetering(CustomCluster):
cluster_id = 0x0702
name = "Owon Simple Metering dbl"
ep_attribute = "simple_metering"
POWER_L = 0x2000
def __init__(self, *args, **kwargs):
"""Init electrical measurement cluster."""
super().__init__(*args, **kwargs)
self.endpoint.device.power_bus.add_listener(self)
def power_reported(self, value):
"""Report consumption."""
self._update_attribute(self.POWER_L, value)
attributes: dict[int, ZCLAttributeDef] = {
0x0000: ZCLAttributeDef("current_summ_delivered", type=t.uint48_t, access="r", mandatory=True),
0x0017: ZCLAttributeDef("Inlet_temperature", type=t.uint24_t, access="r", mandatory=True),
0x0200: ZCLAttributeDef("Status", type=t.bitmap8, access="r", mandatory=True),
0x0300: ZCLAttributeDef("unit_of_measure", type=t.enum8, access="r", mandatory=True),
0x0301: ZCLAttributeDef("multiplier", type=t.uint24_t, access="r", mandatory=True),
0x0302: ZCLAttributeDef("divisor", type=t.uint24_t, access="r", mandatory=True),
0x0303: ZCLAttributeDef("summation_formatting", type=t.bitmap8, access="r", mandatory=True),
0x0304: ZCLAttributeDef("demand_formatting", type=t.bitmap8, access="r", mandatory=True),
0x0306: ZCLAttributeDef("metering_device_type", type=t.bitmap8, access="r", mandatory=True),
0x0400: ZCLAttributeDef("Instantaneous_Demand", type=t.uint24_t, access="rw", mandatory=True),
0x1000: ZCLAttributeDef("report_map", type=t.bitmap8, access="rw", mandatory=True, is_manufacturer_specific=True),
0x2000: ZCLAttributeDef("L1_phase_power", type=t.uint24_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x2001: ZCLAttributeDef("L2_phase_power", type=t.uint24_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x2002: ZCLAttributeDef("L3_phase_power", type=t.uint24_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x2100: ZCLAttributeDef("L1_phase_reactive_power", type=t.uint24_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x2101: ZCLAttributeDef("L2_phase_reactive_power", type=t.uint24_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x2102: ZCLAttributeDef("L3_phase_reactive_power", type=t.uint24_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x2103: ZCLAttributeDef("reactive_power_summation_of_the_3_phases", type=t.uint24_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x3000: ZCLAttributeDef("L1_phase_voltage", type=t.uint24_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x3001: ZCLAttributeDef("L2_phase_voltage", type=t.uint24_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x3002: ZCLAttributeDef("L3_phase_voltage", type=t.uint24_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x3100: ZCLAttributeDef("L1_phase_current", type=t.uint24_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x3101: ZCLAttributeDef("L2_phase_current", type=t.uint24_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x3102: ZCLAttributeDef("L3_phase_current", type=t.uint24_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x3103: ZCLAttributeDef("current_summation_of_the_3_phases", type=t.uint24_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x3104: ZCLAttributeDef("leakage_current", type=t.uint24_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x4000: ZCLAttributeDef("L1_phase_energy_consumption", type=t.uint48_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x4001: ZCLAttributeDef("L2_phase_energy_consumption", type=t.uint48_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x4002: ZCLAttributeDef("L3_phase_energy_consumption", type=t.uint48_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x4100: ZCLAttributeDef("L1_phase_reactive_energy_consumption", type=t.uint48_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x4101: ZCLAttributeDef("L2_phase_reactive_energy_consumption", type=t.uint48_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x4102: ZCLAttributeDef("L3_phase_reactive_energy_consumption", type=t.uint48_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x4103: ZCLAttributeDef("reactive_energy_summation_of_the_3_phases", type=t.uint48_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x5000: ZCLAttributeDef("the_latest_historical_record_time", type=t.uint32_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x5001: ZCLAttributeDef("the_oldest_historical_recorded_time", type=t.uint32_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x5002: ZCLAttributeDef("set_minimum_cycle_for_report", type=t.uint32_t, access="rw", mandatory=True, is_manufacturer_specific=True),
0x5003: ZCLAttributeDef("set_maximum_cycle_for_report", type=t.uint32_t, access="rw", mandatory=True, is_manufacturer_specific=True),
0x5004: ZCLAttributeDef("sent_historical_record_state", type=t.uint8_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x5005: ZCLAttributeDef("frequency", type=t.uint8_t, access="r", mandatory=True, is_manufacturer_specific=True),
0x5006: ZCLAttributeDef("the_accumulative_threshold_of_energy", type=t.uint8_t, access="rw", mandatory=True, is_manufacturer_specific=True),
0x5007: ZCLAttributeDef("report_mode", type=t.uint8_t, access="rw", mandatory=True, is_manufacturer_specific=True),
0x5008: ZCLAttributeDef("Set_Z_percent_change_in_power", type=t.uint8_t, access="rw", mandatory=True, is_manufacturer_specific=True),
}
expose = [
0x2000, 0x2001, 0x2002
]
server_commands: dict[int, ZCLCommandDef] = {
0x20: ZCLCommandDef("get_history_record", {}, is_manufacturer_specific=True),
0x21: ZCLCommandDef("stop_sending_historical_record", {}, is_manufacturer_specific=True),
}
client_commands: dict[int, ZCLCommandDef] = {
0x20: ZCLCommandDef("sent_historical_record", {}, is_manufacturer_specific=True),
}
class ClearMetering(CustomCluster):
cluster_id = 0xFFE0
ep_attribute = "clear_metering"
attributes: dict[int, ZCLAttributeDef] = {}
server_commands: dict[int, ZCLCommandDef] = {
0x00: ZCLCommandDef("clear_measurement_data", {}, is_manufacturer_specific=True),
}
client_commands: dict[int, ZCLCommandDef] = {}
""" nouveau device Owon """
class Owon(CustomDevice):
def __init__(self, *args, **kwargs):
"""Init."""
self.voltage_bus = Bus()
self.consumption_bus = Bus()
self.power_bus = Bus()
super().__init__(*args, **kwargs)
signature = {
#MODELS_INFO: [("Owon", "PC321")],
ENDPOINTS: {
# <SimpleDescriptor endpoint=1 profile=260 device_type=13
# device_version=1
# input_clusters=[0, 3, 1794]
# output_clusters=[3]>
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.CONSUMPTION_AWARENESS_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Identify.cluster_id,
Metering.cluster_id,
],
OUTPUT_CLUSTERS: [Identify.cluster_id],
},
},
"manufacturer": "OWON Technology Inc.",
}
replacement = {
#SKIP_CONFIGURATION: True,
ENDPOINTS: {
# <SimpleDescriptor endpoint=1 profile=260 device_type=13
# device_version=1
# input_clusters=[0, 3, 1794]
# output_clusters=[3]>
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.CONSUMPTION_AWARENESS_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Identify.cluster_id,
SimpleMetering,
ClearMetering,
],
OUTPUT_CLUSTERS: [Identify.cluster_id],
},
},
}
Bonne soirée