diff --git a/tests/data/devices/ubisys-s1-5501.json b/tests/data/devices/ubisys-s1-5501.json new file mode 100644 index 000000000..54b138f83 --- /dev/null +++ b/tests/data/devices/ubisys-s1-5501.json @@ -0,0 +1,1465 @@ +{ + "version": 1, + "ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "nwk": "0x0DB4", + "manufacturer": "ubisys", + "model": "S1 (5501)", + "friendly_manufacturer": "ubisys", + "friendly_model": "S1 (5501)", + "name": "ubisys S1 (5501)", + "quirk_applied": false, + "quirk_class": "zigpy.device.Device", + "exposes_features": [], + "manufacturer_code": 4338, + "power_source": "Mains", + "lqi": 188, + "rssi": -53, + "last_seen": "2026-02-17T02:47:02.479977+00:00", + "available": true, + "device_type": "Router", + "active_coordinator": false, + "node_descriptor": { + "logical_type": "Router", + "complex_descriptor_available": false, + "user_descriptor_available": false, + "reserved": 0, + "aps_flags": 0, + "frequency_band": 8, + "mac_capability_flags": 142, + "manufacturer_code": 4338, + "maximum_buffer_size": 127, + "maximum_incoming_transfer_size": 242, + "server_mask": 11264, + "maximum_outgoing_transfer_size": 242, + "descriptor_capability_field": 0 + }, + "endpoints": { + "1": { + "profile_id": 260, + "device_type": { + "name": "ON_OFF_PLUG_IN_UNIT", + "id": 266 + }, + "in_clusters": [ + { + "cluster_id": "0x0000", + "endpoint_attribute": "basic", + "attributes": [ + { + "id": "0x0004", + "name": "manufacturer", + "zcl_type": "string", + "value": "ubisys" + }, + { + "id": "0x0005", + "name": "model", + "zcl_type": "string", + "value": "S1 (5501)" + } + ] + }, + { + "cluster_id": "0x0003", + "endpoint_attribute": "identify", + "attributes": [] + }, + { + "cluster_id": "0x0004", + "endpoint_attribute": "groups", + "attributes": [] + }, + { + "cluster_id": "0x0005", + "endpoint_attribute": "scenes", + "attributes": [] + }, + { + "cluster_id": "0x0006", + "endpoint_attribute": "on_off", + "attributes": [ + { + "id": "0x0000", + "name": "on_off", + "zcl_type": "bool", + "value": 1 + }, + { + "id": "0x4003", + "name": "start_up_on_off", + "zcl_type": "enum8", + "value": 255 + } + ] + } + ], + "out_clusters": [] + }, + "2": { + "profile_id": 260, + "device_type": { + "name": "DIMMER_SWITCH", + "id": 260 + }, + "in_clusters": [ + { + "cluster_id": "0x0000", + "endpoint_attribute": "basic", + "attributes": [] + }, + { + "cluster_id": "0x0003", + "endpoint_attribute": "identify", + "attributes": [] + } + ], + "out_clusters": [ + { + "cluster_id": "0x0003", + "endpoint_attribute": "identify", + "attributes": [] + }, + { + "cluster_id": "0x0005", + "endpoint_attribute": "scenes", + "attributes": [] + }, + { + "cluster_id": "0x0006", + "endpoint_attribute": "on_off", + "attributes": [] + }, + { + "cluster_id": "0x0008", + "endpoint_attribute": "level", + "attributes": [] + }, + { + "cluster_id": "0x0300", + "endpoint_attribute": "light_color", + "attributes": [] + }, + { + "cluster_id": "0xfc02", + "endpoint_attribute": "manufacturer_specific", + "attributes": [] + } + ] + }, + "3": { + "profile_id": 260, + "device_type": { + "name": "undefined_0x0501", + "id": 1281 + }, + "in_clusters": [ + { + "cluster_id": "0x0000", + "endpoint_attribute": "basic", + "attributes": [] + }, + { + "cluster_id": "0x0702", + "endpoint_attribute": "smartenergy_metering", + "attributes": [ + { + "id": "0x0000", + "name": "current_summ_delivered", + "zcl_type": "uint48", + "value": 0 + }, + { + "id": "0x0001", + "name": "current_summ_received", + "zcl_type": "uint48", + "value": 0 + }, + { + "id": "0x0100", + "name": "current_tier1_summ_delivered", + "zcl_type": "uint48", + "unsupported": true + }, + { + "id": "0x0102", + "name": "current_tier2_summ_delivered", + "zcl_type": "uint48", + "unsupported": true + }, + { + "id": "0x0104", + "name": "current_tier3_summ_delivered", + "zcl_type": "uint48", + "unsupported": true + }, + { + "id": "0x0106", + "name": "current_tier4_summ_delivered", + "zcl_type": "uint48", + "unsupported": true + }, + { + "id": "0x0108", + "name": "current_tier5_summ_delivered", + "zcl_type": "uint48", + "unsupported": true + }, + { + "id": "0x010a", + "name": "current_tier6_summ_delivered", + "zcl_type": "uint48", + "unsupported": true + }, + { + "id": "0x0304", + "name": "demand_formatting", + "zcl_type": "map8", + "unsupported": true + }, + { + "id": "0x0302", + "name": "divisor", + "zcl_type": "uint24", + "value": 1000 + }, + { + "id": "0x0400", + "name": "instantaneous_demand", + "zcl_type": "int24", + "value": 0 + }, + { + "id": "0x0306", + "name": "metering_device_type", + "zcl_type": "map8", + "unsupported": true + }, + { + "id": "0x0301", + "name": "multiplier", + "zcl_type": "uint24", + "value": 1 + }, + { + "id": "0x0200", + "name": "status", + "zcl_type": "map8", + "value": 0 + }, + { + "id": "0x0303", + "name": "summation_formatting", + "zcl_type": "map8", + "unsupported": true + }, + { + "id": "0x0300", + "name": "unit_of_measure", + "zcl_type": "enum8", + "value": 0 + } + ] + }, + { + "cluster_id": "0x0b04", + "endpoint_attribute": "electrical_measurement", + "attributes": [ + { + "id": "0x0603", + "name": "ac_current_divisor", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0602", + "name": "ac_current_multiplier", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0300", + "name": "ac_frequency", + "zcl_type": "uint16", + "value": 49766 + }, + { + "id": "0x0401", + "name": "ac_frequency_divisor", + "zcl_type": "uint16", + "value": 1000 + }, + { + "id": "0x0302", + "name": "ac_frequency_max", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0400", + "name": "ac_frequency_multiplier", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0605", + "name": "ac_power_divisor", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0604", + "name": "ac_power_multiplier", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0601", + "name": "ac_voltage_divisor", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0600", + "name": "ac_voltage_multiplier", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x050b", + "name": "active_power", + "zcl_type": "int16", + "value": 0 + }, + { + "id": "0x050d", + "name": "active_power_max", + "zcl_type": "int16", + "unsupported": true + }, + { + "id": "0x090d", + "name": "active_power_max_ph_b", + "zcl_type": "int16", + "unsupported": true + }, + { + "id": "0x0a0d", + "name": "active_power_max_ph_c", + "zcl_type": "int16", + "unsupported": true + }, + { + "id": "0x090b", + "name": "active_power_ph_b", + "zcl_type": "int16", + "unsupported": true + }, + { + "id": "0x0a0b", + "name": "active_power_ph_c", + "zcl_type": "int16", + "unsupported": true + }, + { + "id": "0x050f", + "name": "apparent_power", + "zcl_type": "uint16", + "value": 1 + }, + { + "id": "0x0103", + "name": "dc_current", + "zcl_type": "int16", + "unsupported": true + }, + { + "id": "0x0203", + "name": "dc_current_divisor", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0202", + "name": "dc_current_multiplier", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0106", + "name": "dc_power", + "zcl_type": "int16", + "unsupported": true + }, + { + "id": "0x0205", + "name": "dc_power_divisor", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0204", + "name": "dc_power_multiplier", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0100", + "name": "dc_voltage", + "zcl_type": "int16", + "unsupported": true + }, + { + "id": "0x0201", + "name": "dc_voltage_divisor", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0200", + "name": "dc_voltage_multiplier", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0000", + "name": "measurement_type", + "zcl_type": "map32", + "value": 15 + }, + { + "id": "0x0403", + "name": "power_divisor", + "zcl_type": "uint32", + "unsupported": true + }, + { + "id": "0x0510", + "name": "power_factor", + "zcl_type": "int8", + "value": 0 + }, + { + "id": "0x0910", + "name": "power_factor_ph_b", + "zcl_type": "int8", + "unsupported": true + }, + { + "id": "0x0a10", + "name": "power_factor_ph_c", + "zcl_type": "int8", + "unsupported": true + }, + { + "id": "0x0402", + "name": "power_multiplier", + "zcl_type": "uint32", + "unsupported": true + }, + { + "id": "0x0508", + "name": "rms_current", + "zcl_type": "uint16", + "value": 4 + }, + { + "id": "0x050a", + "name": "rms_current_max", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x090a", + "name": "rms_current_max_ph_b", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0a0a", + "name": "rms_current_max_ph_c", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0908", + "name": "rms_current_ph_b", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0a08", + "name": "rms_current_ph_c", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0505", + "name": "rms_voltage", + "zcl_type": "uint16", + "value": 232 + }, + { + "id": "0x0507", + "name": "rms_voltage_max", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0907", + "name": "rms_voltage_max_ph_b", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0a07", + "name": "rms_voltage_max_ph_c", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0905", + "name": "rms_voltage_ph_b", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0a05", + "name": "rms_voltage_ph_c", + "zcl_type": "uint16", + "unsupported": true + }, + { + "id": "0x0304", + "name": "total_active_power", + "zcl_type": "int32", + "value": 0 + } + ] + } + ], + "out_clusters": [] + }, + "232": { + "profile_id": 260, + "device_type": { + "name": "undefined_0x0507", + "id": 1287 + }, + "in_clusters": [ + { + "cluster_id": "0x0000", + "endpoint_attribute": "basic", + "attributes": [] + }, + { + "cluster_id": "0xfc00", + "endpoint_attribute": "manufacturer_specific", + "attributes": [] + } + ], + "out_clusters": [ + { + "cluster_id": "0x0003", + "endpoint_attribute": "identify", + "attributes": [] + }, + { + "cluster_id": "0x0019", + "endpoint_attribute": "ota", + "attributes": [ + { + "id": "0x0002", + "name": "current_file_version", + "zcl_type": "uint32", + "value": 39847008 + } + ] + } + ] + }, + "242": { + "profile_id": 41440, + "device_type": { + "name": "COMBO_BASIC", + "id": 102 + }, + "in_clusters": [ + { + "cluster_id": "0x0021", + "endpoint_attribute": "green_power", + "attributes": [] + } + ], + "out_clusters": [ + { + "cluster_id": "0x0021", + "endpoint_attribute": "green_power", + "attributes": [] + } + ] + } + }, + "original_signature": { + "manufacturer": "ubisys", + "model": "S1 (5501)", + "node_desc": { + "logical_type": 1, + "complex_descriptor_available": 0, + "user_descriptor_available": 0, + "reserved": 0, + "aps_flags": 0, + "frequency_band": 8, + "mac_capability_flags": 142, + "manufacturer_code": 4338, + "maximum_buffer_size": 127, + "maximum_incoming_transfer_size": 242, + "server_mask": 11264, + "maximum_outgoing_transfer_size": 242, + "descriptor_capability_field": 0 + }, + "endpoints": { + "1": { + "profile_id": "0x0104", + "device_type": "0x010a", + "input_clusters": [ + "0x0000", + "0x0003", + "0x0004", + "0x0005", + "0x0006" + ], + "output_clusters": [] + }, + "2": { + "profile_id": "0x0104", + "device_type": "0x0104", + "input_clusters": [ + "0x0000", + "0x0003" + ], + "output_clusters": [ + "0x0003", + "0x0005", + "0x0006", + "0x0008", + "0x0300", + "0xfc02" + ] + }, + "3": { + "profile_id": "0x0104", + "device_type": "0x0501", + "input_clusters": [ + "0x0000", + "0x0702", + "0x0b04" + ], + "output_clusters": [] + }, + "232": { + "profile_id": "0x0104", + "device_type": "0x0507", + "input_clusters": [ + "0x0000", + "0xfc00" + ], + "output_clusters": [ + "0x0003", + "0x0019" + ] + }, + "242": { + "profile_id": "0xa1e0", + "device_type": "0x0066", + "input_clusters": [ + "0x0021" + ], + "output_clusters": [ + "0x0021" + ] + } + } + }, + "zha_lib_entities": { + "button": [ + { + "info_object": { + "fallback_name": null, + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2-1-3", + "migrate_unique_ids": [], + "platform": "button", + "class_name": "IdentifyButton", + "translation_key": null, + "translation_placeholders": null, + "device_class": "identify", + "state_class": null, + "entity_category": "diagnostic", + "entity_registry_enabled_default": true, + "enabled": true, + "primary": false, + "cluster_handlers": [ + { + "class_name": "IdentifyClusterHandler", + "generic_id": "cluster_handler_0x0003", + "endpoint_id": 1, + "cluster": { + "id": 3, + "name": "Identify", + "type": "server" + }, + "id": "1:0x0003", + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2:1:0x0003", + "status": "INITIALIZED", + "value_attribute": null + } + ], + "device_ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "endpoint_id": 1, + "available": true, + "group_id": null, + "command": "identify", + "args": [ + 5 + ], + "kwargs": {} + }, + "state": { + "class_name": "IdentifyButton", + "available": true + } + } + ], + "select": [ + { + "info_object": { + "fallback_name": null, + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2-1-6-StartUpOnOff", + "migrate_unique_ids": [], + "platform": "select", + "class_name": "StartupOnOffSelectEntity", + "translation_key": "start_up_on_off", + "translation_placeholders": null, + "device_class": null, + "state_class": null, + "entity_category": "config", + "entity_registry_enabled_default": true, + "enabled": true, + "primary": false, + "cluster_handlers": [ + { + "class_name": "OnOffClusterHandler", + "generic_id": "cluster_handler_0x0006", + "endpoint_id": 1, + "cluster": { + "id": 6, + "name": "On/Off", + "type": "server" + }, + "id": "1:0x0006", + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2:1:0x0006", + "status": "INITIALIZED", + "value_attribute": "on_off" + } + ], + "device_ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "endpoint_id": 1, + "available": true, + "group_id": null, + "enum": "StartUpOnOff", + "options": [ + "Off", + "On", + "Toggle", + "PreviousValue" + ] + }, + "state": { + "class_name": "StartupOnOffSelectEntity", + "available": true, + "state": "PreviousValue" + } + } + ], + "sensor": [ + { + "info_object": { + "fallback_name": null, + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2-1-0-lqi", + "migrate_unique_ids": [], + "platform": "sensor", + "class_name": "LQISensor", + "translation_key": "lqi", + "translation_placeholders": null, + "device_class": null, + "state_class": "measurement", + "entity_category": "diagnostic", + "entity_registry_enabled_default": false, + "enabled": true, + "primary": false, + "cluster_handlers": [ + { + "class_name": "BasicClusterHandler", + "generic_id": "cluster_handler_0x0000", + "endpoint_id": 1, + "cluster": { + "id": 0, + "name": "Basic", + "type": "server" + }, + "id": "1:0x0000", + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2:1:0x0000", + "status": "INITIALIZED", + "value_attribute": null + } + ], + "device_ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "endpoint_id": 1, + "available": true, + "group_id": null, + "suggested_display_precision": null, + "unit": null + }, + "state": { + "class_name": "LQISensor", + "available": true, + "state": 188 + } + }, + { + "info_object": { + "fallback_name": null, + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2-1-0-rssi", + "migrate_unique_ids": [], + "platform": "sensor", + "class_name": "RSSISensor", + "translation_key": "rssi", + "translation_placeholders": null, + "device_class": "signal_strength", + "state_class": "measurement", + "entity_category": "diagnostic", + "entity_registry_enabled_default": false, + "enabled": true, + "primary": false, + "cluster_handlers": [ + { + "class_name": "BasicClusterHandler", + "generic_id": "cluster_handler_0x0000", + "endpoint_id": 1, + "cluster": { + "id": 0, + "name": "Basic", + "type": "server" + }, + "id": "1:0x0000", + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2:1:0x0000", + "status": "INITIALIZED", + "value_attribute": null + } + ], + "device_ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "endpoint_id": 1, + "available": true, + "group_id": null, + "suggested_display_precision": null, + "unit": "dBm" + }, + "state": { + "class_name": "RSSISensor", + "available": true, + "state": -53 + } + }, + { + "info_object": { + "fallback_name": null, + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2-3-1794", + "migrate_unique_ids": [], + "platform": "sensor", + "class_name": "SmartEnergyMetering", + "translation_key": "instantaneous_demand", + "translation_placeholders": null, + "device_class": "power", + "state_class": "measurement", + "entity_category": null, + "entity_registry_enabled_default": true, + "enabled": true, + "primary": false, + "cluster_handlers": [ + { + "class_name": "MeteringClusterHandler", + "generic_id": "cluster_handler_0x0702", + "endpoint_id": 3, + "cluster": { + "id": 1794, + "name": "Metering", + "type": "server" + }, + "id": "3:0x0702", + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2:3:0x0702", + "status": "INITIALIZED", + "value_attribute": "instantaneous_demand" + } + ], + "device_ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "endpoint_id": 3, + "available": true, + "group_id": null, + "suggested_display_precision": null, + "unit": "W" + }, + "state": { + "class_name": "SmartEnergyMetering", + "available": true, + "state": 0.0, + "status": "NO_ALARMS", + "zcl_unit_of_measurement": 0 + }, + "extra_state_attributes": [ + "device_type", + "status", + "zcl_unit_of_measurement" + ] + }, + { + "info_object": { + "fallback_name": null, + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2-3-1794-summation_delivered", + "migrate_unique_ids": [], + "platform": "sensor", + "class_name": "SmartEnergySummation", + "translation_key": "summation_delivered", + "translation_placeholders": null, + "device_class": "energy", + "state_class": "total_increasing", + "entity_category": null, + "entity_registry_enabled_default": true, + "enabled": true, + "primary": false, + "cluster_handlers": [ + { + "class_name": "MeteringClusterHandler", + "generic_id": "cluster_handler_0x0702", + "endpoint_id": 3, + "cluster": { + "id": 1794, + "name": "Metering", + "type": "server" + }, + "id": "3:0x0702", + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2:3:0x0702", + "status": "INITIALIZED", + "value_attribute": "instantaneous_demand" + } + ], + "device_ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "endpoint_id": 3, + "available": true, + "group_id": null, + "suggested_display_precision": 3, + "unit": "kWh" + }, + "state": { + "class_name": "SmartEnergySummation", + "available": true, + "state": 0.0, + "status": "NO_ALARMS", + "zcl_unit_of_measurement": 0 + }, + "extra_state_attributes": [ + "device_type", + "status", + "zcl_unit_of_measurement" + ] + }, + { + "info_object": { + "fallback_name": null, + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2-3-1794-summation_received", + "migrate_unique_ids": [], + "platform": "sensor", + "class_name": "SmartEnergySummationReceived", + "translation_key": "summation_received", + "translation_placeholders": null, + "device_class": "energy", + "state_class": "total_increasing", + "entity_category": null, + "entity_registry_enabled_default": true, + "enabled": true, + "primary": false, + "cluster_handlers": [ + { + "class_name": "MeteringClusterHandler", + "generic_id": "cluster_handler_0x0702", + "endpoint_id": 3, + "cluster": { + "id": 1794, + "name": "Metering", + "type": "server" + }, + "id": "3:0x0702", + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2:3:0x0702", + "status": "INITIALIZED", + "value_attribute": "instantaneous_demand" + } + ], + "device_ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "endpoint_id": 3, + "available": true, + "group_id": null, + "suggested_display_precision": 3, + "unit": "kWh" + }, + "state": { + "class_name": "SmartEnergySummationReceived", + "available": true, + "state": 0.0, + "status": "NO_ALARMS", + "zcl_unit_of_measurement": 0 + }, + "extra_state_attributes": [ + "device_type", + "status", + "zcl_unit_of_measurement" + ] + }, + { + "info_object": { + "fallback_name": null, + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2-3-2820", + "migrate_unique_ids": [], + "platform": "sensor", + "class_name": "UbisysPolledElectricalMeasurement", + "translation_key": null, + "translation_placeholders": null, + "device_class": "power", + "state_class": "measurement", + "entity_category": null, + "entity_registry_enabled_default": true, + "enabled": true, + "primary": false, + "cluster_handlers": [ + { + "class_name": "ElectricalMeasurementClusterHandler", + "generic_id": "cluster_handler_0x0b04", + "endpoint_id": 3, + "cluster": { + "id": 2820, + "name": "Electrical Measurement", + "type": "server" + }, + "id": "3:0x0b04", + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2:3:0x0b04", + "status": "INITIALIZED", + "value_attribute": "ac_voltage_multiplier" + } + ], + "device_ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "endpoint_id": 3, + "available": true, + "group_id": null, + "suggested_display_precision": 1, + "unit": "W" + }, + "state": { + "class_name": "UbisysPolledElectricalMeasurement", + "available": true, + "state": 0.0, + "measurement_type": "ACTIVE_MEASUREMENT, REACTIVE_MEASUREMENT, APPARENT_MEASUREMENT, PHASE_A_MEASUREMENT" + }, + "extra_state_attributes": [ + "active_power_max", + "measurement_type" + ] + }, + { + "info_object": { + "fallback_name": null, + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2-3-2820-ac_frequency", + "migrate_unique_ids": [], + "platform": "sensor", + "class_name": "ElectricalMeasurementFrequency", + "translation_key": "ac_frequency", + "translation_placeholders": null, + "device_class": "frequency", + "state_class": "measurement", + "entity_category": null, + "entity_registry_enabled_default": true, + "enabled": true, + "primary": false, + "cluster_handlers": [ + { + "class_name": "ElectricalMeasurementClusterHandler", + "generic_id": "cluster_handler_0x0b04", + "endpoint_id": 3, + "cluster": { + "id": 2820, + "name": "Electrical Measurement", + "type": "server" + }, + "id": "3:0x0b04", + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2:3:0x0b04", + "status": "INITIALIZED", + "value_attribute": "ac_voltage_multiplier" + } + ], + "device_ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "endpoint_id": 3, + "available": true, + "group_id": null, + "suggested_display_precision": 1, + "unit": "Hz" + }, + "state": { + "class_name": "ElectricalMeasurementFrequency", + "available": true, + "state": 49.766, + "measurement_type": "ACTIVE_MEASUREMENT, REACTIVE_MEASUREMENT, APPARENT_MEASUREMENT, PHASE_A_MEASUREMENT" + }, + "extra_state_attributes": [ + "ac_frequency_max", + "measurement_type" + ] + }, + { + "info_object": { + "fallback_name": null, + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2-3-2820-apparent_power", + "migrate_unique_ids": [], + "platform": "sensor", + "class_name": "ElectricalMeasurementApparentPower", + "translation_key": null, + "translation_placeholders": null, + "device_class": "apparent_power", + "state_class": "measurement", + "entity_category": null, + "entity_registry_enabled_default": true, + "enabled": true, + "primary": false, + "cluster_handlers": [ + { + "class_name": "ElectricalMeasurementClusterHandler", + "generic_id": "cluster_handler_0x0b04", + "endpoint_id": 3, + "cluster": { + "id": 2820, + "name": "Electrical Measurement", + "type": "server" + }, + "id": "3:0x0b04", + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2:3:0x0b04", + "status": "INITIALIZED", + "value_attribute": "ac_voltage_multiplier" + } + ], + "device_ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "endpoint_id": 3, + "available": true, + "group_id": null, + "suggested_display_precision": 1, + "unit": "VA" + }, + "state": { + "class_name": "ElectricalMeasurementApparentPower", + "available": true, + "state": 1.0, + "measurement_type": "ACTIVE_MEASUREMENT, REACTIVE_MEASUREMENT, APPARENT_MEASUREMENT, PHASE_A_MEASUREMENT" + }, + "extra_state_attributes": [ + "measurement_type" + ] + }, + { + "info_object": { + "fallback_name": null, + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2-3-2820-power_factor", + "migrate_unique_ids": [], + "platform": "sensor", + "class_name": "ElectricalMeasurementPowerFactor", + "translation_key": null, + "translation_placeholders": null, + "device_class": "power_factor", + "state_class": "measurement", + "entity_category": null, + "entity_registry_enabled_default": true, + "enabled": true, + "primary": false, + "cluster_handlers": [ + { + "class_name": "ElectricalMeasurementClusterHandler", + "generic_id": "cluster_handler_0x0b04", + "endpoint_id": 3, + "cluster": { + "id": 2820, + "name": "Electrical Measurement", + "type": "server" + }, + "id": "3:0x0b04", + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2:3:0x0b04", + "status": "INITIALIZED", + "value_attribute": "ac_voltage_multiplier" + } + ], + "device_ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "endpoint_id": 3, + "available": true, + "group_id": null, + "suggested_display_precision": 1, + "unit": "%" + }, + "state": { + "class_name": "ElectricalMeasurementPowerFactor", + "available": true, + "state": 0, + "measurement_type": "ACTIVE_MEASUREMENT, REACTIVE_MEASUREMENT, APPARENT_MEASUREMENT, PHASE_A_MEASUREMENT" + }, + "extra_state_attributes": [ + "measurement_type" + ] + }, + { + "info_object": { + "fallback_name": null, + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2-3-2820-rms_current", + "migrate_unique_ids": [], + "platform": "sensor", + "class_name": "ElectricalMeasurementRMSCurrent", + "translation_key": null, + "translation_placeholders": null, + "device_class": "current", + "state_class": "measurement", + "entity_category": null, + "entity_registry_enabled_default": true, + "enabled": true, + "primary": false, + "cluster_handlers": [ + { + "class_name": "ElectricalMeasurementClusterHandler", + "generic_id": "cluster_handler_0x0b04", + "endpoint_id": 3, + "cluster": { + "id": 2820, + "name": "Electrical Measurement", + "type": "server" + }, + "id": "3:0x0b04", + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2:3:0x0b04", + "status": "INITIALIZED", + "value_attribute": "ac_voltage_multiplier" + } + ], + "device_ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "endpoint_id": 3, + "available": true, + "group_id": null, + "suggested_display_precision": 1, + "unit": "A" + }, + "state": { + "class_name": "ElectricalMeasurementRMSCurrent", + "available": true, + "state": 4.0, + "measurement_type": "ACTIVE_MEASUREMENT, REACTIVE_MEASUREMENT, APPARENT_MEASUREMENT, PHASE_A_MEASUREMENT" + }, + "extra_state_attributes": [ + "measurement_type", + "rms_current_max" + ] + }, + { + "info_object": { + "fallback_name": null, + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2-3-2820-rms_voltage", + "migrate_unique_ids": [], + "platform": "sensor", + "class_name": "ElectricalMeasurementRMSVoltage", + "translation_key": null, + "translation_placeholders": null, + "device_class": "voltage", + "state_class": "measurement", + "entity_category": null, + "entity_registry_enabled_default": true, + "enabled": true, + "primary": false, + "cluster_handlers": [ + { + "class_name": "ElectricalMeasurementClusterHandler", + "generic_id": "cluster_handler_0x0b04", + "endpoint_id": 3, + "cluster": { + "id": 2820, + "name": "Electrical Measurement", + "type": "server" + }, + "id": "3:0x0b04", + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2:3:0x0b04", + "status": "INITIALIZED", + "value_attribute": "ac_voltage_multiplier" + } + ], + "device_ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "endpoint_id": 3, + "available": true, + "group_id": null, + "suggested_display_precision": 1, + "unit": "V" + }, + "state": { + "class_name": "ElectricalMeasurementRMSVoltage", + "available": true, + "state": 232.0, + "measurement_type": "ACTIVE_MEASUREMENT, REACTIVE_MEASUREMENT, APPARENT_MEASUREMENT, PHASE_A_MEASUREMENT" + }, + "extra_state_attributes": [ + "measurement_type", + "rms_voltage_max" + ] + }, + { + "info_object": { + "fallback_name": null, + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2-3-2820-total_active_power", + "migrate_unique_ids": [], + "platform": "sensor", + "class_name": "ElectricalMeasurementTotalActivePower", + "translation_key": "total_active_power", + "translation_placeholders": null, + "device_class": "power", + "state_class": "measurement", + "entity_category": null, + "entity_registry_enabled_default": true, + "enabled": true, + "primary": false, + "cluster_handlers": [ + { + "class_name": "ElectricalMeasurementClusterHandler", + "generic_id": "cluster_handler_0x0b04", + "endpoint_id": 3, + "cluster": { + "id": 2820, + "name": "Electrical Measurement", + "type": "server" + }, + "id": "3:0x0b04", + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2:3:0x0b04", + "status": "INITIALIZED", + "value_attribute": "ac_voltage_multiplier" + } + ], + "device_ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "endpoint_id": 3, + "available": true, + "group_id": null, + "suggested_display_precision": 1, + "unit": "W" + }, + "state": { + "class_name": "ElectricalMeasurementTotalActivePower", + "available": true, + "state": 0.0, + "measurement_type": "ACTIVE_MEASUREMENT, REACTIVE_MEASUREMENT, APPARENT_MEASUREMENT, PHASE_A_MEASUREMENT" + }, + "extra_state_attributes": [ + "active_power_max", + "measurement_type" + ] + } + ], + "switch": [ + { + "info_object": { + "fallback_name": null, + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2-1", + "migrate_unique_ids": [], + "platform": "switch", + "class_name": "Switch", + "translation_key": "switch", + "translation_placeholders": null, + "device_class": null, + "state_class": null, + "entity_category": null, + "entity_registry_enabled_default": true, + "enabled": true, + "primary": true, + "cluster_handlers": [ + { + "class_name": "OnOffClusterHandler", + "generic_id": "cluster_handler_0x0006", + "endpoint_id": 1, + "cluster": { + "id": 6, + "name": "On/Off", + "type": "server" + }, + "id": "1:0x0006", + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2:1:0x0006", + "status": "INITIALIZED", + "value_attribute": "on_off" + } + ], + "device_ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "endpoint_id": 1, + "available": true, + "group_id": null + }, + "state": { + "class_name": "Switch", + "state": 1, + "available": true + } + } + ], + "update": [ + { + "info_object": { + "fallback_name": null, + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2-232-25-firmware_update", + "migrate_unique_ids": [], + "platform": "update", + "class_name": "FirmwareUpdateEntity", + "translation_key": null, + "translation_placeholders": null, + "device_class": "firmware", + "state_class": null, + "entity_category": "config", + "entity_registry_enabled_default": true, + "enabled": true, + "primary": false, + "cluster_handlers": [ + { + "class_name": "OtaClientClusterHandler", + "generic_id": "cluster_handler_0x0019_client", + "endpoint_id": 232, + "cluster": { + "id": 25, + "name": "Ota", + "type": "client" + }, + "id": "232:0x0019_client", + "unique_id": "ab:cd:ef:12:e4:d6:5c:c2:232:0x0019_CLIENT", + "status": "INITIALIZED", + "value_attribute": null + } + ], + "device_ieee": "ab:cd:ef:12:e4:d6:5c:c2", + "endpoint_id": 232, + "available": true, + "group_id": null, + "supported_features": 7 + }, + "state": { + "class_name": "FirmwareUpdateEntity", + "available": true, + "installed_version": "0x02600460", + "in_progress": false, + "update_percentage": null, + "latest_version": null, + "release_summary": null, + "release_notes": null, + "release_url": null + } + } + ] + }, + "neighbors": [], + "routes": [] +} \ No newline at end of file diff --git a/tests/test_sensor.py b/tests/test_sensor.py index 3f6966733..65b6bcadf 100644 --- a/tests/test_sensor.py +++ b/tests/test_sensor.py @@ -2151,3 +2151,42 @@ async def test_enum_sensor(zha_gateway: Gateway) -> None: ) assert entity.state["state"] == "undefined_0xab" # TODO: should this be `None`? + + +async def test_ubisys_polled_em_keeps_polling_when_disabled( + zha_gateway: Gateway, +) -> None: + """Test that UbisysPolledElectricalMeasurement keeps polling when disabled.""" + + zigpy_dev = await zigpy_device_from_json( + zha_gateway.application_controller, + "tests/data/devices/ubisys-s1-5501.json", + ) + zha_device = await join_zigpy_device(zha_gateway, zigpy_dev) + + entity = get_entity( + zha_device, + platform=Platform.SENSOR, + exact_entity_type=sensor.UbisysPolledElectricalMeasurement, + ) + + assert isinstance(entity, sensor.UbisysPolledElectricalMeasurement) + assert entity._use_custom_polling is True + assert entity._polling_task is not None + assert entity.enabled is True + + # Disable the entity (simulating what the quirk does) + entity.disable() + + assert entity.enabled is False + # Polling task must still be running + assert entity._polling_task is not None + assert not entity._polling_task.done() + + # Re-enable the entity + entity.enable() + + assert entity.enabled is True + # Polling task must still be running (no duplicate created) + assert entity._polling_task is not None + assert not entity._polling_task.done() diff --git a/zha/application/platforms/__init__.py b/zha/application/platforms/__init__.py index 595f731a2..fae77701d 100644 --- a/zha/application/platforms/__init__.py +++ b/zha/application/platforms/__init__.py @@ -60,6 +60,9 @@ class PlatformFeatureGroup(StrEnum): # Model-specific overrides for VOC level VOC_LEVEL = "voc_level" + # Manufacturer-specific overrides for EM active power polling + EM_ACTIVE_POWER = "em_active_power" + # Model-specific overrides for Smart Energy Summation SMART_ENERGY_SUMMATION = "smart_energy_summation" diff --git a/zha/application/platforms/sensor/__init__.py b/zha/application/platforms/sensor/__init__.py index 1044bf897..88f459025 100644 --- a/zha/application/platforms/sensor/__init__.py +++ b/zha/application/platforms/sensor/__init__.py @@ -786,6 +786,7 @@ class ReportingElectricalMeasurement(ElectricalMeasurementActivePower): _cluster_handler_match = ClusterHandlerMatch( cluster_handlers=frozenset({CLUSTER_HANDLER_ELECTRICAL_MEASUREMENT}), models=frozenset({"VZM31-SN", "SP 234", "outletv4", "INSPELNING Smart plug"}), + feature_priority=(PlatformFeatureGroup.EM_ACTIVE_POWER, 1), ) @@ -797,9 +798,34 @@ class PolledElectricalMeasurement(ElectricalMeasurementActivePower): _cluster_handler_match = ClusterHandlerMatch( cluster_handlers=frozenset({CLUSTER_HANDLER_ELECTRICAL_MEASUREMENT}), + feature_priority=(PlatformFeatureGroup.EM_ACTIVE_POWER, 0), ) +@register_entity(ElectricalMeasurement.cluster_id) +class UbisysPolledElectricalMeasurement(PolledElectricalMeasurement): + """Polled active power for ubisys that keeps polling even when disabled. + + ubisys devices disable the active power entity by default via a quirk, but + this entity still needs to poll the EM cluster so that other EM entities + (voltage, current, power factor) receive updated values. + """ + + _cluster_handler_match = ClusterHandlerMatch( + cluster_handlers=frozenset({CLUSTER_HANDLER_ELECTRICAL_MEASUREMENT}), + manufacturers=frozenset({"ubisys"}), + feature_priority=(PlatformFeatureGroup.EM_ACTIVE_POWER, 1), + ) + + def disable(self) -> None: + """Disable the entity but keep polling for EM cluster updates.""" + PlatformEntity.disable(self) + + def enable(self) -> None: + """Enable the entity without starting a duplicate polling task.""" + PlatformEntity.enable(self) + + @register_entity(ElectricalMeasurement.cluster_id) class ElectricalMeasurementActivePowerPhB(ElectricalMeasurementActivePower): """Active power phase B measurement."""