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
744 stars 678 forks source link

[Device Support Request] Aqara Smoke Detector JY-GZ-01AQ #1828

Closed wishie closed 1 year ago

wishie commented 2 years ago

I am looking to help add support for this smoke detector into ZHA.

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=4447, maximum_buffer_size=127, maximum_incoming_transfer_size=100, server_mask=11264, maximum_outgoing_transfer_size=100, 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", "0x0500" ], "out_clusters": [ "0x0019" ] } }, "manufacturer": "LUMI", "model": "lumi.sensor_smoke.acn03", "class": "zigpy.device.Device" } ```
Diagnostic information ```yaml { "home_assistant": { "installation_type": "Home Assistant Container", "version": "2022.10.1", "dev": false, "hassio": false, "virtualenv": false, "python_version": "3.10.5", "docker": true, "arch": "x86_64", "timezone": "Australia/Brisbane", "os_name": "Linux", "os_version": "5.19.9-Unraid", "run_as_root": true }, "custom_components": { "watchman": { "version": "0.5.1", "requirements": [ "prettytable==3.0.0" ] }, "fullykiosk": { "version": "1.1.0", "requirements": [ "python-fullykiosk==0.0.11" ] }, "goodwe": { "version": "1.0.0", "requirements": [ "goodwe==0.2.20" ] }, "iotawatt": { "version": "0.2.1", "requirements": [ "iotawattpy==0.1.0" ] }, "bayislandsguide": { "version": "1.0.0", "requirements": [] }, "smartthinq_sensors": { "version": "0.24.2", "requirements": [ "pycountry>=20.7.3", "xmltodict>=0.12.0", "cchardet>=2.1.7" ] }, "unifigateway": { "version": "0.3.3", "requirements": [ "pyunifi==2.21" ] }, "spotcast": { "version": "v3.6.30", "requirements": [ "spotify_token==1.0.0" ] }, "weatherflow": { "version": "1.0.6", "requirements": [ "pyweatherflowrest==1.0.8" ] }, "sonoff": { "version": "3.3.1", "requirements": [ "pycryptodome>=3.6.6" ] }, "bureau_of_meteorology": { "version": "1.1.18", "requirements": [ "iso8601" ] }, "hacs": { "version": "1.28.0", "requirements": [ "aiogithubapi>=22.2.4" ] }, "garbage_collection": { "version": "4.8.3", "requirements": [ "python-dateutil>=2.8.2" ] } }, "integration_manifest": { "domain": "zha", "name": "Zigbee Home Automation", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/zha", "requirements": [ "bellows==0.34.1", "pyserial==3.5", "pyserial-asyncio==0.6", "zha-quirks==0.0.82", "zigpy-deconz==0.19.0", "zigpy==0.51.2", "zigpy-xbee==0.16.0", "zigpy-zigate==0.10.0", "zigpy-znp==0.9.0" ], "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*" } ], "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": 55507, "manufacturer": "LUMI", "model": "lumi.sensor_smoke.acn03", "name": "LUMI lumi.sensor_smoke.acn03", "quirk_applied": false, "quirk_class": "zigpy.device.Device", "manufacturer_code": 4447, "power_source": "Mains", "lqi": 174, "rssi": null, "last_seen": "2022-10-14T20:29:05", "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=4447, maximum_buffer_size=127, maximum_incoming_transfer_size=100, server_mask=11264, maximum_outgoing_transfer_size=100, 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", "0x0500" ], "out_clusters": [ "0x0019" ] } } }, "active_coordinator": false, "entities": [ { "entity_id": "button.lumi_lumi_sensor_smoke_acn03_identifybutton", "name": "LUMI lumi.sensor_smoke.acn03" }, { "entity_id": "binary_sensor.kitchen_smoke_detector", "name": "LUMI lumi.sensor_smoke.acn03" } ], "neighbors": [], "endpoint_names": [ { "name": "IAS_ZONE" } ], "user_given_name": "Kitchen Smoke Detector", "device_reg_id": "8aff90d673e35fdb59aa747a5748a165", "area_id": "c8f14518f5d04160aebbc97923659fc0", "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": "LUMI" }, "0x0005": { "attribute_name": "model", "value": "lumi.sensor_smoke.acn03" } }, "unsupported_attributes": {} }, "0x0500": { "endpoint_attribute": "ias_zone", "attributes": { "0x0000": { "attribute_name": "zone_state", "value": 1 }, "0x0001": { "attribute_name": "zone_type", "value": 40 }, "0x0002": { "attribute_name": "zone_status", "value": 0 }, "0x0010": { "attribute_name": "cie_addr", "value": [ 129, 116, 194, 36, 0, 75, 18, 0 ] } }, "unsupported_attributes": {} }, "0x0003": { "endpoint_attribute": "identify", "attributes": {}, "unsupported_attributes": {} }, "0x0001": { "endpoint_attribute": "power", "attributes": {}, "unsupported_attributes": {} } }, "out_clusters": { "0x0019": { "endpoint_attribute": "ota", "attributes": {}, "unsupported_attributes": {} } } } } } } ```
Additional logs ``` Paste any additional debug logs here. Don't remove the extra line breaks outside the ``` marks. ```

Additional context The device apparently has full support in Z2M, and the details of that can be seen here: https://www.zigbee2mqtt.io/devices/JY-GZ-01AQ.html

johnboiles commented 1 year ago

Could you press the button on the smoke alarm to generate one of the "Xiaomi attribute reports" again? (which includes a bunch of data that should now be properly named)

Looks like @Axionkt got one! Thanks @Axionkt. I can do this on Monday also when I'm back with the alarms (in my office).

Yep, we could probably do this, but that would need to be done in ZHA (HA Core) itself

Cool no rush, obviously smoke detection is the most important function of a smoke detector :) Thanks for all your work on this so far!

I'd love to have one, but I'm based in Germany, so I guess shipping will be a bit difficult.

Yeah for sure. Happy to send you some $$ on PayPal or something for one if you want!

TheJulianJES commented 1 year ago

Nice! The logs are all really helpful. It looks like attribute reporting is properly set up for buzzer_manual_mute for example. So that would be that HA entity possible relatively easily.

I do wonder if we need to parse these "Xiaomi attribute reports" at all:

[xiaomi] 54:ef:44:10:00:5a:6f:93 - Attribute report. attribute_id: [247] value: [{'battery_voltage_mV': 3070, 'temperature': 25, 'X-attrib-4': 5032, 'X-attrib-5': 43, 'X-attrib-6': 4, '0xff01-8': 273, 'path': 0, '0xff01-12': 1, '0xff01-102': 3, '0xff01-103': 1, '0xff01-104': 168, 'smoke': 1, 'smoke_density': 10, 'test': 0, 'buzzer_manual_mute': 1, 'heartbeat_indicator': 0, 'linkage_alarm': 0}]

Currently, only the smoke attribute is parsed from that (but only a normal attribute report is sent when smoke is detected, so the above doesn't seem to really matter?). I wonder if these Xiaomi attribute reports are really only sent when the button is pressed or periodically?

Looks like @Axionkt got one! Thanks @Axionkt. I can do this on Monday also when I'm back with the alarms (in my office).

@johnboiles Yep, it would be nice if you could also get one of these Xiaomi attribute reports then (so the [xiaomi] log lines when you press the button). I wonder if there are model differences. Z2M had a bunch of duplicated Xiaomi attributes in those reports, but they don't seem to be in the Xiaomi attribute report from @Axionkt

Yeah for sure. Happy to send you some $$ on PayPal or something for one if you want!

I've had a look on AliExpress and they seem to go for about 42€ (44 USD). Shipping will probably take a bit, but it would make the entity stuff in HA easier for me if I had one. If you want, you can contact me at julian.tjj@proton.me (or Discord: TheJulianJES#2774) and I can send you my PayPal address (different from that email). (No need/pressure for you to send me anything of course)

johnboiles commented 1 year ago

This is what I got when I pushed the button!

{
    'battery_voltage_mV': 3202,
    'temperature': 25,
    'X-attrib-4': 5032,
    'X-attrib-5': 15,
    'X-attrib-6': 1,
    '0xff01-8': 273,
    'path': 0,
    '0xff01-12': 1,
    '0xff01-102': 3,
    '0xff01-103': 1,
    '0xff01-104': 168,
    'smoke': 0,
    'smoke_density': 0,
    'test': 0,
    'buzzer_manual_mute': 0,
    'heartbeat_indicator': 0,
    'linkage_alarm': 0
}
Full logs from pushing the button ``` 2023-02-27 13:20:23.091 DEBUG (MainThread) [bellows.ezsp.protocol] Application frame received incomingMessageHandler: [, EmberApsFrame(profileId=260, clusterId=0, sourceEndpoint=1, destinationEndpoint=1, options=, groupId=0, sequence=96), 156, -61, 0xbc5c, 255, 255, b'\x18x\n\x05\x00B\x17lumi.sensor_smoke.acn03'] 2023-02-27 13:20:23.092 DEBUG (MainThread) [bellows.zigbee.application] Received incomingMessageHandler frame with [, EmberApsFrame(profileId=260, clusterId=0, sourceEndpoint=1, destinationEndpoint=1, options=, groupId=0, sequence=96), 156, -61, 0xbc5c, 255, 255, b'\x18x\n\x05\x00B\x17lumi.sensor_smoke.acn03'] 2023-02-27 13:20:23.092 DEBUG (MainThread) [zigpy.application] Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xBC5C), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=96, profile_id=260, cluster_id=0, data=Serialized[b'\x18x\n\x05\x00B\x17lumi.sensor_smoke.acn03'], tx_options=, radius=0, non_member_radius=0, lqi=156, rssi=-61) 2023-02-27 13:20:23.093 DEBUG (MainThread) [zigpy.zcl] [0xBC5C:1:0x0000] Received ZCL frame: b'\x18x\n\x05\x00B\x17lumi.sensor_smoke.acn03' 2023-02-27 13:20:23.094 DEBUG (MainThread) [zigpy.zcl] [0xBC5C:1:0x0000] 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=True), tsn=120, command_id=10, *direction=, *is_reply=True) 2023-02-27 13:20:23.097 DEBUG (MainThread) [zigpy.zcl] [0xBC5C:1:0x0000] Decoded ZCL frame: Basic:Report_Attributes(attribute_reports=[Attribute(attrid=0x0005, value=TypeValue(type=CharacterString, value='lumi.sensor_smoke.acn03'))]) 2023-02-27 13:20:23.098 DEBUG (MainThread) [zigpy.zcl] [0xBC5C:1:0x0000] Received command 0x0A (TSN 120): Report_Attributes(attribute_reports=[Attribute(attrid=0x0005, value=TypeValue(type=CharacterString, value='lumi.sensor_smoke.acn03'))]) 2023-02-27 13:20:23.099 DEBUG (MainThread) [zigpy.zcl] [0xBC5C:1:0x0000] Attribute report received: model='lumi.sensor_smoke.acn03' 2023-02-27 13:20:23.115 DEBUG (MainThread) [bellows.ezsp.protocol] Application frame received incomingMessageHandler: [, EmberApsFrame(profileId=260, clusterId=64704, sourceEndpoint=1, destinationEndpoint=1, options=, groupId=0, sequence=97), 156, -61, 0xbc5c, 255, 255, b'\x1c_\x11y\n\xf7\x00A>\x01!\x82\x0c\x03(\x19\x04!\xa8\x13\x05!\x0f\x00\x06$\x01\x00\x00\x00\x00\x08!\x11\x01\n!\x00\x00\x0c \x01f \x03g \x01h!\xa8\x00\xa0!\x00\x00\xa1 \x00\xa2 \x00\xa3 \x00\xa4 \x00\xa5 \x00'] 2023-02-27 13:20:23.116 DEBUG (MainThread) [bellows.zigbee.application] Received incomingMessageHandler frame with [, EmberApsFrame(profileId=260, clusterId=64704, sourceEndpoint=1, destinationEndpoint=1, options=, groupId=0, sequence=97), 156, -61, 0xbc5c, 255, 255, b'\x1c_\x11y\n\xf7\x00A>\x01!\x82\x0c\x03(\x19\x04!\xa8\x13\x05!\x0f\x00\x06$\x01\x00\x00\x00\x00\x08!\x11\x01\n!\x00\x00\x0c \x01f \x03g \x01h!\xa8\x00\xa0!\x00\x00\xa1 \x00\xa2 \x00\xa3 \x00\xa4 \x00\xa5 \x00'] 2023-02-27 13:20:23.116 DEBUG (MainThread) [zigpy.application] Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0xBC5C), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=97, profile_id=260, cluster_id=64704, data=Serialized[b'\x1c_\x11y\n\xf7\x00A>\x01!\x82\x0c\x03(\x19\x04!\xa8\x13\x05!\x0f\x00\x06$\x01\x00\x00\x00\x00\x08!\x11\x01\n!\x00\x00\x0c \x01f \x03g \x01h!\xa8\x00\xa0!\x00\x00\xa1 \x00\xa2 \x00\xa3 \x00\xa4 \x00\xa5 \x00'], tx_options=, radius=0, non_member_radius=0, lqi=156, rssi=-61) 2023-02-27 13:20:23.118 DEBUG (MainThread) [zigpy.zcl] [0xBC5C:1:0xfcc0] Received ZCL frame: b'\x1c_\x11y\n\xf7\x00A>\x01!\x82\x0c\x03(\x19\x04!\xa8\x13\x05!\x0f\x00\x06$\x01\x00\x00\x00\x00\x08!\x11\x01\n!\x00\x00\x0c \x01f \x03g \x01h!\xa8\x00\xa0!\x00\x00\xa1 \x00\xa2 \x00\xa3 \x00\xa4 \x00\xa5 \x00' 2023-02-27 13:20:23.119 DEBUG (MainThread) [zigpy.zcl] [0xBC5C:1:0xfcc0] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=, is_manufacturer_specific=True, direction=, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True, *is_reply=True), manufacturer=4447, tsn=121, command_id=10, *direction=, *is_reply=True) 2023-02-27 13:20:23.120 DEBUG (MainThread) [zigpy.zcl] [0xBC5C:1:0xfcc0] Decoded ZCL frame: OppleCluster:Report_Attributes(attribute_reports=[Attribute(attrid=0x00F7, value=TypeValue(type=LVBytes, value=b'\x01!\x82\x0c\x03(\x19\x04!\xa8\x13\x05!\x0f\x00\x06$\x01\x00\x00\x00\x00\x08!\x11\x01\n!\x00\x00\x0c \x01f \x03g \x01h!\xa8\x00\xa0!\x00\x00\xa1 \x00\xa2 \x00\xa3 \x00\xa4 \x00\xa5 \x00'))]) 2023-02-27 13:20:23.120 DEBUG (MainThread) [zigpy.zcl] [0xBC5C:1:0xfcc0] Received command 0x0A (TSN 121): Report_Attributes(attribute_reports=[Attribute(attrid=0x00F7, value=TypeValue(type=LVBytes, value=b'\x01!\x82\x0c\x03(\x19\x04!\xa8\x13\x05!\x0f\x00\x06$\x01\x00\x00\x00\x00\x08!\x11\x01\n!\x00\x00\x0c \x01f \x03g \x01h!\xa8\x00\xa0!\x00\x00\xa1 \x00\xa2 \x00\xa3 \x00\xa4 \x00\xa5 \x00'))]) 2023-02-27 13:20:23.120 DEBUG (MainThread) [zigpy.zcl] [0xBC5C:1:0xfcc0] Attribute report received: 0x00F7=b'\x01!\x82\x0c\x03(\x19\x04!\xa8\x13\x05!\x0f\x00\x06$\x01\x00\x00\x00\x00\x08!\x11\x01\n!\x00\x00\x0c \x01f \x03g \x01h!\xa8\x00\xa0!\x00\x00\xa1 \x00\xa2 \x00\xa3 \x00\xa4 \x00\xa5 \x00' 2023-02-27 13:20:23.122 WARNING (MainThread) [xiaomi] 54:ef:44:10:00:71:1c:25 - Attribute report. attribute_id: [247] value: [{'battery_voltage_mV': 3202, 'temperature': 25, 'X-attrib-4': 5032, 'X-attrib-5': 15, 'X-attrib-6': 1, '0xff01-8': 273, 'path': 0, '0xff01-12': 1, '0xff01-102': 3, '0xff01-103': 1, '0xff01-104': 168, 'smoke': 0, 'smoke_density': 0, 'test': 0, 'buzzer_manual_mute': 0, 'heartbeat_indicator': 0, 'linkage_alarm': 0}] 2023-02-27 13:20:23.136 DEBUG (MainThread) [homeassistant.components.zha.core.channels.base] [0xBC5C:1:0x0500]: Updated alarm state: 0 ```
TheJulianJES commented 1 year ago

Okay, it looks like all the "Xiaomi attribute reports" that end with "2" in my PR are unused (at least by this model/firmware). So I'll probably remove them for now.

TheJulianJES commented 1 year ago

Got the sensor today and I'm currently working on it. Was able to clean up the quirk code a bit and got entities in HA. The only entity that is currently missing is the "smoke density" one. The 0 to 10 for smoke density could be easily exposed, but Z2M does some internal conversion from Xiaomi's scale to dB/m. I don't think exposing both is great, so we could either (1) just expose the raw value, (2) do the conversion in zha-quirks and then update it as a fake attribute, or (3) do the conversion in HA Core itself. Have to think about this.

Due to how ZHA currently works, the other entities will be exposed as a configuration entities, but I think that should be fine (not in area calls and not exposed to cloud/Alexa/Google Assistant/... by default).

Although I've read contradicting information, I think the linkage alarm works like this (have yet to confirm this): When there's smoke without linkage alarm, the "linkage alarm state" binary sensor does NOT turn on. (edit: CONFIRMED) When there's smoke with linkage alarm enabled, the "linkage alarm state" binary sensor turns on for until how long the smoke is present OR the sensor is muted (either via UI or by a button press/hold). (edit: CONFIRMED) Muting the alarm manually (during an alarm) also triggers the switch in the UI to "on". (Although the complete "reset" with holding might only be possible with the device itself (or wait 10 minutes for it to clear I guess?)).

The manual "buzzer manual alarm" works regardless of if linkage alarm is enabled for me.

When triggering it manually, the manual alarm seems to take priority over the manual mute. I think it's best if these are just kept as two switches instead of doing anything more complicated.

Z2M implemented some of these features in a bit of a weird way from what I can see. Write only and then another sensor entity for reading.

This is how it currently looks in HA:

image

If you have different ideas for default mdi icons, please let me know. (https://pictogrammers.com/library/mdi/)

Currently, I'm also not actually parsing the Xiaomi attribute reports (except for smoke, but I could probably drop that too). It looks like these reports are only sent when pressing the button (and maybe once every couple of hours?) I don't really see a benefit, as the custom attributes themselves report properly by themselves.

EDIT: Hmm, "sometimes" toggling the entities fails, as the smoke sensor doesn't wake up/poll properly I guess. But there's nothing I can do about that.

RSDynamics commented 1 year ago

Thanks for your great work! I copied your smoke.py and init.py from the xiomi folder but I only see the Iaszone and the diagnostics. I have three of these detectors and I removed them all, deleted the pycache but the end result stays the same. Is there something else I should do to get the rest of the entities? Thnx!

Edit: got some more time to test. The power source of the device is Mains so no battery percentage is shown as an entity. The Quirk is picked up and via the Manage Zigbee device I can read and write to the endpoints Only no entities as in your screenshot.

After checking the pairing logs: Could this be the issue? 2023-03-07 08:19:17.171 DEBUG (MainThread) [zigpy.appdb] Error handling '_save_attribute' event with (54:ef:44:10:00:5a:76:a2, 1, 0, 4, 'LUMI') params: FOREIGN KEY constraint failed

I renamed the zigbee.db so it created a new one and tried pairing again but got the same results.

TheJulianJES commented 1 year ago

The zigbee.db thing isn't the issue. Due to how ZHA works at the moment, the entities need to be created in Home Assistant Core. There's no good way to test that. (I'm also not sure if I already pushed those changes, but I might have)

javicalle commented 1 year ago

You've probably thought of this already, but would it make sense to set Buzzer manual alarm and Buzzer manual mute as buttons instead of switches? In the case of Buzzer manual alarm how/when is the value reset to off?

TheJulianJES commented 1 year ago

The smoke detector itself can reset that and you can also disable the mute during an active alarm again and the alarm resumes (as long as there's smoke). It's also toggled (and reflected in HA UI) if it's changed by clicking the button on the sensor during an alarm.

RSDynamics commented 1 year ago

Hi @TheJulianJES I don't know if this is to be expected in the current state but I have two things that don't work with this quirk in my environment.

On the the Device Information tab of the device the powersource the keeps stating "Mains" and no battery battery entities are created. When I read the values with the Manage Zigbee Device function, in the power_source (id: 0x0007) in the Basic cluster states PowerSource.Battery. I don't know if this is important but when I read the battery_size (id: 0x0031) from the PowerConfiguration cluster it states CR2 but the actual battery size is CR17450. In the PowerConfiguration cluster I can get the battery_voltage (id: 0x0020) and other battery values but the battery_percentage_remaining (id: 0x0021) states None.

Also when I try to trigger the self_test with value 1 from the Manage Zigbee Device function the write seems to succeed but the self_test is not triggered. When I use the zha_toolkit service and send attr_type 16 with attr_val 1 to the attribute 295 the self_test does fire. Maybe the attr_type is wrong?

Thanks for al the great work!

TheJulianJES commented 1 year ago

no battery battery entities are created

Good point. I think I might have forgotten to add the Xiaomi PowerConfiguration cluster to the replacement. Will do that next.

On the the Device Information tab of the device the powersource the keeps stating "Mains"

Hmm, we might need to override the node descriptor then. On the other hand, this means that ZHA uses the "shorter mains-powered devices" timeout for these devices (which seems to work).

when I read the battery_size (id: 0x0031) from the PowerConfiguration cluster it states CR2 but the actual battery size is CR17450.

Yeah, I think ZHA doesn't "support" that battery size.

Also when I try to trigger the self_test with value 1 from the Manage Zigbee Device function the write seems to succeed but the self_test is not triggered.

That's weird. It works properly for me.

Maybe the attr_type is wrong?

I'll have a look again. Maybe I changed some things and forgot to push them(?) (Or I just tested it using the HA entities)

TheJulianJES commented 1 year ago

The quirk is updated now. Haven't tested self-test again, but battery should work now. (Battery size won't/shouldn't display though, as it's unsupported)

RSDynamics commented 1 year ago

Updated the quirk and battery works! Great work!

The self test still does not work for me. These are the messages send to the device which I could find in the logs. I sent them to different addresses so I could keep the messages apart in the logging but they are configured the same. The data string that is sent is different so maybe this helps you to see what is different?

From the Device manager 2023-03-11 10:33:12.608 DEBUG (MainThread) [zigpy_znp.zigbee.application] Sending packet ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0x0000), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x8F19), dst_ep=1, source_route=None, extended_timeout=True, tsn=74, profile_id=260, cluster_id=64704, data=Serialized[b"\x04_\x11J\x02'\x01 \x01"], tx_options=, radius=0, non_member_radius=0, lqi=None, rssi=None) 2023-03-11 10:33:12.613 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=, address=0x8F19), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=64704, TSN=74, Options=, Radius=0, Data=b'\x04\x5F\x11\x4A\x02\x27\x01\x20\x01')
From zha toolkit 2023-03-11 10:42:56.517 DEBUG (MainThread) [zigpy_znp.zigbee.application] Sending packet ZigbeePacket(src=AddrModeAddress(addr_mode=, address=0x0000), src_ep=1, dst=AddrModeAddress(addr_mode=, address=0x3850), dst_ep=1, source_route=None, extended_timeout=True, tsn=28, profile_id=260, cluster_id=64704, data=Serialized[b"\x04_\x11\x1c\x00'\x01"], tx_options=, radius=0, non_member_radius=0, lqi=None, rssi=None) 2023-03-11 10:42:56.520 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=, address=0x3850), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=64704, TSN=28, Options=, Radius=0, Data=b'\x04\x5F\x11\x1C\x00\x27\x01')
johnboiles commented 1 year ago

Just updated everything and I've got batteries too! Neat! Great work @TheJulianJES

image
JohnDoeXX commented 1 year ago

Hello. I'm new to Home Assistant and github. I saved the init.py and smoke.py files in the directory - config/custom_zha_quirks/xiaomi (both files in the same directory). The smoke detector still only shows as 2 entities by default an IASZone and a Button. The text in the init.py file has 767 lines and the text in the smoke.py file has 131 lines. All other xiaomi devices show Quirks - zhaquirks.xiaomi.aqara.x (where x is wleak, magnet, weather atc.) only smoke detector shows zigpy.device.Device. Any advice? Thank you for answer.

johnboiles commented 1 year ago

@JohnDoeXX two other things you need to do. Add this to your configuration.yaml

zha:
  custom_quirks_path: /config/custom_zha_quirks/

And also edit smoke.py to reference your local xiaomi package on line 22. It should look like this:

from . import LUMI, XiaomiAqaraE1Cluster, XiaomiPowerConfiguration
JohnDoeXX commented 1 year ago

Thanks for answer. I will try this after getting home.

JohnDoeXX commented 1 year ago

zha: custom_quirks_path: /config/custom_zha_quirks/ After add this to yaml file, I see battery status and previous entities (lASZone and a Button) nothing more. I don't know what to change in smoke.py file.

JohnDoeXX commented 1 year ago

Smoke detector shows Quirks - xiaomi.smoke.LumiSensorSmokeAcn03

TheJulianJES commented 1 year ago

I see battery status and previous entities (lASZone and a Button) nothing more

Yes, although the IASZone entity should work with the custom quirk. More functionality will be added with https://github.com/home-assistant/core/pull/90159 (which requires the quirk to be merged into zha-quirks and have the library bumped in HA Core). Not sure if the "smoke density" will make it into the first version though. The device exposes a number from 0 to 10, but the Aqara mobile app and Z2M remap it. There's no proper unit constant for that in HA Core though and the attribute is "faked", as I remap it in quirks now.

JohnDoeXX commented 1 year ago

And also edit smoke.py to reference your local xiaomi package on line 22. It should look like this: from . import LUMI, XiaomiAqaraE1Cluster, XiaomiPowerConfiguration

Anybody has idea what should be in the line 22 above?

TheJulianJES commented 1 year ago

@RSDynamics

The self test still does not work for me.

Fixed now. If everything goes well, the quirk and entities in HA should be available in the next release.

RSDynamics commented 1 year ago

Tested it and works perfect! thanks!

RSDynamics commented 1 year ago

The new entities were populated after a repair of the devices. Everything works great. I didn't remove the quirks yet. How can I see the current version of zigpy that is active in HA?

javicalle commented 1 year ago

I usually check the manifest file from the tag version: https://github.com/home-assistant/core/blob/2023.4.1/homeassistant/components/zha/manifest.json

MattWestb commented 1 year ago

I think you is getting all in the diagnostic the you downloading it fro the device and looking in it if i remember right.

TheJulianJES commented 1 year ago

If you're running HA 2023.4.0 or later, then you should delete the custom quirk.

Caligo82 commented 1 year ago

Using the recent core and the integrated quirks I seem to be missing the whole configuration entities. I got all the sensors though, confirmed working. Is this intentional due to early implementation or do I need to do some debugging?

johnboiles commented 1 year ago

I removed my custom quirks and I've got them. It was seamless for me to remove the custom quirks

image
Caligo82 commented 1 year ago

Well I never used the custom quirks in the first place. Thats what I got: Screenshot_20230412_013437_Home Assistant

TheJulianJES commented 1 year ago

Looks like it didn't pair properly (not all attributes were read during pairing). Try to restart HA and/or re-pair the sensor. In the worst case, you should be able to read the attributes manually through the clusters UI, reboot HA, and then see the entities.

Also, what coordinator are you using? And what firmware is running on it?

Caligo82 commented 1 year ago

Had to completly remove the device and repair it, now I have all the switches. Great work, thanks very much! Using it over a Conbee II USB stick with supposedly the latest firmware in a supervised docker environment in latest debian. Healthy installation and so on.

Caligo82 commented 1 year ago

Is there a certain amount of time before it triggers the linkage alarm? I struggle to keep the smoke on long enough. In any case, I didn't see anything triggered yet on my second sensor... It's not really an issue, as we can manually create a trigger automation. But since it's already there as a config entitiy we might as well use that.

TheJulianJES commented 1 year ago

That's not how linkage alarm works. There's more info in this comment: https://github.com/zigpy/zha-device-handlers/issues/1828#issuecomment-1457122551

You might want an automation to turn on "buzzer manual alarm" on all other smoke sensors if the linkage alarm entity goes off on one of them. That linkage sensor entity will turn off if either the smoke is gone (like the normal smoke entity) OR when you mute it with the button.

Caligo82 commented 1 year ago

As @TheJulianJES mentioned: Due to the not ideal polling of the sensor the toggles are unreliable. For the link alarm - do you think Aqara just spams the other unit until it reacts or would you expect the polling to work reliable with the Aqara Hub instead of a custom Zigbee network? I'll probably try to use Nodered to activate the link alarm, some repeating node until the toggle gets switched.

On a general note: there seem to be issues with sending zigbee commands to aqara devices. I'm having a similar issue with the motion reset of the Aqara FP1 presence sensor. From what I read probably 'cause they're not really adhering to all zigbee standards...

TheJulianJES commented 1 year ago

No issues with the FP1 here. It's an end-device but "mains-powered" and the reset button also seems to be reliable.

Regarding the smoke sensor, you could probably have it repeat multiple times (with a delay of ~10 seconds each time) in the worst case. What coordinator are you using though?

github-actions[bot] commented 1 year ago

There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates. Please make sure to update to the latest version and check if that solves the issue. Let us know if that works for you by adding a comment 👍 This issue has now been marked as stale and will be closed if no further activity occurs. Thank you for your contributions.