Aqara E1 Curtain Driver Battery Sensor in ZHA

Zigbee devices that do not use standard configuration and parameters (standard ZCL clusters and attributes) will need a custom handler/converter/translator as Python script code in “ZHA Device Handlers” repository to extend custom support for specific non-standard devices (which the ZHA integration then makes use of).

If you can not code that Python script code yourself to write the needed custom handler/converter/translator for adding that specific device to the “ZHA Device Handlers” repository/library then suggest submitting a “device support request” as new issues → https://github.com/zigpy/zha-device-handlers/issues

Without a “device support request” as a new issue posted to the “ZHA Device Handlers” repository/library requesting support for an unsupported device or device feature with Device signature and Diagnostic information the ZHA integration developers will not even know about the device unless they by random chance happened to have bought it themselves.

The reason is why non-standard devices need a custom handler/converter/translator is explained in ZHA integration documentation here → https://www.home-assistant.io/integrations/zha#zha-exception-and-deviation-handling

Zigbee devices that use clusters and attributes that are standard in the official ZCL (Zigbee Cluster Library) do not need custom handlers/converters/translators as explained in the ZHA integration documentation here → https://www.home-assistant.io/integrations/zha#knowing-which-devices-are-supported

PS: Off-topic but FYI, this also works kind of similar for Zigbee2MQTT which also requires a custom handler/converter/translator for specific devices → https://www.zigbee2mqtt.io/advanced/support-new-devices/01_support_new_devices.html

Thank you! I’m not familiar with Python programming so I’ve submitted a new Github issue as you’ve suggested. Much appreciated!

Yes I had it working on home assistant with a conbee 2 stick.
5 Aquara E1 shades all showed the battery state and room temperature.

Yesterday I migrated my zigbee network from the conbee to an Sonoff stick and now I don’t get values from the battery sensor else then “unknown”.

Did you run ZHA on the Conbee as well, or deconz?

First Deconz but I didn’t like it.
Migrated to ZHA and I’m using it for a couple off months now without issues.
I put the Sonoff stick back in the box :stuck_out_tongue:

Thanks :slight_smile: so, just to be sure, you had these Aqara blind rollers working with ZHA (using a conbee stick)? :slight_smile:

Correct.

basically as far as I can understand,with ZHA and a custom quirk you can have battery status.
Is something I really want to fix.

Can someone please share some instructions (steps) where to find the quirk, how to download it and how to install at HA ???

What is a quirk?

What device are you using as Zigbee antenna?

hello,
please read bellow what is the quirk and why we need them to fix the battery status

However I can’t find clean instructions how to add the custom quirk which can be found here

I wish that someone will enlight me after this post :slight_smile:

nobody? It’s a shame as I thought this community is huge and everyone is willing to help.
Atleast that’s what I was doing so far. When had the time and knowledge about something was always willing to help

Copy this, put it into a file in zha_quirks folder. name the file aqara_e1.py . Make sure you have enabled quirks and custom quirks path. Restart Home Assistant.

"""Aqara Curtain Driver E1 device."""
from __future__ import annotations

import logging
from typing import Any

from zigpy import types as t
from zigpy.profiles import zha
from zigpy.zcl.clusters.closures import WindowCovering
from zigpy.zcl.clusters.general import Basic, Identify, Ota, PowerConfiguration, Time
from zigpy.zcl.clusters.manufacturer_specific import ManufacturerSpecificCluster
from zigpy.zdo.types import NodeDescriptor

from zhaquirks import Bus, CustomCluster, LocalDataCluster
from zhaquirks.const import (
    DEVICE_TYPE,
    ENDPOINTS,
    INPUT_CLUSTERS,
    MODELS_INFO,
    NODE_DESCRIPTOR,
    OUTPUT_CLUSTERS,
    PROFILE_ID,
)
from zhaquirks.xiaomi import LUMI, XiaomiCluster, XiaomiCustomDevice

_LOGGER = logging.getLogger(__name__)


class XiaomiAqaraCurtainE1(XiaomiCluster, ManufacturerSpecificCluster):
    """Xiaomi mfg cluster implementation specific for E1 Curtain."""

    cluster_id = 0xFCC0

    attributes = XiaomiCluster.attributes.copy()
    attributes.update(
        {
            0x0400: ("reverse_direction", t.Bool, True),
            0x0402: ("positions_stored", t.Bool, True),
            0x0407: ("store_position", t.uint8_t, True),
            0x0408: ("speed", t.uint8_t, True),
            0x0409: ("charging", t.uint8_t, True),
            0x00F7: ("aqara_attributes", t.LVBytes, True),
        }
    )


class WindowCoveringE1(CustomCluster, WindowCovering):
    """Xiaomi Window Covering configuration cluster."""

    def _update_attribute(self, attrid, value):
        if attrid == 8:
            if self.__getitem__(0x0017) == 1:
                value = 100 - value
        _LOGGER.info("WindowCovering - Attribute: %d Value: %d", attrid, value)
        super()._update_attribute(attrid, value)


class PowerConfigurationCurtainE1(PowerConfiguration, LocalDataCluster):
    """Xiaomi power configuration cluster implementation."""

    BATTERY_PERCENTAGE_REMAINING = 0x0021

    def __init__(self, *args: Any, **kwargs: Any) -> None:
        """Init."""
        super().__init__(*args, **kwargs)
        self.endpoint.device.power_bus_percentage.add_listener(self)

    def update_battery_percentage(self, value: int) -> None:
        """Doubles the battery percentage to the Zigbee spec's expected 200% maximum."""
        super()._update_attribute(
            self.BATTERY_PERCENTAGE_REMAINING,
            (value * 2),
        )


class E1Curtain(XiaomiCustomDevice):
    """Aqara Curtain Driver E1 device."""

    def __init__(self, *args: Any, **kwargs: Any) -> None:
        """Init."""
        self.power_bus_percentage: Bus = Bus()  # type: ignore
        super().__init__(*args, **kwargs)  # type: ignore

    signature = {
        MODELS_INFO: [(LUMI, "lumi.curtain.agl001")],
        ENDPOINTS: {
            # <SizePrefixedSimpleDescriptor endpoint=1 profile=260 device_type=256
            # device_version=1
            # input_clusters=[0, 2, 3, 4, 5, 6, 9, 64704, 13, 19, 258]
            # output_clusters=[10, 25]>
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: 0x0107,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfiguration.cluster_id,
                    Identify.cluster_id,
                    Time.cluster_id,
                    WindowCovering.cluster_id,
                    XiaomiAqaraCurtainE1.cluster_id,
                ],
                OUTPUT_CLUSTERS: [
                    Identify.cluster_id,
                    Time.cluster_id,
                    Ota.cluster_id,
                    XiaomiAqaraCurtainE1.cluster_id,
                ],
            }
        },
    }
    replacement = {
        NODE_DESCRIPTOR: NodeDescriptor(
            0x02, 0x40, 0x80, 0x115F, 0x7F, 0x0064, 0x2C00, 0x0064, 0x00
        ),
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfigurationCurtainE1,
                    Identify.cluster_id,
                    Time.cluster_id,
                    WindowCoveringE1,
                    XiaomiAqaraCurtainE1,
                ],
                OUTPUT_CLUSTERS: [
                    Identify.cluster_id,
                    Time.cluster_id,
                    Ota.cluster_id,
                    XiaomiAqaraCurtainE1,
                ],
            }
        },
    }

thank you for the time to answer this.
I’ve copied file and place it under folder /config/custom_zha_quirks.

I’ve enabled quirks and path under configuration.yaml

zha:
  custom_quirks_path: /config/custom_zha_quirks/
  database_path: /config/zigbee.db 
  enable_quirks: true

I removed device.
Then i restarted HA and try to pair device again.

Unfortunately I still get battery status as unknown!!

I must admit it! It drives me mad and I don’t know what to do.
Any help will be much appreciated

why the hell have you managed to have battery status ??
Can you please share firmware version of E1 driver and deconz stick please?

Hi,

Newest firmware from the conbee website (Think that is a few years old now)
Newest firmware of the Rollershades E1. >> Made no difference to me >> Before updating the software of the sahdes, it was also working fine.

Thanks for your reply!
How do I update the firmware of Conbee stick ??
Tried once and I lost all ZHA devices.

How to check firmware version of Shades and Conbee stick ?

So if I have my zigbee device with a standard power configuration cluster, but the battery sensor is not showing on the device in ZHA, this means that my power configuration cluser is not that much ‘stadard’ per se? Where would you suggest to look first for the reason why the battery sensor’s not showing? Thanks!

See https://www.home-assistant.io/integrations/zha#how-to-add-support-for-new-and-unsupported-devices

And Zigbee Guide: How-to add/setup local custom ZHA Device Handlers (also known as ”quirks”) in the ZHA integration

For details post new issues or discussions to GitHub - 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.

Thanks, but I thought that a standard power config cluster would be supprted out of the box without having to have any quirks created. The standard power config cluster is there, and the power source is indicated as battery int he standard basic cluster, yet HA/ZHA still does not recognize the device as being powered by the battery…

If one or more expected entiry is not seen under the device in the ZHA integration then there is probably either a fault in the device firmware or with ZHA, regardless of which of those is the root cause it will not help to simply post here, you still need to report it as an issue on GitHub to that linked ZHA Device Handlers repo (if there is not one already and if there is then provide input there):

You post a bug as an issue there is there is already a zha-quirk for the device and if there is not then you post a device support request as and issue:

I am pretty sure that the ZHA developers to not read this forum or at least not all post, so you really need to post as issues to GitHub.

1 Like