Skip to content

Question: CustomCluster (AnalogInput) -> HomeAssistant Entity - HowTo? #3720

Open
@ummarbhutta

Description

@ummarbhutta

Dear All,

I am working on creating a zigbee weight sensor for one of my DIY project. Quick background/summary:

Environment

  • HomeAssistant Docker based installation Core v 2024.9.1, Frontend v 20240906.0

Hardware/FW

  • I am using ESP32-H2 as a hardware platform.
  • FW is developed using ESP-IDF
  • Device is set as End device
  • I am publishing weight values on an AnalogInput cluster
  • Also included basic and identify(in/out) cluster

Out of Box - HomeAssistant behavior

  • When I pair the device to HomeAssistant, the device is discovered successfully
  • No entity is created other than identify, LQI, RSSI
  • Sensor is transmitting correct values, verified it from Manage Zigbee device menu and reading the present_value (0x0055) attribute of AnalogInput (0x000c) cluster
  • This is an expected behavior, because I need a custom quirk for HomeAssistant to identify the device.

Quirk development

  • I started working on custom quirk development, developed a version and installed it on HomeAssistant, it is loaded and applied to custom device successfully - verified from DeviceInfo panel of Home Assistant
  • I also see the cluster I have defined in replacement dictionary of quirk in Manage Zigbee device menu, with the correct values in present_value attribute.

Issue

  • The issue I am facing is that No entity is created in Home Assistant for my weight sensor
  • I am definitely missing something in quirk, couldn't figure out anything from documentation. Any help is appreciated.

Code of Quirk

import logging
from zigpy.profiles import zha
from zigpy.quirks import CustomDevice
from zigpy.zcl.clusters.general import AnalogInput, Basic, Identify
from zigpy.zcl import foundation
from zhaquirks import CustomCluster
from zhaquirks.const import (
    DEVICE_TYPE,
    ENDPOINTS,
    INPUT_CLUSTERS,
    OUTPUT_CLUSTERS,
    PROFILE_ID,
)

_LOGGER = logging.getLogger(__name__)

class WeightMeasurementInputCluster(CustomCluster, AnalogInput):
    """Custom Analog Input cluster for weight measurement."""
    
    PRESENT_VALUE_ATTRIBUTE = 0x0055
    CLUSTER_SPECIFIC_COMMANDS = {}
    
    async def bind(self):
        """Bind cluster."""
        _LOGGER.debug("WeightSensor: Binding cluster")
        result = await super().bind()
        _LOGGER.debug("WeightSensor: Configuring reporting")
        try:
            await self.configure_reporting(
                self.PRESENT_VALUE_ATTRIBUTE,
                0,    # minimum reporting interval
                3600, # maximum reporting interval
                0.01, # reportable change
            )
            _LOGGER.debug("WeightSensor: Reporting configured successfully")
        except Exception as e:
            _LOGGER.error("WeightSensor: Error configuring reporting: %s", e)
        return result

    def _update_attribute(self, attrid, value):
        _LOGGER.debug("WeightSensor: Updating attribute %s with value %s", attrid, value)
        super()._update_attribute(attrid, value)
        
    @property
    def extra_info(self):
        """Return unit of measurement and icon."""
        return {
            'unit_of_measurement': 'kg',
            'icon': 'mdi:weight-gram',
            'state_class': 'measurement'
        }

class WeightSensor(CustomDevice):
    """Custom device representing a weight sensor."""

    signature = {
        "models_info": [
            ("HQ", "HQWS200kg")
        ],
        "endpoints": {
            20: {
                "profile_id": zha.PROFILE_ID,
                "device_type": zha.DeviceType.SIMPLE_SENSOR,
                "input_clusters": [
                    Basic.cluster_id,
                    AnalogInput.cluster_id,
                    Identify.cluster_id
                ],
                "output_clusters": [
                    Identify.cluster_id
                ],
            },
        },
    }

    replacement = {
        ENDPOINTS: {
            20: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.SIMPLE_SENSOR,
                INPUT_CLUSTERS: [
                    Basic,
                    WeightMeasurementInputCluster,
                    Identify
                ],
                OUTPUT_CLUSTERS: [
                    Identify
                ],
            }
        }
    }

Signature of device

{
  "node_descriptor": {
    "logical_type": 2,
    "complex_descriptor_available": 0,
    "user_descriptor_available": 0,
    "reserved": 0,
    "aps_flags": 0,
    "frequency_band": 8,
    "mac_capability_flags": 140,
    "manufacturer_code": 4660,
    "maximum_buffer_size": 108,
    "maximum_incoming_transfer_size": 1613,
    "server_mask": 11264,
    "maximum_outgoing_transfer_size": 1613,
    "descriptor_capability_field": 0
  },
  "endpoints": {
    "20": {
      "profile_id": "0x0104",
      "device_type": "0x000c",
      "input_clusters": [
        "0x0000",
        "0x0003",
        "0x000c"
      ],
      "output_clusters": [
        "0x0003"
      ]
    }
  },
  "manufacturer": "HQ",
  "model": "HQWS200kg",
  "class": "hq_weight_sensor.WeightSensor"
}

Different UI(s) on home assistant:

Image

Image

Any help is appreciated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    discussionMore of a discussion than an issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions