Need help with smart heating (zigbee2mqtt or zha, TUYA TS0601/MoesHY368)

Hi, I got stuck with the configuration of smart heating.
What do I have:

  1. Working Zigbee Home Automation.
  2. Connected a few Tuya TS0601 / Moes HY386 type1 radiator valves. Added as devices to the integration.
  3. Relay on ESPHome to turn ON/OFF heater.
  4. Each radiator valve has state:
hvac_modes:
  - heat
min_temp: 5
max_temp: 35
preset_modes:
  - none
  - away
  - schedule
  - comfort
  - eco
  - boost
  - complex
current_temperature: 22
temperature: 5
hvac_action: idle
preset_mode: none
system_mode: '[4]/heat'
occupancy: 1
occupied_heating_setpoint: 500
unoccupied_cooling_setpoint: 1500
friendly_name: Bedroom Yourik radiator valve thermostat
supported_features: 17

What do I want to have:
If temperature on radiator valve goes below threshold - it opens and also it starts heater. So each room can have it’s own temperature and I warm only rooms I need.
How I was trying to solve this:

  1. Generic thermostat.
climate:
  - platform: generic_thermostat
    name: Yourik Bedroom manual thermostat
    heater: device_tracker.e8_db_84_ae_2a_b0
    target_sensor: climate.bedroom_yourik_radiator_thermostat
    min_temp: 10
    max_temp: 30
    ac_mode: false
    target_temp: 18
    cold_tolerance: 0.3
    hot_tolerance: 0
    min_cycle_duration:
      seconds: 5
    keep_alive:
      minutes: 3
    initial_hvac_mode: "idle"
    away_temp: 16
    precision: 0.1

this makes an error in logs - Unable to update from sensor: could not convert string to float: ‘heat’
So it doesn’t seem to be a good idea.

  1. Automation using created devices
    Goal - if I receive change state from any radiator valve I compare temperature against current_temperature and execute script with heater on or off.
alias: Heater ON-T
description: ''
trigger:
  - platform: state
    entity_id: climate.bedroom_yourik_radiator_thermostat
  - platform: state
    entity_id: climate.bathroom_radiator_thermostat
condition:
  - condition: or
    conditions:
      - condition: template
        value_template: >-
          states(''climate.bedroom_yourik_radiator_thermostat.temperature'')|int
          >
          states(''climate.bedroom_yourik_radiator_thermostat.current_temperature'')|int
      - condition: template
        value_template: >-
          states(''climate.bathroom_radiator_thermostat.temperature'')|int
          >
          states(''climate.bathroom_radiator_thermostat.current_temperature'')|int

action:
  - service: script.heater_turn_on
mode: single

this doesn’t work. Despite of the temperature/current_temperature values - it always call the script.

  1. Use automation based on HVAC_ACTION
    Since hvac_action can be idle or heating
alias: Heating ON
description: ''
trigger:
  - platform: state
    entity_id: climate.bedroom_yourik_radiator_thermostat
    attribute: hvac_action
    from: idle
    to: heating
    for: '00:01:00'
  - platform: state
    entity_id: climate.bathroom_radiator_thermostat
    attribute: hvac_action
    from: idle
    to: heating
    for: '00:01:00'
condition: []
action:
  - service: script.heater_turn_on
mode: single

it almost worked. But there were moments when hvac_action changes but this event is somehow not registered or temperatures changes but hvac_action is not and, correspondingly, heater doesn’t go on/off.

Or I went to completely wrong direction and it is better to use MQTT integration?
So I would appreciate any advice on how to set it up.

1 Like

1 is the correct way, create a climate entity. However heater: is supposed to be a switch to turn the heating on, device_tracker.e8_db_84_ae_2a_b0 is a device tracker, it can’t swtich your boiler on surely?

Also target_sensor: climate.bedroom_yourik_radiator_thermostat is weird. Do you already have a climate entity? What is it? Is climate.bedroom_yourik_radiator_thermostat even an entity? If it is, the state of a climate entity is not a temperature, it is a string like heat. Guessing this is the real problem.

target_sensor string REQUIRED>
entity_id for a temperature sensor, target_sensor.state must be temperature.

Also your subject says zigbee2mqtt, your questions says ZHA. Which is it?

Hi Nick.
Thank you for you answer.
yes, good point, it should not be device tracker. Correct entity id is switch.house_cv_relay. This is fixed.

about target sensor - this ID I copied from integration->zha->device->entity


What Nick is saying is that the target_sensor must be a sensor whose state is a temperature.

So you would have to extract the current temperature of your existing climate as a sensor (assuming that’s what you want)

Something like:

template:
  - sensor:
      - name: "Bedroom Yourik Current temperature"
        unit_of_measurement: "°C"
        state: "{{ state_attr('climate.bedroom_yourik_radiator_thermostat', 'current_temperature') | float }}"

Then use sensor.bedroom_yourik_current_temperature as the target_sensor

1 Like

Hi Chris,
ok, this part was successful. I created thermostat and two sensors

climate:
  - platform: generic_thermostat
    unique_id: bedroom_yourik_generic_thermostat
    name: Yourik Bedroom manual thermostaat
    heater: switch.house_cv_relay
    target_sensor: sensor.bedroom_yourik_current_temperature
    min_temp: 10
    max_temp: 30
    ac_mode: false
    target_temp: 18
    cold_tolerance: 0.3
    hot_tolerance: 0
    min_cycle_duration:
      seconds: 5
    keep_alive:
      minutes: 3
    initial_hvac_mode: "off"
    away_temp: 16
    precision: 0.1
template:
  - sensor:
    - name: "Bedroom Yourik Current temperature"
      unique_id: sensor.bedroom_yourik_current_temperature
      unit_of_measurement: "°C"
      state: "{{ state_attr('climate.bedroom_yourik_radiator_thermostat', 'current_temperature') | float }}"
    - name: "Bedroom Yourik target temperature"
      unique_id: sensor.bedroom_yourik_target_temperature
      unit_of_measurement: "°C"
      state: "{{ state_attr('climate.bedroom_yourik_radiator_thermostat', 'temperature') | float }}"

and now I created an automation

alias: Heating manual
trigger:
  - platform: template
    value_template: >-
      states(''sensor.bedroom_yourik_target_temperature'')|float >
      states(''sensor.bedroom_yourik_current_temperature'')|float
condition: []
action:
  - service: persistent_notification.create
    data:
      message: yourik target T > current T

but now I am still confused

  1. when target T is more that current T - heater relay turns ON (and heater starts). But in this case - thermostat motor doesn’t work, hvac_action remains the same, so it won’t open (or close) a radiator crane. And I didn’t find a way to change it. I can do either on/off/toggle radiator, change preset and change HVAC mode (which has only value HEAT). None of these starts motor

  2. I have a few radiators. Do I understand it correct that I’ll need to duplicate generic_thermostat and two sensors for each of them but use the same *heater: switch_house_cv_relay" ?

A tad confusing.
What is “thermostat motor” and how does it relates to the relay?

TS0601_thermostat
this thermostat has a motor inside which opens or closes valve. This process is based on

hvac_action = idle/heating

so if take climate.bedroom_yourik_radiator_thermostat entity (see above) and change this parameter - valve will get open/closed. And Step 3 (see above) is based on this parameter.
But I don’t know how to access this field if I do automation for generic thermostat (see screenshots above)

Ok, but what does the relay do, then?
If it’s unrelated to the valve, then you would have to open the valve as a secondary service in the same automation.

Relay is responsible to start a heater itself. It switches it on.

so all thermo-vales control temperature in each room, they also open\close each radiator and tell * switch.house_cv_relay * to start heating process.

So to heat the room you need to

  1. turn the boiler on; and

  2. open the valve?

In that case you need to set the heater: in your Generic Thermostat needs to be a toggle that does both of those things.

so far my automation looks like:

alias: Heating ON 2
description: ''
trigger:
  - platform: state
    entity_id: climate.bedroom_yourik_radiator_thermostat
  - platform: state
    entity_id: climate.livingroom_radiator_thermostat
condition:
  - condition: or
    conditions:
      - condition: template
        value_template: >-
          states(''sensor.bedroom_yourik_target_temperature'')|float >
          states(''sensor.bedroom_yourik_current_temperature'')|float
      - condition: template
        value_template: >-
          states(''sensor.living_room_target_temperature'')|float >
          states(''sensor.living_room_current_temperature'')|float
action:
  - service: script.heater_turn_on
mode: single

where all sensor.xxx - are defined as template sensors.
both current temperature = 20 degree
both target temperature = 5 degree
when I start automation - it turns on the heater relay.

What is wrong with the conditions? I can’t see it :frowning:

but the idea is - radiator valve knob takes care of opening or closing the radiator valve. And on every state change - I decide either to turn on or turn off the heater itself

I found a solution.
configuration:

template:
  - sensor:
    - name: "Bedroom Yourik Current temperature"
      unique_id: sensor.bedroom_yourik_current_temperature
      unit_of_measurement: "°C"
      state: "{{ state_attr('climate.bedroom_yourik_radiator_thermostat', 'current_temperature') | float }}"
    - name: "Bedroom Yourik Target temperature"
      unique_id: sensor.bedroom_yourik_target_temperature
      unit_of_measurement: "°C"
      state: "{{ state_attr('climate.bedroom_yourik_radiator_thermostat', 'temperature') | float }}"
    - name: "Bathroom Target temperature"
      unique_id: sensor.bathroom_target_temperature
      unit_of_measurement: "°C"
      state: "{{ state_attr('climate.bathroom_radiator_thermostat', 'temperature') | float }}"
    - name: "Hallway Current temperature"
      unique_id: sensor.hallway_current_temperature
      unit_of_measurement: "°C"
      state: "{{ state_attr('climate.hallway_radiator_thermostat', 'current_temperature') | float }}"

and automation is:

alias: Heating ON-OFF
description: ''
trigger:
  - platform: state
    entity_id: climate.bedroom_yourik_radiator_thermostat
  - platform: state
    entity_id: climate.bathroom_radiator_thermostat
condition: []
action:
  - choose:
      - conditions:
          - condition: template
            value_template: >-
              {{states('sensor.bedroom_yourik_current_temperature')|float > 
              states('sensor.bedroom_yourik_target_temperature')|float }}
          - condition: template
            value_template: >-
              {{states('sensor.bathroom_current_temperature')|float >
              states('sensor.bathroom_target_temperature')|float }}
        sequence:
          - service: script.heater_turn_off

maybe it will help someone who has similar problem.

Didn’t find yet how to manage presets but will be investigating.

This looks exactly like the solution I need but unfortunately I cannot get it to work.
Would you please assist?


As can be seen from the screenshot - the state has a ‘local_temperature’ attribute that I wish to use in a virtual sensor.


template:
  - sensor:
    - name: "Guest Bedroom TRV sensor"
      unique_id: sensor.guest_bedroom_trv
      unit_of_measurement: "°C"
      state: "{{ state_attr('climate.0x003c84fffe21f325', 'local_temperature') }}"

climate.0x003c84fffe21f325 is the ID of the device in HASS, though I’m getting:
TemplateError('ValueError: Template error: float got invalid input 'None' when rendering template '{{ state_attr('climate.0x003c84fffe21f325', 'local_temperature') | float }}' but no default was specified') while processing template 'Template("{{ state_attr('climate.0x003c84fffe21f325', 'local_temperature') | float }}")' for attribute '_attr_native_value' in entity 'sensor.guest_bedroom_trv_sensor'

Any ideas?

You might like to check out Heating X2: Schedule Thermostats with Calendars

Heating X2 features:

  • Schedule by calendar: set the temperature of each room with a local calendar and as many heating events as you like
  • Multiple thermostats: One or more thermostats per room: multiple thermostats are synchronised together. Works with smart TRVs, any smart thermostat, or Generic Thermostat
  • Manual override: a change on the thermostat, dashboard or by voice assistant remains in effect for a defined period (default 2 hours)
  • Door or window open: heating turns off heating in the room if any door or window is left open for a defined period (default 3 minutes) – optional list of zero or more closure sensors.
  • Occupancy: heating turns off heating if a room is left unoccupied for a defined period (default 1 hour) – optional list of zero or more motion or human presence sensors.
  • Warmup period: occupancy is ignored for a defined period at the start of a calendar event (default 2 hours)
  • Away mode: set all rooms to a temperature specified per room (default 5C) when there is no one at home
  • Background temperature: used when there is no calendar event (default 5C but specified separately from the frost and away temperatures)
  • Zone control: can switch one or multiple heating zone valves, or a boiler that needs a heat demand switch, based on heat demand from a group of thermostats
  • Notifications: if thermostats do not respond to a new setting, go offline, or come back online
  • Robust: Graceful degradation when a thermostat or a sensor is offline
  • Battery-efficient: conserves TRV battery life by only transmitting real changes
  • Code generator: uses mail merge (!) to automatically generate YAML code for helpers, timers, template sensors, groups, automations, and dashboard cards from a single EXEL spreadsheet that lists zones, rooms and thermostats