itavero / homebridge-z2m

Expose your Zigbee devices to HomeKit with ease, by integrating 🐝 Zigbee2MQTT with 🏠 Homebridge.
https://z2m.dev
Apache License 2.0
297 stars 47 forks source link

[Bug] Humidity sensor on thermostat exposed as separate service #869

Open burmistrzak opened 1 month ago

burmistrzak commented 1 month ago

Is there an existing issue for this?

Describe the bug

When a thermostat also exposes a humidity sensor on the same endpoint, the humidity sensor currently gets configured as a secondary service, and not as the optional CurrentRelativeHumidity characteristic for said thermostat service.

It's (for some reason?) not possible to ungroup these two services, meaning the accessory tile in Home will only show a sensor icon and not the current state of the thermostat.

A possible solution might be to simply skip service creation for humidity sensors in case climate is also exposed on the same endpoint. Adding the optional characteristic should also be rather trivial, because we probably can reuse proven code from #854. 😉

Related devices

No response

Related Devices

Steps To Reproduce

No response

Expected behavior

A thermostat service with the optional CurrentRelativeHumidity characteristic gets exposed to HomeKit, and no additional humidity service is created.

Device entry

[…]
"exposes": [
        {
          "features": [
            {
              "access": 5,
              "description": "Current temperature measured on the device",
              "label": "Local temperature",
              "name": "local_temperature",
              "property": "local_temperature",
              "type": "numeric",
              "unit": "°C"
            },
            {
              "access": 7,
              "description": "Temperature setpoint",
              "label": "Occupied heating setpoint",
              "name": "occupied_heating_setpoint",
              "property": "occupied_heating_setpoint",
              "type": "numeric",
              "unit": "°C",
              "value_max": 30,
              "value_min": 4.5,
              "value_step": 0.5
            },
            {
              "access": 7,
              "description": "Temperature setpoint",
              "label": "Occupied cooling setpoint",
              "name": "occupied_cooling_setpoint",
              "property": "occupied_cooling_setpoint",
              "type": "numeric",
              "unit": "°C",
              "value_max": 30,
              "value_min": 4.5,
              "value_step": 0.5
            },
            {
              "access": 7,
              "description": "Offset to add/subtract to the local temperature",
              "label": "Local temperature calibration",
              "name": "local_temperature_calibration",
              "property": "local_temperature_calibration",
              "type": "numeric",
              "unit": "°C",
              "value_max": 5,
              "value_min": -5,
              "value_step": 0.1
            },
            {
              "access": 7,
              "description": "Mode of this device",
              "label": "System mode",
              "name": "system_mode",
              "property": "system_mode",
              "type": "enum",
              "values": [
                "off",
                "heat",
                "cool"
              ]
            },
            {
              "access": 5,
              "description": "The current running state",
              "label": "Running state",
              "name": "running_state",
              "property": "running_state",
              "type": "enum",
              "values": [
                "idle",
                "heat",
                "cool"
              ]
            }
          ],
          "type": "climate"
        },
        {
          "access": 5,
          "description": "Measured relative humidity",
          "label": "Humidity",
          "name": "humidity",
          "property": "humidity",
          "type": "numeric",
          "unit": "%"
        },
        {
          "access": 7,
          "description": "Bosch-specific operating mode (overrides system mode)",
          "label": "Operating mode",
          "name": "operating_mode",
          "property": "operating_mode",
          "type": "enum",
          "values": [
            "schedule",
            "manual",
            "pause"
          ]
        },
        {
          "access": 7,
          "description": "Enable/disable window open (Lo.) mode",
          "label": "Window detection",
          "name": "window_detection",
          "property": "window_detection",
          "type": "binary",
          "value_off": "OFF",
          "value_on": "ON"
        },
        {
          "access": 7,
          "description": "Activate boost heating (5 min. on TRV)",
          "label": "Boost heating",
          "name": "boost_heating",
          "property": "boost_heating",
          "type": "binary",
          "value_off": "OFF",
          "value_on": "ON"
        },
        {
          "access": 7,
          "description": "Enables/disables physical input on the device",
          "label": "Child lock",
          "name": "child_lock",
          "property": "child_lock",
          "type": "binary",
          "value_off": "UNLOCK",
          "value_on": "LOCK"
        },
        {
          "access": 7,
          "description": "Sets the display on-time",
          "label": "Display ontime",
          "name": "display_ontime",
          "property": "display_ontime",
          "type": "numeric",
          "unit": "s",
          "value_max": 30,
          "value_min": 5
        },
        {
          "access": 7,
          "description": "Sets brightness of the display",
          "label": "Display brightness",
          "name": "display_brightness",
          "property": "display_brightness",
          "type": "numeric",
          "value_max": 10,
          "value_min": 0
        },
        {
          "access": 1,
          "category": "diagnostic",
          "description": "Link quality (signal strength)",
          "label": "Linkquality",
          "name": "linkquality",
          "property": "linkquality",
          "type": "numeric",
          "unit": "lqi",
          "value_max": 255,
          "value_min": 0
        }
      ]
[…]

Status update

No response

Messages from this plugin

No response

This plugin

1.11.0-beta.5

Homebridge

1.7.0

Zigbee2MQTT

1.37.1-dev

Homebridge Config UI X (if applicable)

No response

itavero commented 3 weeks ago

Main tricky part is that two separate converters need to be aware of each others behavior, so they (unfortunately) need to be coupled somehow. I'll think about what the possibilities are..

Functionally though, you still have all the data available in HomeKit, right? So you can still make whatever automations you'd want for this?

burmistrzak commented 3 weeks ago

Main tricky part is that two separate converters need to be aware of each others behavior, so they (unfortunately) need to be coupled somehow. I'll think about what the possibilities are..

Why would they need to be coupled? Wouldn't we just skip the basic humidity sensor if we detect a climate expose, or am I missing something? 🤔

Functionally though, you still have all the data available in HomeKit, right? So you can still make whatever automations you'd want for this?

Technically yes, but the UI is kinda messed up. The thermostat doesn't show up correctly because the humidity sensor seems to be treated as the main accessory service (it's the tile on the right).

image

It's probably because the basic sensors are created first? If I exclude the sensor by default, and later on explicitly include it, it's showing up more or less as expected.