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
743 stars 679 forks source link

[Device Support Request] Heiman CO_V15 Monoxide Carbon sensor #1826

Closed cobirnm closed 1 year ago

cobirnm commented 2 years ago

Is your feature request related to a problem? Please describe. When Heiman CO_V15 Monoxide Carbon sensor is added to HA it reports as a "Mains" powerd device and after some hours drops out of the network

Describe the solution you'd like If possible a custom quirk to correct it.

Device 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=48042, maximum_buffer_size=64, maximum_incoming_transfer_size=0, server_mask=0, maximum_outgoing_transfer_size=0, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=True, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": 260, "device_type": "0x0402", "in_clusters": [ "0x0000", "0x0001", "0x0003", "0x0009", "0x0500" ], "out_clusters": [ "0x0019" ] } }, "manufacturer": "Heiman", "model": "CO_V15", "class": "zigpy.device.Device" } ```
Diagnostic information ```y "data": { "ieee": "**REDACTED**", "nwk": 47794, "manufacturer": "Heiman", "model": "CO_V15", "name": "Heiman CO_V15", "quirk_applied": false, "quirk_class": "zigpy.device.Device", "manufacturer_code": 48042, "power_source": "Mains", "lqi": null, "rssi": null, "last_seen": "2022-10-14T16:00:40", "available": false, "device_type": "EndDevice", "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=48042, maximum_buffer_size=64, maximum_incoming_transfer_size=0, server_mask=0, maximum_outgoing_transfer_size=0, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=True, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": 260, "device_type": "0x0402", "in_clusters": [ "0x0000", "0x0001", "0x0003", "0x0009", "0x0500" ], "out_clusters": [ "0x0019" ] } } }, "active_coordinator": false, "entities": [ { "entity_id": "binary_sensor.heiman_co_v15_iaszone", "name": "Heiman CO_V15" }, { "entity_id": "button.heiman_co_v15_identifybutton", "name": "Heiman CO_V15" } ], "neighbors": [], "endpoint_names": [ { "name": "IAS_ZONE" } ], "user_given_name": null, "device_reg_id": "42f806d41819474f86ae2300cb621106", "area_id": null, "cluster_details": { "1": { "device_type": { "name": "IAS_ZONE", "id": 1026 }, "profile_id": 260, "in_clusters": { "0x0000": { "endpoint_attribute": "basic", "attributes": { "0x0004": { "attribute_name": "manufacturer", "value": "Heiman" }, "0x0005": { "attribute_name": "model", "value": "CO_V15" } }, "unsupported_attributes": {} }, "0x0003": { "endpoint_attribute": "identify", "attributes": {}, "unsupported_attributes": {} }, "0x0500": { "endpoint_attribute": "ias_zone", "attributes": { "0x0000": { "attribute_name": "zone_state", "value": 1 }, "0x0001": { "attribute_name": "zone_type", "value": 43 }, "0x0002": { "attribute_name": "zone_status", "value": 32 }, "0x0010": { "attribute_name": "cie_addr", "value": "00:21:2e:ff:ff:03:2d:f4" } }, "unsupported_attributes": {} }, "0x0001": { "endpoint_attribute": "power", "attributes": {}, "unsupported_attributes": {} }, "0x0009": { "endpoint_attribute": "alarms", "attributes": {}, "unsupported_attributes": {} } }, "out_clusters": { "0x0019": { "endpoint_attribute": "ota", "attributes": {}, "unsupported_attributes": {} } ```
Additional logs ``` 22-10-14 15:39:50.280 DEBUG (MainThread) [zigpy.zcl] [0xEF61:1:0x000a] Received ZCL frame: b'\x10\x96\x00\x00\x00' 2022-10-14 15:39:50.282 DEBUG (MainThread) [zigpy.zcl] [0xEF61:1:0x000a] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=0, direction=, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True, *is_reply=False), tsn=150, command_id=0, *direction=, *is_reply=False) 2022-10-14 15:39:50.286 DEBUG (MainThread) [zigpy.zcl] [0xEF61:1:0x000a] Decoded ZCL frame: Time:Read_Attributes(attribute_ids=[0]) 2022-10-14 15:39:50.287 DEBUG (MainThread) [zigpy.zcl] [0xEF61:1:0x000a] Received command 0x00 (TSN 150): Read_Attributes(attribute_ids=[0]) 2022-10-14 15:39:50.290 DEBUG (MainThread) [zigpy.zcl] [0xEF61:1:0x000a] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=False, direction=, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True, *is_reply=True), tsn=150, command_id=, *direction=, *is_reply=True) 2022-10-14 15:39:50.292 DEBUG (MainThread) [zigpy.zcl] [0xEF61:1:0x000a] Sending reply: Read_Attributes_rsp(status_records=[ReadAttributeRecord(attrid=0x0000, status=, value=TypeValue(type=UTCTime, value=719073590))]) 2022-10-14 15:39:50.296 DEBUG (MainThread) [zigpy_deconz.zigbee.application] Sending packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0x0000), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0xEF61), dst_ep=1, source_route=None, extended_timeout=False, tsn=150, profile_id=260, cluster_id=10, data=Serialized[b'\x18\x96\x01\x00\x00\x00\xe261\xdc*'], tx_options=, radius=0, non_member_radius=0, lqi=None, rssi=None) 2022-10-14 15:39:50.297 DEBUG (MainThread) [zigpy_deconz.api] 'aps_data_indication' response from , ep: 1, profile: 0x0104, cluster_id: 0x000a, data: b'1096000000' 2022-10-14 15:39:50.299 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_request (26, 111, , , 260, 10, 1, b'\x18\x96\x01\x00\x00\x00\xe261\xdc*', , 0) 2022-10-14 15:39:50.300 DEBUG (MainThread) [zigpy_deconz.uart] Send: 0x12d80021001a006f000261ef0104010a00010b00189601000000e23631dc2a0200 2022-10-14 15:39:50.325 DEBUG (MainThread) [zigpy_deconz.uart] Frame received: 0x12d80009000200226f 2022-10-14 15:39:50.326 DEBUG (MainThread) [zigpy_deconz.api] Received command aps_data_request[2, , 111] 2022-10-14 15:39:50.326 DEBUG (MainThread) [zigpy_deconz.api] APS data request response: [2, , 111] 2022-10-14 15:39:50.326 DEBUG (MainThread) [zigpy_deconz.uart] Frame received: 0x0ed9000700a600 2022-10-14 15:39:50.327 DEBUG (MainThread) [zigpy_deconz.api] Received command device_state_changed[, 0] 2022-10-14 15:39:50.327 DEBUG (MainThread) [zigpy_deconz.api] Device state changed response: [, 0] 2022-10-14 15:39:50.328 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_confirm (0,) 2022-10-14 15:39:50.328 DEBUG (MainThread) [zigpy_deconz.uart] Send: 0x04d90007000000 2022-10-14 15:39:50.341 DEBUG (MainThread) [zigpy_deconz.uart] Frame received: 0x04d90013000c00226f0261ef01010000000000 2022-10-14 15:39:50.342 DEBUG (MainThread) [zigpy_deconz.api] Received command aps_data_confirm[12, , 111, , 1, , 0, 0, 0, 0] 2022-10-14 15:39:50.343 DEBUG (MainThread) [zigpy_deconz.api] APS data confirm response for request with id 111: 00 2022-10-14 15:39:50.343 DEBUG (MainThread) [zigpy_deconz.api] Request id: 0x6f 'aps_data_confirm' for , status: 0x00 2022-10-14 15:39:50.421 DEBUG (MainThread) [zigpy_deconz.uart] Frame received: 0x1fda000e0007002fdda1230f0000 2022-10-14 15:39:50.421 DEBUG (MainThread) [zigpy_deconz.api] Received command simplified_beacon[7, 56623, 9121, 15, 0, 0] 2022-10-14 15:39:50.421 DEBUG (MainThread) [zigpy_deconz.api] Received simplified beacon frame: source=0xdd2f, pan_id=0x23a1, channel=15, flags=0x00, update_id=0x00 2022-10-14 15:39:50.437 DEBUG (MainThread) [zigpy_deconz.uart] Frame received: 0x1fdb0015000e004a6fa1230f00006638a1230f0000 2022-10-14 15:39:50.438 DEBUG (MainThread) [zigpy_deconz.api] Received command simplified_beacon[14, 28490, 9121, 15, 0, 0] 2022-10-14 15:39:50.439 DEBUG (MainThread) [zigpy_deconz.api] Received simplified beacon frame: source=0x6f4a, pan_id=0x23a1, channel=15, flags=0x00, update_id=0x00 ```

Additional context image

javicalle commented 2 years ago

It seems that there is another case like this.

Can you try with that quirks:

heidan/smoke.py ```python """Smoke Sensor.""" import zigpy.profiles.zha from zigpy.quirks import CustomDevice from zigpy.zcl.clusters.general import Alarms, Basic, Identify, Ota, PowerConfiguration from zigpy.zcl.clusters.security import IasWd, IasZone import zigpy.zdo.types from zhaquirks.const import ( DEVICE_TYPE, ENDPOINTS, INPUT_CLUSTERS, MODELS_INFO, NODE_DESCRIPTOR, OUTPUT_CLUSTERS, PROFILE_ID, ) from zhaquirks.heiman import HEIMAN class HeimanSmokYDLV10(CustomDevice): """YDLV10 quirk.""" # NodeDescriptor(byte1=2, byte2=64, mac_capability_flags=132, # manufacturer_code=48042, maximum_buffer_size=64, maximum_incoming_transfer_size=0, # server_mask=0, maximum_outgoing_transfer_size=0, descriptor_capability_field=3) # SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=1026, # device_version=0, input_clusters=[0, 3, 1280, 1, 9, 1282], output_clusters=[25]) signature = { MODELS_INFO: [(HEIMAN, "SMOK_YDLV10")], ENDPOINTS: { 1: { PROFILE_ID: zigpy.profiles.zha.PROFILE_ID, DEVICE_TYPE: zigpy.profiles.zha.DeviceType.IAS_ZONE, INPUT_CLUSTERS: [ Basic.cluster_id, PowerConfiguration.cluster_id, Identify.cluster_id, Alarms.cluster_id, IasZone.cluster_id, IasWd.cluster_id, ], OUTPUT_CLUSTERS: [ Ota.cluster_id, ], }, }, } replacement = { NODE_DESCRIPTOR: zigpy.zdo.types.NodeDescriptor( 0x02, 0x40, 0x84 & 0b1111_1011, 0xBBAA, 0x40, 0x0000, 0x0000, 0x0000, 0x03 ), ENDPOINTS: { 1: { PROFILE_ID: zigpy.profiles.zha.PROFILE_ID, DEVICE_TYPE: zigpy.profiles.zha.DeviceType.IAS_ZONE, INPUT_CLUSTERS: [ Basic.cluster_id, PowerConfiguration.cluster_id, Identify.cluster_id, Alarms.cluster_id, IasZone.cluster_id, IasWd.cluster_id, ], OUTPUT_CLUSTERS: [ Ota.cluster_id, ], }, }, } class HeimanSmokCO_V15(CustomDevice): """CO_V15 quirk.""" # NodeDescriptor( # logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, # frequency_band=, mac_capability_flags=, # manufacturer_code=48042, maximum_buffer_size=64, maximum_incoming_transfer_size=0, server_mask=0, maximum_outgoing_transfer_size=0, # descriptor_capability_field=, # *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, # *is_mains_powered=True, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False # )" signature = { MODELS_INFO: [(HEIMAN, "CO_V15")], ENDPOINTS: { # "profile_id": 260,"device_type": "0x0402", # "in_clusters": ["0x0000","0x0001","0x0003","0x0009","0x0500"], # "out_clusters": ["0x0019"] 1: { PROFILE_ID: zigpy.profiles.zha.PROFILE_ID, DEVICE_TYPE: zigpy.profiles.zha.DeviceType.IAS_ZONE, INPUT_CLUSTERS: [ Basic.cluster_id, PowerConfiguration.cluster_id, Identify.cluster_id, Alarms.cluster_id, IasZone.cluster_id, ], OUTPUT_CLUSTERS: [ Ota.cluster_id, ], }, }, } replacement = { NODE_DESCRIPTOR: zigpy.zdo.types.NodeDescriptor( 0x02, 0x40, 0x84 & 0b1111_1011, 0xBBAA, 0x40, 0x0000, 0x0000, 0x0000, 0x03 ), ENDPOINTS: { 1: { PROFILE_ID: zigpy.profiles.zha.PROFILE_ID, DEVICE_TYPE: zigpy.profiles.zha.DeviceType.IAS_ZONE, INPUT_CLUSTERS: [ Basic.cluster_id, PowerConfiguration.cluster_id, Identify.cluster_id, Alarms.cluster_id, IasZone.cluster_id, ], OUTPUT_CLUSTERS: [ Ota.cluster_id, ], }, }, } ```

There is a guide about enabling custom quirks:

Create a new smoke.py file in your local quirks folder. Put the proposed code in the new file. Restart HA and pair you device again. Check that the device is loading the quirk and that the device signature has changed.

cobirnm commented 2 years ago

@javicalle, this worked like a charm!!!! Thank you. Should I close this or do you want to make a PR with this issue?

javicalle commented 2 years ago

No, don't close yet.