Zigbee not updating value in UI

(This is cross-posted from Not updating value in UI which I posted in the Zigbee section 6 days ago but has not received a response. Perhaps it is more a ‘front end’ related than Zigbee question.)
I have a Zigbee end device that is connected via the ZHA integration to HA. (The details are in the other post linked above).
In the ‘home-assistant.log’ I can see the ‘temperature measurement’ coming in every few seconds but I can’t see any update of the value in the UI.
I’ve even tried to create a card on the default dashboard but it always shows the original value when the end device first connects.
Any advice on how to get the updates to be shown?
Susan

Not sure what you mean by “UI”, here.
What do you see in the development tools?

and in the settings

Yes I can:




And, as you will see the value is always 21.0C.
However the end device is sending a new value every 2 seconds (as this is a test it is a counter that increments between the min and max values defined in the ‘temperature’ cluster. I.e. -2000 to 10000 counting by 1 every 2 seconds)
That new value is not being updated in the UI/display/screen/card/whatever.
The log in the other thread shows that the ZHA integration is receiving the updates and triggering at least 1 SQL command so something is getting through. Also the information in the debug log is what I would expect to see from the end device.
Susan

I guess this is key:

Decoded ZCL frame: TemperatureMeasurement:Write_Attributes(attributes=[Attribute(attrid=0x0000, value=TypeValue(type=int16s, value=882))])

However, HA only records “last_seen”, not that value.

Did you write a quirk for your device?
Please show it’s zigbee signature

Thanks for replying Chris.
I have written my own quirk which I have deliberately written to effectively do nothing in the first instance. Also I get the same problem (not updating the UI value) if I remove the quirk.
the quirk is:

""" Custom quirk for the ConMac Weather2 zigbee device"""
from zigpy.profiles import zha

from zigpy.quirks import CustomDevice

from zhaquirks.const import (
    DEVICE_TYPE,
    ENDPOINTS,
    INPUT_CLUSTERS,
    OUTPUT_CLUSTERS,
    PROFILE_ID,
)

from zigpy.zcl.clusters.general import (
#    AnalogInput,
#    AnalogOutput,
    Basic,
    OnOff,
)

from zigpy.zcl.clusters.measurement import (
    TemperatureMeasurement,
)

# class AnalogInputCluster( CustomCluster, AnalogInput):
#     cluster_id = AnalogInput.cluster_id
#     def __init__(self,*args, **kwargs):
#         self.current_state = {}
#         super().__init__(*args, **kwargs)
        
#     def _update_attribute( self, attrid, value):
#         super()._update_attribute( attrid, value)
#         if value is not None and value >= 0:
#             self.endpoint.device.power_bus.listener_even(POWER_REPORTED, value)

class ConMacWeather2( CustomDevice):
    
    def __init__(self, *args, **kwargs):
        """Init,"""
        super().__init__(*args, **kwargs)
    
    signature = {
#        MODELS_INFO: [("Weather2", "manuforte.org")],
        ENDPOINTS: {
            # < SimpleDescriptor endpoint=2 profile=0x0104 device_type=0x0002
            # device_version=1
            # input_clusters=[0,6]
            # output_clusters=[]>
            1: {
                PROFILE_ID: 0x0104,
                DEVICE_TYPE: 0x0002,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    OnOff.cluster_id,
                ],
                OUTPUT_CLUSTERS: [],
            },
            # < SimpleDescriptor endpoint=2 profile=0x0104 device_type=0x0007
            # device_version=1
            # input_clusters=[12]
            # output_clusters=[13]>
            2: {
                PROFILE_ID: 0x0104,
                DEVICE_TYPE: 0x0302,
                INPUT_CLUSTERS: [
                    TemperatureMeasurement.cluster_id,
                ],
                OUTPUT_CLUSTERS: [],
            },
        },
    }
    replacement = {
#        SKIP_CONFIGURATION: True,
        ENDPOINTS: {
            1: {
                PROFILE_ID: 0x0104,
                DEVICE_TYPE: 0x0002,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    OnOff.cluster_id,
                ],
                OUTPUT_CLUSTERS: [],
               },
            2: {
                PROFILE_ID: 0x0104,
                DEVICE_TYPE: 0x0302,
                INPUT_CLUSTERS: [
                    TemperatureMeasurement.cluster_id
                ],
                OUTPUT_CLUSTERS: [],
               },
           },
        "manufacturer": "ConMac",
        "model": "Weather2",
    }

The signature is:

{
  "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.EndDevice: 2>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.MainsPowered|RxOnWhenIdle|AllocateAddress: 140>, manufacturer_code=4660, maximum_buffer_size=108, maximum_incoming_transfer_size=0, server_mask=11264, maximum_outgoing_transfer_size=0, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *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=True, *is_router=False, *is_security_capable=False)",
  "endpoints": {
    "1": {
      "profile_id": "0x0104",
      "device_type": "0x0002",
      "input_clusters": [
        "0x0000",
        "0x0006"
      ],
      "output_clusters": []
    },
    "2": {
      "profile_id": "0x0104",
      "device_type": "0x0302",
      "input_clusters": [
        "0x0402"
      ],
      "output_clusters": []
    }
  },
  "manufacturer": "ConMac",
  "model": "Weather2",
  "class": "weather2_quirk.ConMacWeather2"
}

Given. what you have said (or what I interpret from it) that ‘last seen’ value is being updated (I can see the regular updates in the database when the ‘WHERE’ clause is true), I am wondering if that SQL statement is being automatically generated but is missing some vital part, or the part that updates the ‘attributes_cache_v12’ (at least that is the table I can see that holds the always displayed value) row is not generated.
Susan

It’s above my grade, but from https://www.nxp.com/docs/en/user-guide/JN-UG-3115.pdf , chapter 25, it seem the Temperature measurement cluster is more than “send a temp”.

Are you sure of attrid=0x0000 when you send the value?

I’m going by the Zigbee ZCL spec at https://zigbeealliance.org/wp-content/uploads/2021/10/07-5123-08-Zigbee-Cluster-Library.pdf. Section 4.4 on page 4-10 is the specification for the Temperature Measurement cluster. (It would seem that the document you link to is saying the same thing but in a way for the NXP provided stack.)

I’m also using ESP Zigbee SDK Programming Guide - ESP32-H2 - — ESP Zigbee SDK latest documentation as the docuemntation for the ESP32-H2 end device.

As you say, the temperature measurement cluster has 3 mandatory and one optional attribute. When I define the cluster, all 3 mandatory attributes are defined within the SDK.
When I look at the attributes as seen by ZHA I can see:


so all of the mandatory attributes are being seen. Also you can see that the ‘measured_value’ is correctly attribute 0x0000.

Susan

Yep. I cannot see something wrong with my (more limited than yours) zigbee knowledge.

From a pure debugging perspective, it would make sense to find out where this “21” value comes from. Maybe try to update the value by using HA API, and check whether “something” else is updating it…

The “21” is coming from the ‘measured_value’ attribute when the cluster is defined in the end device. Just as a test I changed this to ‘18.5’ and sure enough that is now the value shown in the HA UI.
I’ve also asked this question in the ‘zha-device-handlers’ github section (End device temperature value not being updated in ZHA · Issue #2881 · zigpy/zha-device-handlers · GitHub)
Susan

So it’s the initial value after a device “reboot”?

So it “works” for the first update after a device reboot, do I get that right?
Intriguing…

Yes and no. It is more than a ‘reboot’ of the end device as it occurs when the end device is first ‘added’ to ZHA (or after it has been ‘removed’ and ‘added’ again etc.).
The end device can reboot and reconnect with the coordinator as often as it likes but if the coordinator still has the end device in its cache then it will use the cached information.

I’ve also just discovered something “interesting”. I used SQLite3 to change the ‘value’ for the end point in the ‘attribute_cache_v12’ table in zigbee.db. After a few minutes (no exact timing determined) the cached value returns the original number. I take it that it must be stored somewhere else as well. Lots more to try to understand how ZHA works.
Susan