zigpy / zha-device-handlers

ZHA device handlers bridge the functionality gap created when manufacturers deviate from the ZCL specification, handling deviations and exceptions by parsing custom messages to and from Zigbee devices.
Apache License 2.0
705 stars 650 forks source link

Develco SPLZB-131: Wrong device temperature (divisor) #2121

Closed eriknn closed 1 year ago

eriknn commented 1 year ago

Hi, it seems that device temperature is reported "as is" from the device, but then a divisor of 100 is applied, giving a wrong result. If I'm not mistaken the 100 divisor is default for device temperature, so this is probably a bug in the device. Is this something that could be solved with a quirk?

TheJulianJES commented 1 year ago

You did not fill out the issue template.

Please provide the device signature and diagnostic information for the affected device.

eriknn commented 1 year ago

Is your feature request related to a problem? Please describe. Yes, seems to be a bug in the device

Describe the solution you'd like Use divisor = 1 instead of divisor = 100 which I believe is default

Device signature ```yaml { "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4117, maximum_buffer_size=72, maximum_incoming_transfer_size=128, server_mask=0, maximum_outgoing_transfer_size=128, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)", "endpoints": { "1": { "profile_id": 49353, "device_type": "0x0001", "in_clusters": [ "0x0005", "0x0006" ], "out_clusters": [] }, "2": { "profile_id": 260, "device_type": "0x0051", "in_clusters": [ "0x0000", "0x0002", "0x0003", "0x0004", "0x0005", "0x0006", "0x0009", "0x0702", "0x0b04" ], "out_clusters": [ "0x0000", "0x0003", "0x000a", "0x0019", "0x0406" ] } }, "manufacturer": "Develco Products A/S", "model": "SPLZB-131", "class": "zigpy.device.Device" } ```
Diagnostic information ```yaml { "home_assistant": { "installation_type": "Home Assistant OS", "version": "2023.1.6", "dev": false, "hassio": true, "virtualenv": false, "python_version": "3.10.7", "docker": true, "arch": "x86_64", "timezone": "Europe/Oslo", "os_name": "Linux", "os_version": "5.15.80", "supervisor": "2022.12.1", "host_os": "Home Assistant OS 9.4", "docker_version": "20.10.19", "chassis": "embedded", "run_as_root": true }, "custom_components": { "wasteplan_trv": { "version": "1.0.1", "requirements": [] }, "hacs": { "version": "1.29.1", "requirements": [ "aiogithubapi>=22.10.1" ] }, "zha_toolkit": { "version": "v0.8.29", "requirements": [ "packaging>=20.8", "pytz" ] }, "airthings_ble": { "version": "4.0.0", "requirements": [] }, "nordpool": { "version": "0.0.10", "requirements": [ "nordpool>=0.2" ] }, "pax_ble": { "version": "1.0.0", "requirements": [] }, "airthings_wave": { "version": "4.0.0", "requirements": [ "bleak==0.14.3" ] }, "pyscript": { "version": "1.3.3", "requirements": [ "croniter==1.3.4", "watchdog==2.1.6" ] } }, "integration_manifest": { "domain": "zha", "name": "Zigbee Home Automation", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/zha", "requirements": [ "bellows==0.34.6", "pyserial==3.5", "pyserial-asyncio==0.6", "zha-quirks==0.0.90", "zigpy-deconz==0.19.2", "zigpy==0.53.0", "zigpy-xbee==0.16.2", "zigpy-zigate==0.10.3", "zigpy-znp==0.9.2" ], "usb": [ { "vid": "10C4", "pid": "EA60", "description": "*2652*", "known_devices": [ "slae.sh cc2652rb stick" ] }, { "vid": "1A86", "pid": "55D4", "description": "*sonoff*plus*", "known_devices": [ "sonoff zigbee dongle plus v2" ] }, { "vid": "10C4", "pid": "EA60", "description": "*sonoff*plus*", "known_devices": [ "sonoff zigbee dongle plus" ] }, { "vid": "10C4", "pid": "EA60", "description": "*tubeszb*", "known_devices": [ "TubesZB Coordinator" ] }, { "vid": "1A86", "pid": "7523", "description": "*tubeszb*", "known_devices": [ "TubesZB Coordinator" ] }, { "vid": "1A86", "pid": "7523", "description": "*zigstar*", "known_devices": [ "ZigStar Coordinators" ] }, { "vid": "1CF1", "pid": "0030", "description": "*conbee*", "known_devices": [ "Conbee II" ] }, { "vid": "10C4", "pid": "8A2A", "description": "*zigbee*", "known_devices": [ "Nortek HUSBZB-1" ] }, { "vid": "0403", "pid": "6015", "description": "*zigate*", "known_devices": [ "ZiGate+" ] }, { "vid": "10C4", "pid": "EA60", "description": "*zigate*", "known_devices": [ "ZiGate" ] }, { "vid": "10C4", "pid": "8B34", "description": "*bv 2010/10*", "known_devices": [ "Bitron Video AV2010/10" ] } ], "codeowners": [ "@dmulcahey", "@adminiuga", "@puddly" ], "zeroconf": [ { "type": "_esphomelib._tcp.local.", "name": "tube*" }, { "type": "_zigate-zigbee-gateway._tcp.local.", "name": "*zigate*" }, { "type": "_zigstar_gw._tcp.local.", "name": "*zigstar*" }, { "type": "_slzb-06._tcp.local.", "name": "slzb-06*" } ], "dependencies": [ "file_upload" ], "after_dependencies": [ "onboarding", "usb", "zeroconf" ], "iot_class": "local_polling", "loggers": [ "aiosqlite", "bellows", "crccheck", "pure_pcapy3", "zhaquirks", "zigpy", "zigpy_deconz", "zigpy_xbee", "zigpy_zigate", "zigpy_znp" ], "is_built_in": true }, "data": { "ieee": "**REDACTED**", "nwk": 31681, "manufacturer": "Develco Products A/S", "model": "SPLZB-131", "name": "Develco Products A/S SPLZB-131", "quirk_applied": false, "quirk_class": "zigpy.device.Device", "manufacturer_code": 4117, "power_source": "Mains", "lqi": 255, "rssi": -65, "last_seen": "2023-01-20T22:31:46", "available": true, "device_type": "Router", "signature": { "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4117, maximum_buffer_size=72, maximum_incoming_transfer_size=128, server_mask=0, maximum_outgoing_transfer_size=128, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)", "endpoints": { "1": { "profile_id": 49353, "device_type": "0x0001", "in_clusters": [ "0x0005", "0x0006" ], "out_clusters": [] }, "2": { "profile_id": 260, "device_type": "0x0051", "in_clusters": [ "0x0000", "0x0002", "0x0003", "0x0004", "0x0005", "0x0006", "0x0009", "0x0702", "0x0b04" ], "out_clusters": [ "0x0000", "0x0003", "0x000a", "0x0019", "0x0406" ] } } }, "active_coordinator": false, "entities": [ { "entity_id": "button.stromplugg_kjoleskap_identify", "name": "Develco Products A/S SPLZB-131" }, { "entity_id": "sensor.stromplugg_kjoleskap_active_power", "name": "Develco Products A/S SPLZB-131" }, { "entity_id": "sensor.stromplugg_kjoleskap_rms_current", "name": "Develco Products A/S SPLZB-131" }, { "entity_id": "sensor.stromplugg_kjoleskap_rms_voltage", "name": "Develco Products A/S SPLZB-131" }, { "entity_id": "sensor.stromplugg_kjoleskap_ac_frequency", "name": "Develco Products A/S SPLZB-131" }, { "entity_id": "sensor.stromplugg_kjoleskap_power_factor", "name": "Develco Products A/S SPLZB-131" }, { "entity_id": "sensor.stromplugg_kjoleskap_device_temperature", "name": "Develco Products A/S SPLZB-131" }, { "entity_id": "sensor.stromplugg_kjoleskap_instantaneous_demand", "name": "Develco Products A/S SPLZB-131" }, { "entity_id": "sensor.stromplugg_kjoleskap_summation_delivered", "name": "Develco Products A/S SPLZB-131" }, { "entity_id": "switch.stromplugg_kjoleskap_switch_2", "name": "Develco Products A/S SPLZB-131" } ], "neighbors": [ { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0xF081", "permit_joining": "NotAccepting", "depth": "15", "lqi": "75" }, { "device_type": "Coordinator", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0x0000", "permit_joining": "NotAccepting", "depth": "0", "lqi": "58" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0x3AC7", "permit_joining": "NotAccepting", "depth": "15", "lqi": "101" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0xBD59", "permit_joining": "NotAccepting", "depth": "15", "lqi": "58" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0xF25A", "permit_joining": "NotAccepting", "depth": "15", "lqi": "67" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0x313F", "permit_joining": "NotAccepting", "depth": "15", "lqi": "75" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0xD74C", "permit_joining": "NotAccepting", "depth": "15", "lqi": "57" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0xF5CA", "permit_joining": "NotAccepting", "depth": "15", "lqi": "135" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0x2EDC", "permit_joining": "NotAccepting", "depth": "15", "lqi": "88" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0x120F", "permit_joining": "NotAccepting", "depth": "15", "lqi": "77" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0xFECF", "permit_joining": "NotAccepting", "depth": "15", "lqi": "74" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0x2DA5", "permit_joining": "NotAccepting", "depth": "15", "lqi": "79" } ], "routes": [ { "dest_nwk": "0x257D", "route_status": "Active", "memory_constrained": false, "many_to_one": false, "route_record_required": true, "next_hop": "0x313F" }, { "dest_nwk": "0x0000", "route_status": "Active", "memory_constrained": false, "many_to_one": false, "route_record_required": true, "next_hop": "0x2DA5" } ], "endpoint_names": [ { "name": "SMART_PLUG" }, { "name": "unknown 1 device_type of 0xc0c9 profile id" } ], "user_given_name": "Str\u00f8mplugg Kj\u00f8leskap", "device_reg_id": "7d064576313d19dd4493637e82d26378", "area_id": "teknisk_rom", "cluster_details": { "2": { "device_type": { "name": "SMART_PLUG", "id": 81 }, "profile_id": 260, "in_clusters": { "0x0000": { "endpoint_attribute": "basic", "attributes": { "0x0004": { "attribute_name": "manufacturer", "value": "Develco Products A/S" }, "0x0005": { "attribute_name": "model", "value": "SPLZB-131" } }, "unsupported_attributes": { "0x0001": { "attribute_name": "app_version" }, "0x0013": { "attribute_name": "alarm_mask" }, "0x000e": { "attribute_name": "product_label" }, "0xfffe": { "attribute_name": "attr_reporting_status" }, "0x000b": { "attribute_name": "product_url" }, "0x0011": { "attribute_name": "physical_env" } } }, "0x0702": { "endpoint_attribute": "smartenergy_metering", "attributes": { "0x0000": { "attribute_name": "current_summ_delivered", "value": 2218 }, "0x0002": { "attribute_name": "current_max_demand_delivered", "value": 1354 }, "0x0200": { "attribute_name": "status", "value": 0 }, "0x0300": { "attribute_name": "unit_of_measure", "value": 0 }, "0x0301": { "attribute_name": "multiplier", "value": 1 }, "0x0302": { "attribute_name": "divisor", "value": 1000 }, "0x0303": { "attribute_name": "summation_formatting", "value": 248 }, "0x0304": { "attribute_name": "demand_formatting", "value": 248 }, "0x0306": { "attribute_name": "metering_device_type", "value": 0 }, "0x0400": { "attribute_name": "instantaneous_demand", "value": 75 } }, "unsupported_attributes": { "0x0006": { "attribute_name": "power_factor" }, "0x0202": { "attribute_name": "hours_in_operation" }, "0x0019": { "attribute_name": "control_temperature" }, "0x0017": { "attribute_name": "inlet_temperature" }, "0x030c": { "attribute_name": "temperature_unit_of_measure" }, "0x030d": { "attribute_name": "temperature_formatting" }, "0x0018": { "attribute_name": "outlet_temperature" } } }, "0x0003": { "endpoint_attribute": "identify", "attributes": {}, "unsupported_attributes": {} }, "0x0009": { "endpoint_attribute": "alarms", "attributes": {}, "unsupported_attributes": { "0xfffd": { "attribute_name": "cluster_revision" }, "0xfffe": { "attribute_name": "attr_reporting_status" } } }, "0x0b04": { "endpoint_attribute": "electrical_measurement", "attributes": { "0x0000": { "attribute_name": "measurement_type", "value": 11 }, "0x0300": { "attribute_name": "ac_frequency", "value": 50000 }, "0x0400": { "attribute_name": "ac_frequency_multiplier", "value": 1 }, "0x0401": { "attribute_name": "ac_frequency_divisor", "value": 1000 }, "0x0505": { "attribute_name": "rms_voltage", "value": 22742 }, "0x0508": { "attribute_name": "rms_current", "value": 645 }, "0x050b": { "attribute_name": "active_power", "value": 75 }, "0x0600": { "attribute_name": "ac_voltage_multiplier", "value": 1 }, "0x0601": { "attribute_name": "ac_voltage_divisor", "value": 100 }, "0x0602": { "attribute_name": "ac_current_multiplier", "value": 1 }, "0x0603": { "attribute_name": "ac_current_divisor", "value": 1000 }, "0x0604": { "attribute_name": "ac_power_multiplier", "value": 1 }, "0x0605": { "attribute_name": "ac_power_divisor", "value": 1 } }, "unsupported_attributes": { "0x0803": { "attribute_name": "ac_active_power_overload" }, "0x0302": { "attribute_name": "ac_frequency_max" }, "0x0403": { "attribute_name": "power_divisor" }, "0x0402": { "attribute_name": "power_multiplier" }, "0x0504": { "attribute_name": "instantaneous_power" }, "0x0507": { "attribute_name": "rms_voltage_max" }, "0x050a": { "attribute_name": "rms_current_max" }, "0x050d": { "attribute_name": "active_power_max" }, "0x050f": { "attribute_name": "apparent_power" }, "0xfffd": { "attribute_name": "cluster_revision" } } }, "0x0006": { "endpoint_attribute": "on_off", "attributes": { "0x0000": { "attribute_name": "on_off", "value": 1 } }, "unsupported_attributes": { "0x4003": { "attribute_name": "start_up_on_off" } } }, "0x0004": { "endpoint_attribute": "groups", "attributes": {}, "unsupported_attributes": { "0xfffe": { "attribute_name": "attr_reporting_status" } } }, "0x0005": { "endpoint_attribute": "scenes", "attributes": {}, "unsupported_attributes": {} }, "0x0002": { "endpoint_attribute": "device_temperature", "attributes": { "0x0000": { "attribute_name": "current_temperature", "value": 27 } }, "unsupported_attributes": { "0xfffe": { "attribute_name": "attr_reporting_status" }, "0x0012": { "attribute_name": "high_temp_thres" }, "0xfffd": { "attribute_name": "cluster_revision" } } } }, "out_clusters": { "0x0000": { "endpoint_attribute": "basic", "attributes": {}, "unsupported_attributes": {} }, "0x0019": { "endpoint_attribute": "ota", "attributes": {}, "unsupported_attributes": {} }, "0x000a": { "endpoint_attribute": "time", "attributes": {}, "unsupported_attributes": {} }, "0x0003": { "endpoint_attribute": "identify", "attributes": {}, "unsupported_attributes": {} }, "0x0406": { "endpoint_attribute": "occupancy", "attributes": {}, "unsupported_attributes": {} } } }, "1": { "device_type": { "name": "unknown", "id": 1 }, "profile_id": 49353, "in_clusters": { "0x0005": { "endpoint_attribute": "scenes", "attributes": {}, "unsupported_attributes": {} }, "0x0006": { "endpoint_attribute": "on_off", "attributes": {}, "unsupported_attributes": {} } }, "out_clusters": {} } } } } ```
eriknn commented 1 year ago

I thought I would try to make the quirk myself. The standard class for this attribute is here: https://github.com/zigpy/zigpy/blob/dev/zigpy/zcl/clusters/general.py#L389

If I understand quirks correctly, this is the class that would typically be modified with the quirk. However, the divisor is not here, it is here: https://github.com/home-assistant/core/blob/c3e27f68123511fe28a6898ef49b1a60aeabe64c/homeassistant/components/zha/sensor.py#L624

I'm asking on the wrong github channel? Or could it still be fixed with a quirk?

TheJulianJES commented 1 year ago

You're totally right. I thought there was a divisor attribute available on that cluster, but that's not the case.

This could probably still be fixed with a quirk by modifying the sent messages (modifying when saving the attribute -- perhaps overriding _update_attribute for that cluster), but it's more complicated than just changing a constant divisor.

eriknn commented 1 year ago

Yeah, I’ll try to figure it out. Might as well understand how this works and maybe I can be a resource for you guys later as well!

eriknn commented 1 year ago

Okay, I got this working now!

One question though: Endpoint 1 contains a switch that does nothing, and a scenes cluster that I don’t see as necessary either. Is it considered okay to just remove this endpoint in the replacement signature?

A different problem, a bit more unrelated: One of the attributes has reporting set to 5/900/1 according to the reconfigure-log, yet it still updates every second. Zha Toolkit reveals that the actual config is 1/900/1. Configuring manually with Zha Toolkit fixes the issue. Any idea why this is happening? It was the case w/o quirk as well!

TheJulianJES commented 1 year ago

Is it considered okay to just remove this endpoint in the replacement signature?

If they really don't do anything and create and unnecessary entity in HA, it should be fine to remove them, yes. Also, can you post the device signature (and your current quirk)? (or feel free to already create a PR with your current quirk)

One of the attributes has reporting set to 5/900/1 according to the reconfigure-log. Zha Toolkit reveals that the actual config is 1/900/1. Configuring manually with Zha Toolkit fixes the issue.

Hmm, after you've configured it with ZHA Toolkit, does starting a normal "reconfigure" through the UI set it to 1/900/1 again? Can you maybe also post the debug logs from the reconfigure (and the ones from when you set it with ZHA Toolkit)?

eriknn commented 1 year ago

Will test this later tonight. I noticed that this device reports these values in HA: (Cluster - Attribute) ElectricalMeasurement - Active Power Metering - Instantanious Demand

These two give the same value. Using the signature we can disable/remove an entire cluster. But can I remove a single attribute somehow?

eriknn commented 1 year ago

Did a test now. A reconfigure does indeed set the value back to 1/900/1.

My debug log is very large, but I tried to extract the part when reconfiguring through UI. Seems like it should be okay....

2023-01-24 22:21:40.812 DEBUG (MainThread) [zigpy.zcl] [0x8B93:2:0x0702] Received ZCL frame: b'\x18\x85\x07\x00'
2023-01-24 22:21:40.812 DEBUG (MainThread) [zigpy.zcl] [0x8B93:2:0x0702] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.GLOBAL_COMMAND: 0>, is_manufacturer_specific=0, direction=<Direction.Client_to_Server: 1>, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True, *is_reply=True), tsn=133, command_id=7, *direction=<Direction.Client_to_Server: 1>, *is_reply=True)
2023-01-24 22:21:40.813 DEBUG (MainThread) [zigpy.zcl] [0x8B93:2:0x0702] Decoded ZCL frame: Metering:Configure_Reporting_rsp(status_records=[ConfigureReportingResponseRecord(status=<Status.SUCCESS: 0>)])
2023-01-24 22:21:40.813 DEBUG (MainThread) [zigpy_deconz.api] 'aps_data_indication' response from <DeconzAddress address_mode=AddressMode.NWK address=0x8b93>, ep: 2, profile: 0x0104, cluster_id: 0x0702, data: b'18850700'
2023-01-24 22:21:40.813 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x8B93:2:0x0702]: Successfully configured reporting for '{'instantaneous_demand': (5, 900, 1), 'current_summ_delivered': (30, 900, 1), 'status': (1, 900, 1)}' on 'smartenergy_metering' cluster: [ConfigureReportingResponseRecord(status=<Status.SUCCESS: 0>)]
2023-01-24 22:21:40.814 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x8B93:2:0x0702]: finished channel configuration
TheJulianJES commented 1 year ago

These two give the same value. Using the signature we can disable/remove an entire cluster. But can I remove a single attribute somehow?

Not easily and you normally shouldn't really or does HA creates two sensor entities?

eriknn commented 1 year ago

HA creates two sensor identities with the same value, which seems a bit redundant. I can't find any good docs on how HA decides which entites to create - looks a bit like magic for me at the moment. Is there any developer docs on this, or do I have to browse code?

TheJulianJES commented 1 year ago

Ah, that's annoying then.

Check https://github.com/home-assistant/core/blob/dev/homeassistant/components/zha/sensor.py for which attributes are used to create sensors. There aren't any docs really :/

I wonder if we can just use CONSTANT_ATTRIBUTES to override the attribute from the Metering cluster then..

eriknn commented 1 year ago

I think the debug log above was from the manual successful entry. Here's the log from reconfigure. Looks correct to me.

2023-01-28 00:19:54.903 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x8B93:2:0x0702]: bound 'smartenergy_metering' cluster: Status.SUCCESS
2023-01-28 00:19:54.904 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x8B93:2:0x0702]: Configuring cluster attribute reporting
2023-01-28 00:19:54.904 DEBUG (MainThread) [zigpy.zcl] [0x8B93:2:0x0702] Sending request header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.GLOBAL_COMMAND: 0>, is_manufacturer_specific=False, direction=<Direction.Server_to_Client: 0>, disable_default_response=0, reserved=0, *is_cluster=False, *is_general=True, *is_reply=False), tsn=115, command_id=<GeneralCommand.Configure_Reporting: 6>, *direction=<Direction.Server_to_Client: 0>, *is_reply=False)
2023-01-28 00:19:54.904 DEBUG (MainThread) [zigpy.zcl] [0x8B93:2:0x0702] Sending request: Configure_Reporting(config_records=[AttributeReportingConfig(direction=0, attrid=0x0400, datatype=42, min_interval=5, max_interval=900, reportable_change=1), AttributeReportingConfig(direction=0, attrid=0x0000, datatype=37, min_interval=30, max_interval=900, reportable_change=1), AttributeReportingConfig(direction=0, attrid=0x0200, datatype=24, min_interval=1, max_interval=900, reportable_change=1)])
2023-01-28 00:19:54.905 DEBUG (MainThread) [zigpy_deconz.zigbee.application] Sending packet: ZigbeePacket(src=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0x0000), src_ep=2, dst=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0x8B93), dst_ep=2, source_route=None, extended_timeout=False, tsn=115, profile_id=260, cluster_id=1794, data=Serialized[b'\x00s\x06\x00\x00\x04*\x05\x00\x84\x03\x01\x00\x00\x00\x00\x00%\x1e\x00\x84\x03\x01\x00\x00\x00\x00\x00\x00\x00\x02\x18\x01\x00\x84\x03'], tx_options=<TransmitOptions.NONE: 0>, radius=0, non_member_radius=0, lqi=None, rssi=None)
2023-01-28 00:19:54.905 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_request (51, 116, <DeconzSendDataFlags.NONE: 0>, <DeconzAddressEndpoint address_mode=AddressMode.NWK address=0x8b93 endpoint=2>, 260, 1794, 1, b'\x00s\x06\x00\x00\x04*\x05\x00\x84\x03\x01\x00\x00\x00\x00\x00%\x1e\x00\x84\x03\x01\x00\x00\x00\x00\x00\x00\x00\x02\x18\x01\x00\x84\x03', <DeconzTransmitOptions.USE_NWK_KEY_SECURITY: 2>, 0)
2023-01-28 00:19:54.919 DEBUG (MainThread) [zigpy_deconz.api] Received command aps_data_request[2, <DeviceState.APSDE_DATA_REQUEST_SLOTS_AVAILABLE|2: 34>, 116]
2023-01-28 00:19:54.920 DEBUG (MainThread) [zigpy_deconz.api] APS data request response: [2, <DeviceState.APSDE_DATA_REQUEST_SLOTS_AVAILABLE|2: 34>, 116]
2023-01-28 00:19:54.920 DEBUG (MainThread) [zigpy_deconz.api] Received command device_state_changed[<DeviceState.128|APSDE_DATA_REQUEST_SLOTS_AVAILABLE|APSDE_DATA_INDICATION|2: 170>, 0]
2023-01-28 00:19:54.920 DEBUG (MainThread) [zigpy_deconz.api] Device state changed response: [<DeviceState.128|APSDE_DATA_REQUEST_SLOTS_AVAILABLE|APSDE_DATA_INDICATION|2: 170>, 0]
2023-01-28 00:19:54.920 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_indication (1, <DataIndicationFlags.Always_Use_NWK_Source_Addr: 1>)
2023-01-28 00:19:54.922 DEBUG (MainThread) [zigpy_deconz.api] Received command aps_data_indication[25, <DeviceState.APSDE_DATA_REQUEST_SLOTS_AVAILABLE|2: 34>, <DeconzAddress address_mode=AddressMode.NWK address=0x0000>, 0, <DeconzAddress address_mode=AddressMode.NWK address=0x8b93>, 0, 0, 32801, b'm\x00', 0, 175, 232, 36, 62, 85, 0, -78]
2023-01-28 00:19:54.922 DEBUG (MainThread) [zigpy_deconz.api] APS data indication response: [25, <DeviceState.APSDE_DATA_REQUEST_SLOTS_AVAILABLE|2: 34>, <DeconzAddress address_mode=AddressMode.NWK address=0x0000>, 0, <DeconzAddress address_mode=AddressMode.NWK address=0x8b93>, 0, 0, 32801, b'm\x00', 0, 175, 232, 36, 62, 85, 0, -78]
2023-01-28 00:19:54.922 DEBUG (MainThread) [zigpy.application] Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0x8B93), src_ep=0, dst=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0x0000), dst_ep=0, source_route=None, extended_timeout=False, tsn=None, profile_id=0, cluster_id=32801, data=Serialized[b'm\x00'], tx_options=<TransmitOptions.NONE: 0>, radius=0, non_member_radius=0, lqi=232, rssi=-78)
2023-01-28 00:19:54.923 DEBUG (MainThread) [zigpy_deconz.api] 'aps_data_indication' response from <DeconzAddress address_mode=AddressMode.NWK address=0x8b93>, ep: 0, profile: 0x0000, cluster_id: 0x8021, data: b'6d00'
2023-01-28 00:19:54.923 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x8B93:2:0x0b04]: bound 'electrical_measurement' cluster: Status.SUCCESS

This is the same reconfiguration, but the device temperature cluster:

2023-01-28 00:19:55.012 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x8B93:2:0x0002]: bound 'device_temperature' cluster: Status.SUCCESS
2023-01-28 00:19:55.013 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0x8B93:2:0x0002]: Configuring cluster attribute reporting
2023-01-28 00:19:55.013 DEBUG (MainThread) [zigpy.zcl] [0x8B93:2:0x0002] Sending request header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.GLOBAL_COMMAND: 0>, is_manufacturer_specific=False, direction=<Direction.Server_to_Client: 0>, disable_default_response=0, reserved=0, *is_cluster=False, *is_general=True, *is_reply=False), tsn=125, command_id=<GeneralCommand.Configure_Reporting: 6>, *direction=<Direction.Server_to_Client: 0>, *is_reply=False)
2023-01-28 00:19:55.014 DEBUG (MainThread) [zigpy.zcl] [0x8B93:2:0x0002] Sending request: Configure_Reporting(config_records=[AttributeReportingConfig(direction=0, attrid=0x0000, datatype=41, min_interval=30, max_interval=900, reportable_change=50)])
2023-01-28 00:19:55.015 DEBUG (MainThread) [zigpy_deconz.zigbee.application] Sending packet: ZigbeePacket(src=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0x0000), src_ep=2, dst=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0x8B93), dst_ep=2, source_route=None, extended_timeout=False, tsn=125, profile_id=260, cluster_id=2, data=Serialized[b'\x00}\x06\x00\x00\x00)\x1e\x00\x84\x032\x00'], tx_options=<TransmitOptions.NONE: 0>, radius=0, non_member_radius=0, lqi=None, rssi=None)
2023-01-28 00:19:55.015 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_confirm (0,)

It seems that this gets a "Command Command.aps_data_confirm (0,)" reply. Note that this only has one attribute. The "electrical_measurement" cluster also contains several attributes, and does not get an ack.

So could it be that configuration fails when trying to configure several attributes in one packet?

ervee commented 1 year ago

HA creates two sensor identities with the same value, which seems a bit redundant. I can't find any good docs on how HA decides which entites to create - looks a bit like magic for me at the moment. Is there any developer docs on this, or do I have to browse code?

Thank you for the temperature quirk!

For the power sensors it does seem to report differently:

Screenshot_2023-02-22-11-14-13-02_c3a231c25ed346e59462e84656a70e50

The instantaneous sensor seems te be reporting much more often? I don't know if that makes sense, I'm pretty new to this Zigbee stuff.

eriknn commented 1 year ago

Yeah, read my posts above. This seems to be due to an issue when the entity is configured. HA attempts to configure update frequency on all sensors belonging to the same cluster with one config-telegram. The device doesn’t handle this well, and ends up with minimum 1 sec interval (should be 5). I had to fix this manually by setting each individually.

ervee commented 1 year ago

Ah yes I see. I guess I'll be installing ZHA Toolkit then 😅 I can probably figure it out. Thanks!

ervee commented 1 year ago

Haha guess not 😅 I have ZHA Toolkit running and I think I need to call service ZHA Toolkit: conf_report, select ieee Entity "mydevice Instantaneous demand". Then fill min/max/reportable with 5/900/1. But it seems like I need to fill in more stuff before it will let me call the service. That's where I'm lost.

Could you please fill me in on this? There is a lot to read about all this but it is a bit overwhelming.

So this is where I'm at now:

service: zha_toolkit.conf_report
data:
  ieee: sensor.frient_a_s_splzb_131_instantaneous_demand
  min_interval: 5
  max_interval: 900
  reportable_change: 1
eriknn commented 1 year ago

Try these:

service: zha_toolkit.conf_report
data:
  ieee: sensor.device_ac_frequency
  cluster: 0xb04
  attribute: 0x300
  min_interval: 5
  reportable_change: 50
  max_interval: 900

service: zha_toolkit.conf_report
data:
  ieee: sensor.device_rms_voltage
  cluster: 0xb04
  attribute: 0x505
  min_interval: 5
  reportable_change: 50
  max_interval: 900

service: zha_toolkit.conf_report
data:
  ieee: sensor.device_rms_current
  cluster: 0xb04
  attribute: 0x508
  min_interval: 5
  reportable_change: 50
  max_interval: 900

service: zha_toolkit.conf_report
data:
  ieee: sensor.device_active_power
  cluster: 0xb04
  attribute: 0x50b
  min_interval: 5
  reportable_change: 5
  max_interval: 900

service: zha_toolkit.conf_report
data:
  ieee: sensor.device_instantaneous_demand
  cluster: 0x702
  attribute: 0x400
  min_interval: 5
  reportable_change: 5
  max_interval: 900

service: zha_toolkit.conf_report
data:
  ieee: sensor.device_summation_delivered
  cluster: 0x0702
  attribute: 0x0000
  min_interval: 5
  reportable_change: 10
  max_interval: 900
ervee commented 1 year ago

Ah yes I was looking for the cluster/attribute in the "Manage Zigbee Device" option of the device. I found the 0x702 and 0x400 and put it in the conf_report_read service. Found the output in the HA log and it was 1/900/1 as expected.

I did the conf_report service call for the instantaneous_demand and another read and the log now shows:

Last logged: 19:21:20

Read reporting with [ReadReportingConfigRecord(direction=0, attrid=1024)] {'manufacturer': None}
Read reporting with [ReadReportingConfigRecord(direction=0, attrid=1024)] result Read_Reporting_Configuration_rsp(attribute_configs=[AttributeReportingConfigWithStatus(status=<Status.SUCCESS: 0>, config=AttributeReportingConfig(direction=<ReportingDirection.SendReports: 0>, attrid=0x0400, datatype=42, min_interval=1, max_interval=900, reportable_change=1))])
Read reporting with [ReadReportingConfigRecord(direction=0, attrid=1024)] result Read_Reporting_Configuration_rsp(attribute_configs=[AttributeReportingConfigWithStatus(status=<Status.SUCCESS: 0>, config=AttributeReportingConfig(direction=<ReportingDirection.SendReports: 0>, attrid=0x0400, datatype=42, min_interval=5, max_interval=900, reportable_change=1))])

Not sure why at the second bullets it shows 1/900/1 and at the third bullet it shows 5/900/1. I'm still pretty new at this Zigbee stuff 😅

eriknn commented 1 year ago

Alright, looks like you’ve got it under control then! Sure these aren’t read before and after you configured it correctly? I think multiple reads will cluster up like that…

i debugged the zigbee betwork to really clean this up, so take note of my values. Some are multiplied etc, that’s why I have some high reportable change-thresholds!

ervee commented 1 year ago

It could be clustered. I'll keep an eye on it. Thank you for your help and for the other values. Really appreciated!