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
683 stars 634 forks source link

Add Xiaomi E1 Driver Support (lumi.curtain.acn003, model ZNCLBL01LM) #2860

Open BackedUpBooty opened 6 months ago

BackedUpBooty commented 6 months ago

Problem description

Connects out of the box to ZHA. HA functionality is limited to control with sliders only (open / close buttons don't work, call service cover.open/close by extension don't work, no option to invert direction, no battery or light sensor info).

Issue #2629 provides a quirk for the agl001 (global version of the Chinese acn003). Changing the quirk line 127 to acn003 and applying the quirk results in a working illuminance sensor and open / close buttons. Battery status is now a sensor but is 'Unknown' and no direction invert options seem present.

Solution description

Searching for a solution to add in a functioning battery status and inverted direction option.

Screenshots/Video

Screenshots/Video ![image](https://github.com/zigpy/zha-device-handlers/assets/53868636/521c9159-d0fa-4c51-b1f3-81a76b76ea94) Screenshot using the quirk from #2629

Device signature

Device signature ```json { "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=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": "0x0104", "device_type": "0x0202", "input_clusters": [ "0x0000", "0x0001", "0x0003", "0x000a", "0x0102", "0x0400", "0xfcc0" ], "output_clusters": [ "0x0003", "0x000a", "0x0019" ] } }, "manufacturer": "LUMI", "model": "lumi.curtain.acn003", "class": "aqara_e1_driver.DriverE1" } ```

Diagnostic information

Diagnostic information ```json { "home_assistant": { "installation_type": "Home Assistant OS", "version": "2023.12.3", "dev": false, "hassio": true, "virtualenv": false, "python_version": "3.11.6", "docker": true, "arch": "aarch64", "timezone": "Asia/Tokyo", "os_name": "Linux", "os_version": "6.1.63-haos", "supervisor": "2023.12.0", "host_os": "Home Assistant OS 11.2", "docker_version": "24.0.7", "chassis": "embedded", "run_as_root": true }, "custom_components": { "flashforge_adventurer_3": { "version": "1.0.0", "requirements": [] }, "watchman": { "version": "0.5.1", "requirements": [ "prettytable==3.0.0" ] }, "icloud3": { "version": "2.4.7", "requirements": [] }, "sengledapi": { "version": "0.2", "requirements": [ "paho-mqtt>=1.6.1" ] }, "google_fit": { "version": "v3.0.0", "requirements": [ "oauth2client==4.1.3", "google-api-python-client==2.82.0" ] }, "xiaomi_miot": { "version": "0.7.14", "requirements": [ "construct>=2.10.56", "python-miio>=0.5.6", "micloud>=0.3" ] }, "hacs": { "version": "1.33.0", "requirements": [ "aiogithubapi>=22.10.1" ] }, "browser_mod": { "version": "2.3.0", "requirements": [] }, "asusrouter": { "version": "0.25.0", "requirements": [ "asusrouter==1.4.0" ] }, "adaptive_lighting": { "version": "1.20.0", "requirements": [ "ulid-transform" ] }, "hass_agent": { "version": "2022.11.9", "requirements": [] }, "alexa_media": { "version": "4.8.1", "requirements": [ "alexapy==1.27.10", "packaging>=20.3", "wrapt>=1.14.0" ] }, "dwains_dashboard": { "version": "3.6.0", "requirements": [] } }, "integration_manifest": { "domain": "zha", "name": "Zigbee Home Automation", "after_dependencies": [ "onboarding", "usb" ], "codeowners": [ "@dmulcahey", "@adminiuga", "@puddly", "@TheJulianJES" ], "config_flow": true, "dependencies": [ "file_upload" ], "documentation": "https://www.home-assistant.io/integrations/zha", "iot_class": "local_polling", "loggers": [ "aiosqlite", "bellows", "crccheck", "pure_pcapy3", "zhaquirks", "zigpy", "zigpy_deconz", "zigpy_xbee", "zigpy_zigate", "zigpy_znp", "universal_silabs_flasher" ], "requirements": [ "bellows==0.37.3", "pyserial==3.5", "pyserial-asyncio==0.6", "zha-quirks==0.0.107", "zigpy-deconz==0.22.2", "zigpy==0.60.1", "zigpy-xbee==0.20.1", "zigpy-zigate==0.12.0", "zigpy-znp==0.12.0", "universal-silabs-flasher==0.0.15", "pyserial-asyncio-fast==0.11" ], "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": "0403", "pid": "6015", "description": "*conbee*", "known_devices": [ "Conbee III" ] }, { "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" ] } ], "zeroconf": [ { "type": "_esphomelib._tcp.local.", "name": "tube*" }, { "type": "_zigate-zigbee-gateway._tcp.local.", "name": "*zigate*" }, { "type": "_zigstar_gw._tcp.local.", "name": "*zigstar*" }, { "type": "_uzg-01._tcp.local.", "name": "uzg-01*" }, { "type": "_slzb-06._tcp.local.", "name": "slzb-06*" } ], "is_built_in": true }, "data": { "ieee": "**REDACTED**", "nwk": 12072, "manufacturer": "LUMI", "model": "lumi.curtain.acn003", "name": "LUMI lumi.curtain.acn003", "quirk_applied": true, "quirk_class": "aqara_e1_driver.DriverE1", "quirk_id": null, "manufacturer_code": 4447, "power_source": "Battery or Unknown", "lqi": 232, "rssi": -42, "last_seen": "2023-12-24T12:25:21", "available": true, "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=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": "0x0104", "device_type": "0x0202", "input_clusters": [ "0x0000", "0x0001", "0x0003", "0x000a", "0x0102", "0x0400", "0xfcc0" ], "output_clusters": [ "0x0003", "0x000a", "0x0019" ] } }, "manufacturer": "LUMI", "model": "lumi.curtain.acn003" }, "active_coordinator": false, "entities": [ { "entity_id": "sensor.curtain_br1_battery", "name": "LUMI lumi.curtain.acn003" }, { "entity_id": "cover.curtain_br1_cover", "name": "LUMI lumi.curtain.acn003" }, { "entity_id": "button.curtain_br1_identify", "name": "LUMI lumi.curtain.acn003" }, { "entity_id": "sensor.curtain_br1_illuminance", "name": "LUMI lumi.curtain.acn003" } ], "neighbors": [], "routes": [], "endpoint_names": [ { "name": "WINDOW_COVERING_DEVICE" } ], "user_given_name": "Curtain_BR1", "device_reg_id": "781f5ff1522c5b23cde79278e9d58f09", "area_id": "bedroom", "cluster_details": { "1": { "device_type": { "name": "WINDOW_COVERING_DEVICE", "id": 514 }, "profile_id": 260, "in_clusters": { "0x0000": { "endpoint_attribute": "basic", "attributes": {}, "unsupported_attributes": {} }, "0x0001": { "endpoint_attribute": "power", "attributes": { "0x0033": { "attribute_name": "battery_quantity", "value": 1 }, "0x0031": { "attribute_name": "battery_size", "value": 10 }, "0x0020": { "attribute_name": "battery_voltage", "value": 30.0 } }, "unsupported_attributes": { "0x0020": { "attribute_name": "battery_voltage" }, "0x0021": { "attribute_name": "battery_percentage_remaining" } } }, "0x0003": { "endpoint_attribute": "identify", "attributes": {}, "unsupported_attributes": {} }, "0x000a": { "endpoint_attribute": "time", "attributes": {}, "unsupported_attributes": {} }, "0x0102": { "endpoint_attribute": "window_covering", "attributes": { "0x0007": { "attribute_name": "config_status", "value": 11 }, "0x0008": { "attribute_name": "current_position_lift_percentage", "value": 100 } }, "unsupported_attributes": { "0x0009": { "attribute_name": "current_position_tilt_percentage" } } }, "0x0400": { "endpoint_attribute": "illuminance", "attributes": { "0x0000": { "attribute_name": "measured_value", "value": 20001.0 } }, "unsupported_attributes": {} }, "0xfcc0": { "endpoint_attribute": "opple_cluster", "attributes": { "0x0401": { "attribute_name": "hand_open", "value": 0 }, "0x0429": { "attribute_name": "light_level", "value": 2 }, "0x0402": { "attribute_name": "positions_stored", "value": 1 }, "0x0407": { "attribute_name": "store_position", "value": 0 } }, "unsupported_attributes": {} } }, "out_clusters": { "0x0003": { "endpoint_attribute": "identify", "attributes": {}, "unsupported_attributes": {} }, "0x000a": { "endpoint_attribute": "time", "attributes": {}, "unsupported_attributes": {} }, "0x0019": { "endpoint_attribute": "ota", "attributes": {}, "unsupported_attributes": {} } } } } } } ```

Logs

Logs ```python [Paste the logs here] ```

Custom quirk

Custom quirk Custom quirk on the device zigbee website (https://zigbee.blakadder.com/Aqara_ZNCLBL01LM.html) links to a quirk for the agl001 which is here https://github.com/zigpy/zha-device-handlers/issues/2003. The discussion is closed and the final comment links to #2629 to continue the discussion

Additional information

I did find a github post at one point specific to the acn003 where someone suggested changing the open / close from 'motor' to 'position', though I'm not sure how to implement that myself.

BackedUpBooty commented 4 months ago

Hi @TheJulianJES wondering if there's any likely movement on this at all? I noticed not long ago that the battery information and light sensor info had begun to populate on the device page, but no direction inversion.

dmulcahey commented 4 months ago

Hi @TheJulianJES wondering if there's any likely movement on this at all? I noticed not long ago that the battery information and light sensor info had begun to populate on the device page, but no direction inversion.

Try the beta

BackedUpBooty commented 4 months ago

Try the beta

Would you mind linking which beta you mean? I've looked through the repo quickly but not sure what you're referring to.