zha-device-handlers icon indicating copy to clipboard operation
zha-device-handlers copied to clipboard

[Device Support Request] Please add so far unsupported attributes to Sonoff TRVZB

Open Cangoo opened this issue 2 years ago • 79 comments

Problem description

The new Sonoff TRVZB (https://zigbee.blakadder.com/Sonoff_TRVZB.html) is working in general but missing some attributes that can be exposed and changed. For instance local_temperature_calibration can be adjusted sending a Zigbee SET command, but is not showing up in the list of available attributes.

Solution description

Like in zigbee2mqtt, it would be great if the missing attributes like local_temperature_calibration could be added to ZHA as well. See https://github.com/Koenkk/zigbee2mqtt/issues/19269 for details.

Screenshots/Video

Screenshots/Video

[Paste/upload your media here]

Device signature

Device signature
{
  "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.AllocateAddress: 128>, manufacturer_code=4742, maximum_buffer_size=82, maximum_incoming_transfer_size=255, server_mask=11264, maximum_outgoing_transfer_size=255, 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=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)",
  "endpoints": {
    "1": {
      "profile_id": "0x0104",
      "device_type": "0x0301",
      "input_clusters": [
        "0x0000",
        "0x0001",
        "0x0003",
        "0x0006",
        "0x0020",
        "0x0201",
        "0xfc11",
        "0xfc57"
      ],
      "output_clusters": [
        "0x000a",
        "0x0019"
      ]
    }
  },
  "manufacturer": "SONOFF",
  "model": "TRVZB",
  "class": "zigpy.device.Device"
}

Diagnostic information

Diagnostic information
{
  "home_assistant": {
    "installation_type": "Home Assistant Container",
    "version": "2023.11.3",
    "dev": false,
    "hassio": false,
    "virtualenv": false,
    "python_version": "3.11.6",
    "docker": true,
    "arch": "aarch64",
    "timezone": "Europe/Berlin",
    "os_name": "Linux",
    "os_version": "6.1.21-v8+",
    "run_as_root": true
  },
  "custom_components": {},
  "integration_manifest": {
    "domain": "zha",
    "name": "Zigbee Home Automation",
    "after_dependencies": [
      "onboarding",
      "usb"
    ],
    "codeowners": [
      "@dmulcahey",
      "@adminiuga",
      "@puddly"
    ],
    "config_flow": true,
    "dependencies": [
      "file_upload"
    ],
    "documentation": "https://www.home-assistant.io/integrations/zha",
    "iot_class": "local_polling",
    "loggers": [
      "aiosqlite",
      "bellows",
      "crccheck",
      "pure_pcapy3",
      "zhaquirks",
      "zigpy",
      "zigpy_deconz",
      "zigpy_xbee",
      "zigpy_zigate",
      "zigpy_znp",
      "universal_silabs_flasher"
    ],
    "requirements": [
      "bellows==0.36.8",
      "pyserial==3.5",
      "pyserial-asyncio==0.6",
      "zha-quirks==0.0.106",
      "zigpy-deconz==0.21.1",
      "zigpy==0.59.0",
      "zigpy-xbee==0.19.0",
      "zigpy-zigate==0.11.0",
      "zigpy-znp==0.11.6",
      "universal-silabs-flasher==0.0.14",
      "pyserial-asyncio-fast==0.11"
    ],
    "usb": [
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*2652*",
        "known_devices": [
          "slae.sh cc2652rb stick"
        ]
      },
      {
        "vid": "1A86",
        "pid": "55D4",
        "description": "*sonoff*plus*",
        "known_devices": [
          "sonoff zigbee dongle plus v2"
        ]
      },
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*sonoff*plus*",
        "known_devices": [
          "sonoff zigbee dongle plus"
        ]
      },
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*tubeszb*",
        "known_devices": [
          "TubesZB Coordinator"
        ]
      },
      {
        "vid": "1A86",
        "pid": "7523",
        "description": "*tubeszb*",
        "known_devices": [
          "TubesZB Coordinator"
        ]
      },
      {
        "vid": "1A86",
        "pid": "7523",
        "description": "*zigstar*",
        "known_devices": [
          "ZigStar Coordinators"
        ]
      },
      {
        "vid": "1CF1",
        "pid": "0030",
        "description": "*conbee*",
        "known_devices": [
          "Conbee II"
        ]
      },
      {
        "vid": "10C4",
        "pid": "8A2A",
        "description": "*zigbee*",
        "known_devices": [
          "Nortek HUSBZB-1"
        ]
      },
      {
        "vid": "0403",
        "pid": "6015",
        "description": "*zigate*",
        "known_devices": [
          "ZiGate+"
        ]
      },
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*zigate*",
        "known_devices": [
          "ZiGate"
        ]
      },
      {
        "vid": "10C4",
        "pid": "8B34",
        "description": "*bv 2010/10*",
        "known_devices": [
          "Bitron Video AV2010/10"
        ]
      }
    ],
    "zeroconf": [
      {
        "type": "_esphomelib._tcp.local.",
        "name": "tube*"
      },
      {
        "type": "_zigate-zigbee-gateway._tcp.local.",
        "name": "*zigate*"
      },
      {
        "type": "_zigstar_gw._tcp.local.",
        "name": "*zigstar*"
      },
      {
        "type": "_uzg-01._tcp.local.",
        "name": "uzg-01*"
      },
      {
        "type": "_slzb-06._tcp.local.",
        "name": "slzb-06*"
      }
    ],
    "is_built_in": true
  },
  "data": {
    "ieee": "**REDACTED**",
    "nwk": 519,
    "manufacturer": "SONOFF",
    "model": "TRVZB",
    "name": "SONOFF TRVZB",
    "quirk_applied": false,
    "quirk_class": "zigpy.device.Device",
    "quirk_id": null,
    "manufacturer_code": 4742,
    "power_source": "Battery or Unknown",
    "lqi": null,
    "rssi": null,
    "last_seen": "2023-11-26T09:20:02",
    "available": true,
    "device_type": "EndDevice",
    "signature": {
      "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.AllocateAddress: 128>, manufacturer_code=4742, maximum_buffer_size=82, maximum_incoming_transfer_size=255, server_mask=11264, maximum_outgoing_transfer_size=255, 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=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)",
      "endpoints": {
        "1": {
          "profile_id": "0x0104",
          "device_type": "0x0301",
          "input_clusters": [
            "0x0000",
            "0x0001",
            "0x0003",
            "0x0006",
            "0x0020",
            "0x0201",
            "0xfc11",
            "0xfc57"
          ],
          "output_clusters": [
            "0x000a",
            "0x0019"
          ]
        }
      },
      "manufacturer": "SONOFF",
      "model": "TRVZB"
    },
    "active_coordinator": false,
    "entities": [
      {
        "entity_id": "sensor.trv_battery",
        "name": "SONOFF TRVZB"
      },
      {
        "entity_id": "sensor.trv_hvac_action",
        "name": "SONOFF TRVZB"
      },
      {
        "entity_id": "climate.trv",
        "name": "SONOFF TRVZB"
      },
      {
        "entity_id": "button.trv_identify",
        "name": "SONOFF TRVZB"
      },
      {
        "entity_id": "switch.trv_switch",
        "name": "SONOFF TRVZB"
      }
    ],
    "neighbors": [],
    "routes": [],
    "endpoint_names": [
      {
        "name": "THERMOSTAT"
      }
    ],
    "user_given_name": "Thermostat",
    "device_reg_id": "9cf40a1e2e31ed20cf480c7240fa16eb",
    "area_id": "bad_oben",
    "cluster_details": {
      "1": {
        "device_type": {
          "name": "THERMOSTAT",
          "id": 769
        },
        "profile_id": 260,
        "in_clusters": {
          "0x0000": {
            "endpoint_attribute": "basic",
            "attributes": {
              "0x0004": {
                "attribute_name": "manufacturer",
                "value": "SONOFF"
              },
              "0x0005": {
                "attribute_name": "model",
                "value": "TRVZB"
              }
            },
            "unsupported_attributes": {}
          },
          "0x0001": {
            "endpoint_attribute": "power",
            "attributes": {
              "0x0021": {
                "attribute_name": "battery_percentage_remaining",
                "value": 142
              }
            },
            "unsupported_attributes": {
              "0x0020": {
                "attribute_name": "battery_voltage"
              },
              "0x0031": {
                "attribute_name": "battery_size"
              },
              "0x0033": {
                "attribute_name": "battery_quantity"
              }
            }
          },
          "0x0003": {
            "endpoint_attribute": "identify",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x0006": {
            "endpoint_attribute": "on_off",
            "attributes": {
              "0x0000": {
                "attribute_name": "on_off",
                "value": 1
              }
            },
            "unsupported_attributes": {
              "0x4003": {
                "attribute_name": "start_up_on_off"
              }
            }
          },
          "0x0020": {
            "endpoint_attribute": "poll_control",
            "attributes": {
              "0x0000": {
                "attribute_name": "checkin_interval",
                "value": 13200
              }
            },
            "unsupported_attributes": {}
          },
          "0x0201": {
            "endpoint_attribute": "thermostat",
            "attributes": {
              "0x0004": {
                "attribute_name": "abs_max_heat_setpoint_limit",
                "value": 3500
              },
              "0x0003": {
                "attribute_name": "abs_min_heat_setpoint_limit",
                "value": 400
              },
              "0x001b": {
                "attribute_name": "ctrl_sequence_of_oper",
                "value": 2
              },
              "0x0000": {
                "attribute_name": "local_temperature",
                "value": 2420
              },
              "0x0010": {
                "attribute_name": "local_temperature_calibration",
                "value": 0
              },
              "0x0016": {
                "attribute_name": "max_heat_setpoint_limit",
                "value": 3500
              },
              "0x0015": {
                "attribute_name": "min_heat_setpoint_limit",
                "value": 400
              },
              "0x0002": {
                "attribute_name": "occupancy",
                "value": 1
              },
              "0x0012": {
                "attribute_name": "occupied_heating_setpoint",
                "value": 2500
              },
              "0x001e": {
                "attribute_name": "running_mode",
                "value": 0
              },
              "0x0029": {
                "attribute_name": "running_state",
                "value": 1
              },
              "0x001c": {
                "attribute_name": "system_mode",
                "value": 4
              }
            },
            "unsupported_attributes": {
              "0x0008": {
                "attribute_name": "pi_heating_demand"
              },
              "0x0006": {
                "attribute_name": "abs_max_cool_setpoint_limit"
              },
              "0x0005": {
                "attribute_name": "abs_min_cool_setpoint_limit"
              },
              "0x0013": {
                "attribute_name": "unoccupied_cooling_setpoint"
              },
              "0x0007": {
                "attribute_name": "pi_cooling_demand"
              },
              "0x0011": {
                "attribute_name": "occupied_cooling_setpoint"
              },
              "0x0014": {
                "attribute_name": "unoccupied_heating_setpoint"
              },
              "0x0017": {
                "attribute_name": "min_cool_setpoint_limit"
              },
              "0x0018": {
                "attribute_name": "max_cool_setpoint_limit"
              }
            }
          },
          "0xfc57": {
            "endpoint_attribute": "manufacturer_specific",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0xfc11": {
            "endpoint_attribute": "manufacturer_specific",
            "attributes": {},
            "unsupported_attributes": {}
          }
        },
        "out_clusters": {
          "0x000a": {
            "endpoint_attribute": "time",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x0019": {
            "endpoint_attribute": "ota",
            "attributes": {},
            "unsupported_attributes": {}
          }
        }
      }
    }
  }
}

Logs

Logs
[Paste the logs here]

Custom quirk

Custom quirk
[Paste your custom quirk here]

Additional information

No response

Cangoo avatar Nov 26 '23 08:11 Cangoo

I am seeking ZHA support for extended features since I have four of those. Sonoff is advertising this product as Home Assistant and ZHA compatible but I can use very few of its features, so I support this request.

onurunaldi avatar Nov 30 '23 21:11 onurunaldi

It will be great to get the valve positioning control, and the auto mode control. So I support this request.

dmytrohuskov avatar Nov 30 '23 22:11 dmytrohuskov

I recently purchased seven of these and it's a shame that lots of the available features are not available as yet, so I support this request.

jazst avatar Dec 01 '23 07:12 jazst

I support this request as well. I am having 6 of these already and plan to go further with up to 25 in total if only these features are supported.

MarcinResearchLab avatar Dec 01 '23 11:12 MarcinResearchLab

Second it. Great quality product will be hit soon, full support badly needed.

edgarmaloverian avatar Dec 01 '23 18:12 edgarmaloverian

Can the TRVZB’s current firmware do more than just turn on and off?

MarkHessburg avatar Dec 03 '23 00:12 MarkHessburg

Please try to prioritise this as it's a quite popular TRV

asdkjasdfla avatar Dec 03 '23 10:12 asdkjasdfla

Yep, have a couple of these and would be great to get the extra attributes.

len5771 avatar Dec 03 '23 19:12 len5771

I think that if you set the device to 'Auto' mode by short-pressing the main button, it will gradually adjust the valve. However, in this mode, you cannot then manually adjust the temperature; it is fixed at either 19 or 16 degrees. Interestingly, when set this way, the device maintains the room temperature at around 21-22 degrees.

dmytrohuskov avatar Dec 04 '23 09:12 dmytrohuskov

I think that if you set the device to 'Auto' mode by short-pressing the main button, it will gradually adjust the valve. However, in this mode, you cannot then manually adjust the temperature; it is fixed at either 19 or 16 degrees. Interestingly, when set this way, the device maintains the room temperature at around 21-22 degrees.

dmytrohuskov avatar Dec 04 '23 09:12 dmytrohuskov

I think that if you set the device to 'Auto' mode by short-pressing the main button, it will gradually adjust the valve. However, in this mode, you cannot then manually adjust the temperature; it is fixed at either 19 or 16 degrees. Interestingly, when set this way, the device maintains the room temperature at around 21-22 degrees.

Wow, interesting. Must test that. Shouldn’t the attribute "occupied heating setpoint“ work with that? Set it to auto and set the occupied heating setpoint instead of „temperature“.

MarkHessburg avatar Dec 04 '23 10:12 MarkHessburg

I think that if you set the device to 'Auto' mode by short-pressing the main button, it will gradually adjust the valve. However, in this mode, you cannot then manually adjust the temperature; it is fixed at either 19 or 16 degrees. Interestingly, when set this way, the device maintains the room temperature at around 21-22 degrees.

Wow, interesting. Must test that. Shouldn’t the attribute "occupied heating setpoint“ work with that? Set it to auto and set the occupied heating setpoint instead of „temperature“.

I just tried to change the year from 1900 to 2100 in the YAML file and set the state, but it did not work. On the TRV screen, it still showed '19', and when I hit the refresh button, it reverted to 1900.

dmytrohuskov avatar Dec 04 '23 10:12 dmytrohuskov

I think that if you set the device to 'Auto' mode by short-pressing the main button, it will gradually adjust the valve. However, in this mode, you cannot then manually adjust the temperature; it is fixed at either 19 or 16 degrees. Interestingly, when set this way, the device maintains the room temperature at around 21-22 degrees.

The temperatures and time-tables of the 'auto'-mode seems to be accessible through the official Sonos-App (haven't tried it myself). Would be great if this was settable via ZHA as well. The TRV is falling to manual-mode as soon as ZHA is setting the temperature again.

It seems that the TRV has an offset of 2-3 degrees above the real room-temperature by default when coming from the factory, thats why it would be great to have access to local_temperature_calibration.

I just tried to change the year from 1900 to 2100 in the YAML file

Which YAML file are you referring to?

Cangoo avatar Dec 04 '23 11:12 Cangoo

I just tried to change the year from 1900 to 2100 in the YAML file

Which YAML file are you referring to?

Screenshot 2023-12-04 at 12 02 16 I was referring state in yaml format, not the yaml file itself, just mistyped

dmytrohuskov avatar Dec 04 '23 11:12 dmytrohuskov

I'd also love to see the same support zigbee2mqtt offers for this TRV in ZHA, as I am running 6 of these great thermostats.

Kombustor avatar Dec 08 '23 14:12 Kombustor

Considering that z2m has got it would it not be possible to import the parameters that z2m.uses for this device?

asdkjasdfla avatar Dec 08 '23 14:12 asdkjasdfla

I would also really appreciate full ZHA support for the Sonoff TRVZB. I am currently converting all my old Danfoss Connect to Sonoff.

OldSmurf56 avatar Dec 11 '23 08:12 OldSmurf56

I also got few of these and now struggling with manual / automode. On manual mode there's just off and heat modes and on auto mode (heat/cool) it does not cool down so maybe it's calibration issue. Radiator temperature is something like 27-28 °C and TRV in idle all the time... well at least it's warm 😀

poikjo avatar Dec 12 '23 08:12 poikjo

Support this request as well since I'm using a douzen of them through ZHA Thanks!

lio0909 avatar Dec 14 '23 22:12 lio0909

Support this request as well :-)

MagicBugsBunny avatar Dec 15 '23 14:12 MagicBugsBunny

I support this as well

MoustacheMonkey avatar Dec 17 '23 23:12 MoustacheMonkey

I support this request

velasub avatar Dec 18 '23 12:12 velasub

I support this request

ggdagg avatar Dec 19 '23 22:12 ggdagg

I support this too

defixio avatar Dec 19 '23 23:12 defixio

I have started with a quirk to implement the local temperature calibration. Now I am stuck because I don't know how to set it as a float input value. Maybe someone can help over here? Furthermore, I found out that "local_temperature_calibration" is defined in the zigbee cluster library. Why is it than not supported out of the box?

"""Quirk for SONOFF TRVZB."""
# import typing

from zigpy.profiles import zha 
from zigpy.quirks import CustomDevice
from zigpy.zcl.clusters.general import (
    Basic,
    Identify,
    OnOff,
    Ota,
    PollControl,
    PowerConfiguration,
    Time,
)
from zigpy.zcl.clusters.hvac import (
    Thermostat,
)
from zhaquirks.const import (
    DEVICE_TYPE,
    ENDPOINTS,
    INPUT_CLUSTERS,
    MODELS_INFO,
    OUTPUT_CLUSTERS,
    PROFILE_ID,
)

# Thermostat_Cluster_ID: typing.Final = 0x0201

class Thermostat(CustomCluster):
    "Cluster for Thomostatic values"

    cluster_id = Thermostat.cluster_id
    TempCalibration = 0x0010


    def __init__(self, *args, **kwargs):
        """Init."""
        super().__init__(*args, **kwargs)
        self.endpoint.device.voltage_bus.add_listener(self)
        self.endpoint.device.consumption_bus.add_listener(self)
        self.endpoint.device.power_bus.add_listener(self)

    def power_reported(self, value):
        """Power reported."""
        self._update_attribute(self.TempCalibration, value)



class SonoffTrvzb(CustomDevice):
    """Sonoff TRVZB custom device implementation."""

    signature = {
        MODELS_INFO: [("SONOFF", "TRVZB")],
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.THERMOSTAT,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfiguration.cluster_id,
                    Identify.cluster_id,
                    OnOff.cluster_id,
                    PollControl.cluster_id,
                    Thermostat.cluster_id,
                    0xfc11,
                    0xfc57,
                ],
                OUTPUT_CLUSTERS: [
                    Time.cluster_id,
                    Ota.cluster_id,
                ],
            },
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.THERMOSTAT,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfiguration.cluster_id,
                    Identify.cluster_id,
                    OnOff.cluster_id,
                    PollControl.cluster_id,
                    Thermostat.cluster_id,
                    0xfc11,
                    0xfc57,
                ],
                OUTPUT_CLUSTERS: [
                    Time.cluster_id,
                    Ota.cluster_id,
                ],
            },
        },
    }

KaiDroste avatar Dec 21 '23 12:12 KaiDroste

Thanks for starting to write a quirk! Unfortunately I have absolute no experience here. I just wanted to add that the local_temperature_calibration seems to be an int. For example "-10" means an offset of -1,0°C.

image

Cangoo avatar Dec 22 '23 10:12 Cangoo

I support this request

hbalzerbss avatar Dec 23 '23 13:12 hbalzerbss

I support this request

kilianramharter avatar Dec 25 '23 00:12 kilianramharter

I support this request and having the possibility to use an external sensor (Ex SNZB02) would be a killer feature

magickaribu avatar Dec 28 '23 13:12 magickaribu

+1 Support for this request!

Thanks to all Dev's that know how to do that!

Regards,

t0medic avatar Dec 29 '23 12:12 t0medic