Tuya TV02 Zigbee Thermostatic radiator valve hysteresis

Hi all,
I have a Honeywell Evohome central heating control system which I have been successfully operating with HA for over 2 years. I have the full complement of 12 radiator valves on the Evohome System, but I have an upcoming problem - a new conservatory will put our total of radiators up to 14 (a new pair of radiators in the conservatory).

I decided the best course of action was to buy some Zigbee thermostatic valves each of which I could operate as a ‘slave’ to one of the Evohome valves. For example, I have anormal radiator and a towel radiator in the bathroom. I was hoping that I could use an automation to make sure the temperature setting of a Zigbee radiator valve on the towel radiator follows that of the Evohome radiator.
I managed to successfully get the zigbee valve (a Tuya TV02) to follow the temperature of the Evohome valve, BUT - I came across something strange - even though the towel radiator temperature was above the ambient temperature reported by that valve, it was not opening and thus the towel radiator was not heating when it should.

I did some experimenting and I found that the Tuya TV02 will only open when the set temperature is >4 degrees centrigrade above the reported ambient. It will close the valve when the set temperature is more than 1 degree centrigrade below the reported ambient.

I am OK with the latter, but not opening until the set temperature is 4 degrees above ambient is not acceptable behaviour (to me anyway). Does anyone have any idea if this is set in stone, or is there a setting I can change to reduce the range over which the valve opens and closes?

Also, does anyone know what the 3 x ‘switches’ which HA shows for the Tuya TV02 entity are for?#

Many thanks and a belated happy new year to you all.
Peter

1 Like

@bigbigblue I bought a Tuya TV02 a while back for evaluation and found it troublesome both in responsiveness to commands and in trying to work the schedules. e.g. I needed to wake it up every 10 mins with a dummy zigbee command in order that it would report its temp etc. In the end I chose the Moes BRT-100-TRV which has been really good.
Re. your problem I would try setting the local_temperature_calibration to a -ve value. This might make it open in a more timely fashion.
I’ve no idea what you mean by 3 x ‘switches’ - please explain.
Happy New Year to you too, Peter!

I dont have many issues with responsiveness - although I do issue each command twice, 5 seconds apart, in an attempt to avoid issues.
Unfortunately I dont think the Moes devices are readily available in the UK. I have managed to do a work around for the large hysteresis of the TV02’s. When the master (Evohome) thermostat temperature changes, I immediately set the tv02 temperature to 30 degrees. In my scenario, this will ensure the valve always opens. I also start a 2 minute timer. This will allow enough time for the TV02 to open if it is needed. I then set the TV02 temperature to the same as the master (Evohome) thermostat. The TV02 will then stay open if it needs to, or closes if it needs to. It isn’t perfect, but it limits the unneccesary open time to 2 mins plus the time taken to close the valve.

In terms of the ‘switches’, if I go into 'Settings@, then ‘Devices and Services’, then select ‘Entities’ under the Zigbee dongle entry, then select the TV02’s entry, the resulting panel, under the ‘controls’ section, HA shows 3 switches, but they are just called ‘switch’. I have no idea what they are for, but the first 2 are ‘off’ and the third is ‘on’.

I use zigbee2mqtt which explains why I’m not seeing the ‘switches’ x3 issue.

I got the Moes BRT-100-TRVs via Bangood, I believe.

I’m working on a ‘holistic’ temperature control method using node-RED flows to tweak the TRVs and the central thermostat (Hive) dynamically in response to actual room temperatures (measured with Aqara sensors). I’ve found so far, that uploading a programmed-mode schedule to each TRV at start of day and then altering the calibration levels individually is quite successful. I prefer this to dynamically tweaking the setpoint.

At the moment I’m trying to make the bright green line (room temp) in this chart straighten out to match the red one (target room temp in schedule). It would be neat if I could get it to predict where the room temp will be in 10 mins time rather than working on hindsight.

Well hello. I’ve also just received these TRV’s and came across this issue so i’ve been doing some research.
Here’s where I’m at:
" The switches must be “Boost function”, “Child Lock” and “Online Mode” (whatever they are). " [Device Support Request] MOES TRV TV02 (TS0601 - _TZE200_kds0pmmv) · Issue #1839 · zigpy/zha-device-handlers · GitHub
This version of the TRV does NOT support valve %/ manual opening/closing. (the TV01 version did)

Normally the boost function should run a timer for 5-ish minutes but this doesn’t seem to be the case when switched on via HASS. Since i presume this boost function will open the valve (from what i’ve read, im not at home right now so havent checked yet.)

However, sending the zigbee command to set this function to a number does in fact turn that switch on for that many seconds.

service: zha.set_zigbee_cluster_attribute
data:
  cluster_type: in
  ieee: --redacted--
  endpoint_id: 1
  cluster_id: 61184
  attribute: 613
  value: "300"

For those who already want the command.

I’ll test to see if this opens the valve, and if it does if it stays open until temp is reached or if it closes it back. if it does open until temp reached then all that is needed is to write an automation to send that command once the requested temp > current temp and we should be good to go!

I’ll keep you guys posted and i think this is a good reason to necro this thread :slight_smile:

1 Like

FYI, it works!
Just made an automation that sends that command when the temperature of the room is lower than the requested/target temperature and done :slight_smile:

1 Like

iirc, the switches are child lock, open window detection and recalibrate. You have to play around to find out which is which, and then you can rename them on your device.

I thought I was getting crazy, now I finally found an explanation :smiley:

I think because of all these limitations these valves can only be used as ON/OFF switches (using really high and low temperatures thresholds) but not really as thermostats. That’s really a shame… I’ve been using them for a year and they are cheap, look good but do cause a lot of issues…

I’m wondering if there is somewhere a Zigbee thermostat valve that just works where you can actually control both target temperature AND valve opening without weird hysteresis or unknown functions. Been looking for quite some time…

1 Like

Thanks, @stinobook, your command works!

I’ve tried many Zigbee TRVs so far and all of them are just too loud for the bedroom, so I was very excited to find the very quiet TV02. However, this hysteresis issue hit me almost immediately. I suspect that this TRV actually only has two states, OPEN and CLOSED, and that the excessive hysteresis range is to protect against repeated temperature “surfing” that would otherwise drain the battery more quickly and incur more wear-and-tear on the gears.

The other TRVs I’ve tried seem to be able to make analogue adjustments to the open state of the valve, which allows them to stay within a degree of the target temperature. Some of them even try to “learn” the correlation between valve settings and temperature, which I’m somewhat skeptical of as I do not trust hidden state in my devices.

Given how cheap and quiet this TRV is I am contemplating embracing the ON/OFF behaviour and working around it in Home Assistant. In general I prefer my devices to be dumb and stateless, but the automation could be quite fiddly.

All I want (for Christmas) is a simple, functional, and quiet TRV. Is that too much to ask?

Following the suggestion by @stinobook I can confirm that setting the boost timeout works and breaks the TRV out of it’s hysteresis state. In fact it will not close the valve again until the current temperature is 1 degree above the target, which is more-or-less what you would want. You could send this command every time you raise the temperature, but once it closes (or if someone adjusts the target manually) it would once again be stuck in hysteresis.

I’ve written a little sentry script that triggers when the temperature drops 1 degree below target and sets the boost timeout to 60 seconds (as long as a boost isn’t running already)

alias: Bedroom Radiator sentry
description: ""
trigger:
  - platform: state
    entity_id:
      - climate.bedroom_radiator
condition:
  - alias: When 1 degree below target
    condition: numeric_state
    entity_id: climate.bedroom_radiator
    value_template: >-
      {{ state_attr('climate.bedroom_radiator', 'current_temperature') -
      state_attr('climate.bedroom_radiator', 'temperature') }}
    below: -1
  - condition: numeric_state
    entity_id: sensor.bedroom_radiator_boost_timeset_countdown
    below: 1
action:
  - device_id: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    domain: number
    entity_id: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    type: set_value
    value: 60
mode: single

It works well, but I’m still not sure if I’m willing to accept the ON/OFF behaviour and coarse, infrequent, temperature reports from this TRV yet.

1 Like

I have followed this discussion after I noticed the huge activation threshold of > 4°C.
The presented solution, to setup a short boost works well for me.
Because I have many thermostats, I want to share my adaptation of @rawnsley `s automation. This now allows to select all thermostats and boost the one where the tigger condition is met individually.

alias: "Boost Thermostat "
description: >-
  10 second boost, when the target temperature is 1 degree above the current temperature
triggers:
  - trigger: numeric_state
    entity_id:
      - climate.arbeitszimmer_thermostat
      - climate.esszimmer_thermostat
      - climate.badezimmer_thermostat
      - climate.wohnzimmer_thermostat
      - climate.schlafzimmer_thermostat
    value_template: >-
      {{ state_attr(trigger.entity_id, "temperature") -
      state_attr(trigger.entity_id, "current_temperature") | float}}
    above: 1
    attribute: temperature
conditions: []
actions:
  - action: number.set_value
    metadata: {}
    data:
      value: "10"
    target:
      entity_id: >-
        {{ trigger.entity_id | replace('climate', 'number')
        }}_boost_timeset_countdown
mode: restart
2 Likes

@Matten @rawnsley thanks for your input here, i have the same issue with my TV02 Tuya Zigbee Valves, you have to manual put the temperature 4° higher than the actual temperature to get the valve working.
Where should I program this script? Is it a template automation? And do I have to change anything besides the names of the entities?

Because I get this error when starting the automation

Error: Template rendered invalid entity IDs: _boost_timeset_countdown

This is the entity of one of my valves

number.radiator_badkamer_beneden_boost_timeset_countdown

An actuator is completely silent. They are mains or 12/24 volt operated and most of them just work as on/off. But for us that is good enough.
Seeing here when we came home from a vacation the temperature held itself reasonably within the specified range.

It’s set to 20.9 degrees with a cold_tolerance of 0.3.
The lowest temperature in this range was 20.4.

I have made an automation with the following script, maybe someone can tell me if it’s ok or say what’s best to do?

id: '1732032870780'
alias: CV Radiator Badkamer Beneden Wake-Up
description: ''
triggers:
  - entity_id:
      - climate.radiator_badkamer_beneden
    trigger: state
conditions:
  - alias: When 1 degree below target
    condition: numeric_state
    entity_id: climate.radiator_badkamer_beneden
    value_template: >-
      {{ state_attr('climate.radiator_badkamer_beneden', 'current_temperature')
      - state_attr('climate.radiator_badkamer_beneden', 'temperature') }}
    below: -1
  - condition: numeric_state
    entity_id: number.radiator_badkamer_beneden_boost_timeset_countdown
    below: 1
actions:
  - action: number.set_value
    metadata: {}
    data:
      value: '10'
    target:
      entity_id: number.radiator_badkamer_beneden_boost_timeset_countdown
mode: restart

This code does not work for me, it says “Template rendered invalid entity IDs: _boost_timeset_countdown” can somebody give me a tip or show me how I should use this code in a template with my entities below ?

climate.radiator_badkamer_beneden
climate.radiator_badkamer_boven
climate.radiator_keuken

Thank you