DIY multi room thermostat

Hi all,

I’ve been running around with some ideas in my head for quite a while and post this to get a feeling if there are more of you like me :wink:.
Sorry in advance for my English it’s not my native language.

Where it all started:
I’m getting sick of all the thermostats and radiator control valves not being what I would like of them. For me as European it’s quite normal to have a central gas fired boiler. (central heating)

With my background in Proces Control systems within a big power plant I’m in for an automation challenge. Beside of that more and more people around me are automating stuff but are hitting the limitations of what some off the shelf components can do.

At the end of the line I would like to build a multi room system with cheap parts like esp’s witch is fully integrated in HA. The idea is to build it like LEGO blocks so everyone can combine the parts in the way the would like. One of the things is that we could make it possible to built it in an way that the amount of boiler fire is controlled by the amount of heat needed for the room(‘s). And that the TRV’s (thermostatic radiator valve) are not only looking to room temperature but also increasing efficiency by looking at inlet and return temperatures.

Let’s say an more advanced but cheaper version of the evo home system.

The thing about the LEGO blocks is that we could build en extend it together because a lot of us know more then one. Also some of the parts we would need are some times already proven by other diy builders.

I’m thinking about at least stuf like below here.

  • TRV (thermostatic radiator valve)
  • boiler controller board(‘s) (several protocols are in use by different manufacturers so we could do several versions)
  • HMI panel to control by touch interface (for wife approval factor)

We could update and reduce/extend this off course as we go!

Kind regards,

Rosiaantje

3 Likes

Hi @Rosiaantje, did you make any progress in the mean time?

Hi Floor,

(Sounds also quite Dutch?)

I went on with it and ordered some parts to start with the most challenging. (TRV’s) have been tinkering with them but not yet to the extend that it’s ready to share with the world.

Because of other things I’ve been building and automating this one came on the back burner.
But still want to revive it cause I still se a lot of options and not that manny cheap/diy solutions.

If you and or others are interested I would always be interested to bounce ideas around. And starting to put time in again.

@Rosiaantje, yes dutch i am! Makes it easier boiler and general setup wise. I’m having a discussion with @maxym on how to solve this exact issue. He will start introducing the TVR’s to have control of his 3rd floor but nothing yet with a smart thermostat in his setup.
What we are missing out on is the connection between the TVR’s and the smart thermostat.
I would like to use this DIY thermostat (link). Whit this thermostat i can control the boiler via the opentherm bus. This thermostat should be able to modulate and help keeping cost down.


The missing part is how will the TVR’s talk to the thermostat and how will the thermostat know what to do taking all the different TVR’s into account? I hope we can combine forces and solve this issue.

@shcherban, i think you have the solution for us. We want to understand how you linked the TVR’s to the thermostat. Can you explain?

Thats a bit tricky part and there’s lot of space to experiment.
You should understand that boiler’s thermostat cant drive TRVs by itself unless you either write your own firmware for it or drive them from elsewhere, i.e. HomeAssistant.
One of the options - you should control TRVs in each room independently with a simple relay approach (open when cold closed when warm) and boiler thermostat should be driven by the largest difference between setpoint and actual room temp (in other words - coldest room drives the boiler). For examle:
# temp setpoint difference
1 20.4° 21° 0.6°
2 21.1° 21° -0.1°
3 20.9° 18° -2.9°
Rooms 2 and 3 dont need heating, so automation should close TRVs, and 1st is 0.6° under setpoint, so that difference should drive the boiler thermostat.
Now let change situation a bit:
# temp setpoint difference
1 20.4° 21° 0.6°
2 21.1° 22° 0.9°
3 20.9° 18° -2.9°
Now Room 2 gets larger difference meaning it needs heating more than #1, and that diff is going to the opentherm thermostat.
TRV driver itself might be a simple switch in HA and all logics mentioned above can be described via HA automations. The logic for calculation the largest difference between setpoint and actual also can be placed here hovewer i find yaml programming a bit cumbersome, so i’ve moved complex logic creation to node red, since i can just draw flows there or if i’d like - write it in javascript.

@shcherban, oke i’m getting there. Maybe i will not need this advanced setup. How i see it:
Every room has TVR’s and ideally separate heat sensors. In the HA dashboard you will have a thermostat per room. These can be set manually via the app and will communicate to the DIY thermostat.
Besides that i may want to have an automation on everybody is out of the house → temp in all rooms down. Or a HA thermostat that rules them all which can lower or rise the temperature for the full house.
Do you think this is possible with HA automations only?

Every room has TVR’s and ideally separate heat sensors

that is must, there’s no point having separate TRVs for each room without separate temperature sensors.

That is possible and is a question to home assistant and your presence/occupancy sensors setup

That part would require a bit of work. Either writing custom firmware or developing a lot of automations in HA. Alternatively you can use opentherm thermostat to turn your boiler into weather-dependent regulation and simply shut it down if none ogf the rooms needs heating.

For the fast start you can tie opentherm thermostat to one of the rooms (either coldest or most occuppied where comfort if preferrable), leave TRV for that room always open, so temperature in that room wil be controlled by boiler. And the rest rooms would be a simple on-off thermostats and no open-therm aware. That kind of setup worked for me for a year, and i was pretty happy with it, boiler was almost always held in condensing mode (low temperatures).

@shcherban, would this thermostat need a lot configuration? Home Assistant OpenTherm Thermostat - DIYLESS Electronics
It seems easy.
The difficult part as i understand it is to control the boiler true multiple separate room request for heating or not heating?

Hi all,

We’re talking open therm… but are you planning to use it as boiler on/off control or variable “heatload” control? The last would be in my opinion the most energy efficient. Definitely if you can make a calculation for heat request based on the room temperatures.

I looked at building this too, went with Drayton wiser in the end.
I don’t use open therm, my boiler is too old but I modified the existing controller so that the wiser relay turn on anf off comfort mode on the existing worcester bosch greenstar boiler
Wiser then deals with the auto start time and heat up down calcs for different room sizes

i agree i would always want the boiler to be run modulated. Not on/of.

Hi @versigo, how old is your boiler?

Its a worcester greenstar r35 he plus combi
I looked to use opentherm when i decided to modify the smart thermostat. It works well enough the bosch stat is located centrally. This measures the local temp and adjusts the output power of the boiler.
Wiser/HA then changes the operating mode to comfort from frost mode.

i’m reopening this “challange” for my self… but…
i think nowday’s i would take a different route to succes.

  • Use opentherm to control the boiler / standard thermostat.
  • Use Zigbee TRVs with external room temperature input.
  • Use cheap simple battery powerd zigbee room thermostats

hooking this all up in the right way would give optimal control and still the user flexibility of local tempreature setpoint.

Or was anyone any further in this topic of building your own hardware?

1 Like

Hi, not to derail the thread but, with your suggested new route, wouldn’t you need a smart thermostat that can communicate with HA? With a standard thermostat, it would be doing its own thing.
Also, can you recommend good Zigbee TRVs and thermostats?

I have considered starting a similar project myself a few times already. Are you still interested in getting started with this?

For those of us having to work with the hardware we have, which includes no way to control the boiler other than on and off.

I use 2 generic thermostats in Home Assistant, one for downstairs and one for upstairs.

  switch:
    - name: "House Boiler"
      state_topic: "building/dhjm/boiler/states/house"
      command_topic: "building/dhjm/boiler/control/house"
      payload_on: "on"
      payload_off: "off"
      state_on: "on"
      state_off: "off"
      unique_id: onewire-d99ea90a-a20b-4ae6-9b75-662b47d28c0b

    - name: "Upper House Boiler"
      state_topic: "building/dhjm/boiler/states/bedrooms"
      command_topic: "building/dhjm/boiler/control/bedrooms"
      payload_on: "on"
      payload_off: "off"
      state_on: "on"
      state_off: "off"
      unique_id: onewire-6ac98a97-2e10-4aa4-83aa-3d2622c9dcd9
    
climate:
  - platform: generic_thermostat
    name: Lower House
    heater: switch.house_boiler
    target_sensor: sensor.average_house_temperature
    min_temp: 14
    max_temp: 25
    min_cycle_duration:
      minutes: 15
    initial_hvac_mode: "heat"
    away_temp: 16.5
    cold_tolerance: 0.3
    hot_tolerance: 0.3
    keep_alive:
      minutes: 5
    precision: 0.1
  - platform: generic_thermostat
    name: Upper House
    heater: switch.upper_house_boiler
    target_sensor: sensor.average_upper_bedrooms
    min_temp: 14
    max_temp: 25
    min_cycle_duration:
      minutes: 15
    initial_hvac_mode: "heat"
    away_temp: 16.5
    cold_tolerance: 0.3
    hot_tolerance: 0.3
    keep_alive:
      minutes: 5
    precision: 0.1

On the hardware side, I’m actually using an 8 channel One Wire Relay board that is controlled by an OW-ENET-2.

Now for the fun logic part, I use Schedy in AppDaemon, with this config - which lets me compensate for all sorts of things, like outside weather conditions, season, forecast, whether I am home etc.

schedy_heating:  # This is our app instance name.
  module: hass_apps_loader
  class: SchedyApp

  actor_type: thermostat

  schedule_snippets:
    weather:
      - x: "Add(+0.125) if is_on('binary_sensor.spring_season') else Next()"
      - x: "Add(-0.35) if is_on('binary_sensor.summer_season') else Next()"
      - x: "Add(+0.125) if is_on('binary_sensor.autumn_season') else Next()"
      - x: "Add(+0.550) if is_on('binary_sensor.winter_season') else Next()"
      - x: "Add(-0.1) if is_on('input_boolean.heating_eco_mode') else Next()"
      - x: "Add(-0.4) if is_off('input_boolean.home_state_home') else Next()"
      - x: "Add(+0.125) if float(state('sensor.cc_30_min_gust')) > 15 and (state('sensor.wind_dir_cardinal')[:1] == 'N' or state('sensor.wind_dir_cardinal')[:1] == 'E') else Next()"
#      - x: "Add(+0.025) if (float(state('sensor.cc_outside_temperature')) < 15.1 and float(state('sensor.cc_rain_rate')) > 0) else Next()"
      - x: "Add(+0.2) if float(state('sensor.cc_outside_temperature')) < -9.9 else Next()"
      - x: "Add(+0.0750) if float(state('sensor.cc_outside_temperature')) < -4.9 else Next()"
      - x: "Add(+0.045) if float(state('sensor.cc_outside_temperature')) < 0.1 else Next()"
      - x: "Add(+0.035) if float(state('sensor.cc_outside_temperature')) < 5.1 else Next()"
      - x: "Add(+0.025) if float(state('sensor.cc_outside_temperature')) < 10.1 else Next()"
      - x: "Add(+0.025) if float(state('sensor.cc_outside_temperature')) < 14.1 else Next()"
      - x: "Add(-2.5) if float(state('sensor.cc_outside_temperature')) > 30.1 else Next()"
      - x: "Add(-1.2) if float(state('sensor.cc_outside_temperature')) > 24.9 else Next()"
      - x: "Add(-0.9) if float(state('sensor.cc_outside_temperature')) > 22.9 else Next()"
      - x: "Add(-0.7) if float(state('sensor.cc_outside_temperature')) > 21.9 else Next()"
      - x: "Add(-0.5) if float(state('sensor.cc_outside_temperature')) > 20.9 else Next()"
      - x: "Add(-0.3) if float(state('sensor.cc_outside_temperature')) > 16.8 else Next()"
      - x: "Add(+0.025) if (float(state('sensor.cc_outside_temperature')) < 15.1 and float(state('sensor.openweathermap_forecast_precipitation_probability')) > 75) else Next()"
#      - x: "Postprocess(lambda result: round(result, 1))"

  rooms:

    house:
      actors:
        climate.lower_house:
      rescheduling_delay: 60
      watched_entities:
        - "input_boolean.heating_night_mode"
        - "input_boolean.home_state_home"
        - "sensor.cc_outside_temperature"
        - "sensor.cc_30_min_gust"
        - "sensor.cc_rain_rate"
        - "sensor.wind_dir_cardinal"
        - "input_boolean.heating_eco_mode"
        - "sensor.livingroom_temperature_temperature"
        - "binary_sensor.livingroom_presence"
        - "binary_sensor.spring_season"
        - "binary_sensor.summer_season"
        - "binary_sensor.autumn_season"
        - "binary_sensor.winter_season"
        - "sensor.openweathermap_forecast_precipitation_probability"
      friendly_name: House
      schedule:
        - v: 18.5
          rules:
            - x: "IncludeSchedule(schedule_snippets['weather'])"
            - x: "Add(-0.2) if is_on('input_boolean.heating_night_mode') else Next()"
            - x: "Add(+0.5) if is_on('binary_sensor.livingroom_presence') else Next()"
            - x: "Add(+0.1) if (float(state('sensor.livingroom_temperature_temperature')) < 17.8 and is_on('binary_sensor.livingroom_presence')) else Next()"
            - x: "Postprocess(lambda result: min(round(result,1), 18.8))"
            - { v: 16.0, start: "00:00", end: "07:00" }
            - { v: 17.3, start: "07:00", end: "09:00" }
            - { v: 17.5, start: "09:00", end: "11:00" }
            - { v: 17.7, start: "11:00", end: "12:00" }
            - { v: 17.8, start: "12:00", end: "13:00" }
            - { v: 18.0, start: "13:00", end: "14:00" }
            - { v: 18.1, start: "14:00", end: "15:00" }
            - { v: 18.2, start: "15:00", end: "16:00" }
            - { v: 18.3, start: "16:00", end: "18:00" }
            - { v: 18.4, start: "18:00", end: "20:00" }
            - { v: 18.3, start: "20:00", end: "20:30" }
            - { v: 18.2, start: "20:30", end: "21:00" }
            - { v: 18.1, start: "21:00", end: "22:00" }
            - { v: 18.0, start: "22:00", end: "23:00" }
            - { v: 17.9, start: "23:00", end: "00:00" }

    upper_house:
      actors:
        climate.upper_house:
      rescheduling_delay: 45
      watched_entities:
        - "input_boolean.home_state_home"
        - "sensor.cc_outside_temperature"
        - "sensor.cc_30_min_gust"
        - "sensor.cc_rain_rate"
        - "sensor.wind_dir_cardinal"
        - "input_boolean.heating_eco_mode"
        - "sensor.average_upper_bedrooms"
        - "binary_sensor.bedroom_presence"
        - "binary_sensor.spring_season"
        - "binary_sensor.summer_season"
        - "binary_sensor.autumn_season"
        - "binary_sensor.winter_season"
        - "sensor.openweathermap_forecast_precipitation_probability"
      friendly_name: Upper House
      schedule:
        - v: 18
          rules:
            - x: "IncludeSchedule(schedule_snippets['weather'])"
            - x: "Add(+0.3) if is_on('binary_sensor.bedroom_presence') else Next()"
            - x: "Postprocess(lambda result: min(round(result,1), 18.2))"
            - { v: "OFF", start: "08:00", end: "20:00" }
            - { v: 17.6, start: "20:00", end: "21:00" }
            - { v: 17.7, start: "21:00", end: "22:00" }
            - { v: 17.8, start: "22:00", end: "23:00" }
            - { v: 17.9, start: "23:00", end: "00:00" }
            - { v: 18.0, start: "00:00", end: "01:00" }
            - { v: 18.1, start: "01:00", end: "02:00" }
            - { v: 18.0, start: "02:00", end: "03:00" }
            - { v: 17.9, start: "03:00", end: "04:00" }
            - { v: 17.8, start: "04:00", end: "05:00" }
            - { v: 17.7, start: "05:00", end: "06:00" }
            - { v: 17.6, start: "06:00", end: "07:00" }
            - { v: 17.5, start: "07:00", end: "08:00" }

    attic:
      actors:
        climate.attic_fans:
          hvac_mode_on: cool
      schedule:
        - v: 17.5
          start: "08:00"
          end: "22:00"
        - v: "OFF"
      friendly_name: Attic

is it even possible to use feature of modulating when controlling temp in multiple rooms?
Are there some complete solutions (ie from major companies) we could take ideas from or use some of solutions or their parts?