Aqara E1 Curtain Driver Battery Sensor in ZHA

Has anyone been able to get the battery sensor to show up in ZHA? Youtuber Everythingsmarthome said he had a “workaround” for this in his review of the product, but didn’t give any details. I would really like to be able to see the battery status so that I can charge before it runs out.

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 ?