Underfloor heating project for a HA Newbie

thanks for your detailed post @c957031

I have the same requirement as you @gemboly - I was looking at MH7H-WH/MH7H-EH-广州迈赫姆电子科技有限公司 for a Z-Wave option although currently unsure if I need the WH or EH version for Thermo-Electric Actuators.

Edit: this could also work I believe: MH3901-Z-广州迈赫姆电子科技有限公司

You would of course also need a Z-Wave controller

1 Like

Also became aware of this off the shelf solution that looks interesting for the use case if you prefer Z-Wave over the custom ESP board solution:

https://www.mcohome.com/Multi-relay-controller-PG7037109

Although currently do not see it for sale from any retailers online.

Thanks for sharing, I’m planning a quite similar solution and this was good inspiration. Have most components acquired but have not come to the installation yet (mostly working on bench for now). During development I have also found these ESP32 Development Board - AliExpress, I still use the same ESP12E version as you but the extra versatility and exposed GPIO’s with those board look interesting as a future upgrade.

In addition I plan to use wall thermostats as room sensors, giving the option to set and view temperatures in rooms without using HA, but not connect the output or relay on them. I shoose these ones but are many other similar, Smart Thermostat - Aliexpress (that now also work with ZHA using the custom quirk ts0601_thermostat_avatto.py).
My initial goal is to let the room thermostat (virtual) heating status to be mirrored to the relay board via a home-assistant template.
Further on it might have to be replaced by a HA thermostat like swingerman/ha-dual-smart-thermostat (github.com) if adding AC to the equation as the wall thermostats only support heating.

A second addition is that I plan for connecting Dallas one-wire thermometers to the incomming water and all returns, is at least one input GPIO left on the relay-board. From those calculate the delta-temperature and estimate some statistics or usage per room. If someone has done anything similar I’m happy to receive guidance. I just have to assume some static water-flow once the valve is open, adding flow-meters seem a bit overambitious.

Hello there !

I am currently in the process of choosing my underfloor heating control system and so far I have identified three options:

  • The installer option based on Nussbaum hardware and relying on Modbus protocol for communication with HA. Probably the most expensive solution (And not that easy to integrate to HA?).

  • The “Kit” option using hardware such as the Homematic IP relying on Homematic HA integration for communication with HA. It looks easy and affordable but I don’t know how trusty this brand is and/or reliable it is.

  • And the DIY option (Relay board,etc…). The cheapest but regulation is maybe less accurate or more complex to manage?

I have a heat pump (geothermal) as heat source and it has “free cooling” capacity during the summer.

I don’t know if the DIY option would be feasible with both heating and cooling mode?

From what I have read here, the DIY option only work with ON/OFF valve and not adjustable valves, is that right?

What would be your suggestions for my use case? Can you give feedback about your installations?

Thanks in advance.

What did you end up with in the end? I’m going through the exact same thing in the next couple of months, so I’m curious to learn from your experiences.

thanks @c957031 for the reply. Seems interesting, but I agree with @Jack-Harper that adjustable valves (not just on/off) might be better to created a balanced system in which the heat pump can run longer, but on a modulated setting (requiring lower supply temperature and hence higher COP). Anybody any advice here? Interested in co-developing/co-prototyping something.

Hello again Jack-Harper and antonclaeys
I have to say that I was also skeptical regarding the binary (on/off only) valves and if I should investigate adjustable valves. However, my setup was born with the binary valves so I decided to give it a go.
The result was convincing to me, and if you look at the temperature log (screen dump below) the temperature fluctuates around half a degree (celsius) above and below the target temperature. This is close enough for my usage so I am not investigating further.
In my development I started with a beta setup of 2 rooms in order to investigate if the functionality was adequate and this proved the point to me. I then continued with building the control box and adding the rest of the house.

Of course my results cannot necessarily be reproduced in your setup since a variety of factors apply.

Please post what you come up with in your setups

BR David

@c957031 I follow your reasoning that the room temperature deviations are quite ok. However, do you have an idea of the supply water temperature of your heating device? You mention you have district heating; do you also have a small heat pump in your home to increase the supply temperature, or are you just directly using what comes in? Because in the latter case, you’re probably not really interested in the efficiency.
In case of a heat pump, it is key to avoid cycling and to have it running in as low power as possible, so instead of turning the loop ON three times as in your screenshot, you would want to have it cycle less and keep it on longer, but on a lower supply temperature

Hi antonclaeys,
The way district heating works in my setup is that I have a heat exchanger that transfers the heat from the district heating circuit into my home circuit (the circuits don’t exchange the water, only the energy). I don’t have a heat pump in my setup. The temperature of the water is max 35°C in my underfloor circuits.
/David

Yes, that’s what i thought. in your case, you have no benefit/incentive of lowering the supply temperature. when you have a heat pump you do. I typically can heat my home with 28 to 30°C °C supply temperature, but lowering it even further would increase my heat pump’s efficiency and hence lower my electricity consumption.

Have any of you come across a way to adjust the shunt thermostat with HA? I have water floor heating myself and would like to adjust the temperature of the circulating water with HA.

Hi @c957031
Its really interesting system you’ve setup and I plan to do something similar. I even believe we might be from the same country :smiley:

My question is, in my setup I have a pump that circulates the water in the underfloor heating. This pump is controlled by the old controller which I would like to replace.

I was thinking if you have such a pump, and how you control it? Ideally I could control it using one relay on the relay board, and just have some simple HA automation that would make sure the pump would run in case is any of the thermostats are calling for heating.

Thanks in advance.
/Martin

Hi Martin
Truthfully I have the same challenge that you are describing, and I was going to post a question in here asking the HA-wizards how to best solve it. In summary, I have 10 relays connected to heating valves, and relay connected to the pump. So the question is: I want the pump to switch on if either of the 10 relays is on and off again when all 10 relays are off.
Howto do that?
New post on this topic
/D

Hi Martin
I asked some wizards in another thread and solved the problem:

Share how your setup is doing when you get there.

/D

1 Like

Hi David, For some reason I do not get notified when replies are in. My apology for not getting back sooner.
Thank you very much for your help on this. I have not received the hardware yet, but when I do, I will make sure to post how I resolve it here. Your post will come handy in my setup Im sure. Thanks.

Br Martin

Hi All
I am experimenting with a similar setup but using offsetable Tuya TRVs in connection with the better-thermostat script. In my case the fluctuation usually stays at around 0.5°C around the target temperature too. (There are occasional outliers up- or downwards, but they might actually be caused by faults in the rather cheap TRVs.)

The Tuya TRV theoretically could partly open the valves given they are using a small electric motor. Unfortunately the internal firmware does not seem to support this, can only fully open or fully close the valve. Hence effectively the same setup as c957031’s.

What I wonder though is energy efficiency. Note I can not change the supply temperature as it is set by the building’s central heating (not controllable by me). Still, I wonder whether a continuous but limited/adjusted water flow would be more energy efficient that my on-off controlled setup.

Does anyone have an idea about this?

Hi everyone,
First of all - thank you @c957031 for this thread. I’d never come up to do this myself. Now I’m assembling my own system. :slight_smile:

I hope I can add something to this topic.

As I’ve had my HA crash on me multiple times, I’m very cautious about relying on it for such a critical part of the house.
Because of that I came up with some fall-backs.

For example, you can run a script on the node which checks for connection to HA, and if there is none then closes all valves and shuts off the pump. This is what that looks like:

YAML
esphome:
  name: "heating-1"
  friendly_name: Heating 1
  on_boot:
    then:
    - script.execute: connection_watchdog

script:
  - id: connection_watchdog
    mode: queued
    then:
      - if:
          condition:
            not:
              api.connected:
          then:
          - switch.turn_off: pump
          - switch.turn_off: valve_hot
          - switch.turn_off: valve_loop_1
          - switch.turn_off: valve_loop_2
          - switch.turn_off: valve_loop_3

This will speed up the reaction - ESP Home nodes by default reboot after 15 min without active connection.

You can also have the script handling the pump running on the ESP itself. This might be interesting for @Atomizer too.

script:
  - id: recirculate
    mode: restart
    then:
      - switch.turn_on: pump
      - wait_until:
            lambda: |-
                if (!id(valve_loop_1).state 
                and !id(valve_loop_2).state 
                and !id(valve_loop_3).state) {
                return true;
                } else {
                return false;
                 }
      - delay: 500s
      - switch.turn_off: pump

The script should be called when a valve is opened:

switch:
  - platform: gpio
    name: valve_loop_1
    on_turn_on:
      then:
        - script.execute: recirculate

For my setup I opted to use Thermostat component for ESP Home to run directly on the node.
Together with LYWSD03 BLE sensors in every room, that makes it completely independent of the HA, as the sensors can communicate directly with ESP.
It can also handle both heating and cooling, which was an additional requirement for me.

I also added Dallas sensors to monitor the temperature in the manifold and all returns and shut everything off if it exceeds a threshold.
@dala318 can you share what you’ve done with your sensor readings?

1 Like

Hi. Part of my ESPHome config.
Still not fully in operation, but i guess you can take some inspiration from it, and feedback if you find any bugs in it :wink:

# External connectors
# 5V
# TXd - GPIO1 - use for Dallas in non-flashing mode
# RXd - GPIO3
# IO0 - GPIO0 - connect to GND and reboot (power cycle) if you need to set the ESP8266 in flash mode
# GND
# GND
# IO2 - GPIO2 - also used for the (blue) LED on the ESP8266
# ADC - A0 / GPIO17 - the analog input of the ESP8266

substitutions:
  # Deafult values, can be overriden before <<: !include .<this file>.yaml
  pin_status: GPIO23        # Internal
  pin_onboard_button: GPIO0 # Internal

  pin_relay1: GPIO32        # Internal
  pin_relay2: GPIO33        # Internal
  pin_relay3: GPIO25        # Internal
  pin_relay4: GPIO26        # Internal
  pin_relay5: GPIO27        # Internal
  pin_relay6: GPIO14        # Internal
  pin_relay7: GPIO12        # Internal
  pin_relay8: GPIO13        # Internal

  pin_dallas: GPIO22        # data + gnd + 3.3v
  pin_water_pulse: GPIO02   # data + gnd + 3.3v

  incomming_temp_adress: "0x0000000000000000"

  room1_name: "Room #1"
  room1_temp_adress: "0x0000000000000000"
  room1_thermostat: "climate.one"
  room2_name: "Room #2"
  room2_temp_adress: "0x0000000000000000"
  room2_thermostat: "climate.two"
  room3_name: "Room #3"
  room3_temp_adress: "0x0000000000000000"
  room3_thermostat: "climate.three"
  room4_name: "Room #4"
  room4_temp_adress: "0x0000000000000000"
  room4_thermostat: "climate.four"
  room5_name: "Room #5"
  room5_temp_adress: "0x0000000000000000"
  room5_thermostat: "climate.five"

logger:
  baud_rate: 0  # Make sure logging is not using the serial port and RX/TX pins

dallas:
  - pin: ${pin_dallas}
    # update_interval: 10s

status_led:
  pin:
    number: ${pin_status}
    # inverted: yes

time:
  - platform: sntp
    on_time:
      - seconds: 0
        minutes: /5  # Every 5 minutes
        then:
          - script.execute: set_circulation_state

script:
  - id: set_circulation_state
    then:
      - logger.log: "Checking if circulation shall change"
      - if:
          condition:
            or:
              - switch.is_on: valve_1
              - switch.is_on: valve_2
              - switch.is_on: valve_3
              - switch.is_on: valve_4
              - switch.is_on: valve_5
          then:
            - switch.turn_on: cirkulation_relay
          else:
            - switch.turn_off: cirkulation_relay

switch:
  - platform: gpio
    pin: ${pin_relay1}
    name: Underfloor ${room1_name}
    id: valve_1
    icon: mdi:valve
    restore_mode: RESTORE_DEFAULT_OFF
    on_turn_on:
      - script.execute: set_circulation_state
    on_turn_off:
      - script.execute: set_circulation_state

  - platform: gpio
    pin: ${pin_relay2}
    name: Underfloor ${room2_name}
    id: valve_2
    icon: mdi:valve
    restore_mode: RESTORE_DEFAULT_OFF
    on_turn_on:
      - script.execute: set_circulation_state
    on_turn_off:
      - script.execute: set_circulation_state

  - platform: gpio
    pin: ${pin_relay3}
    name: Underfloor ${room3_name}
    id: valve_3
    icon: mdi:valve
    restore_mode: RESTORE_DEFAULT_OFF
    on_turn_on:
      - script.execute: set_circulation_state
    on_turn_off:
      - script.execute: set_circulation_state

  - platform: gpio
    pin: ${pin_relay4}
    name: Underfloor ${room4_name}
    id: valve_4
    icon: mdi:valve
    restore_mode: RESTORE_DEFAULT_OFF
    on_turn_on:
      - script.execute: set_circulation_state
    on_turn_off:
      - script.execute: set_circulation_state

  - platform: gpio
    pin: ${pin_relay5}
    name: Underfloor ${room5_name}
    id: valve_5
    icon: mdi:valve
    restore_mode: RESTORE_DEFAULT_OFF
    on_turn_on:
      - script.execute: set_circulation_state
    on_turn_off:
      - script.execute: set_circulation_state

  - platform: gpio
    pin: ${pin_relay6}
    name: "Relay #6"
    id: relay_6
    restore_mode: ALWAYS_OFF
    internal: true

  - platform: gpio
    pin: ${pin_relay7}
    name: "Relay #7"
    id: relay_7
    restore_mode: ALWAYS_OFF
    internal: true

  - platform: gpio
    pin: ${pin_relay8}
    name: "Underfloor cirkulation"
    id: cirkulation_relay
    icon: mdi:pump
    restore_mode: RESTORE_DEFAULT_OFF
    on_turn_on:
      - delay: 5s  # Check pump do not run without open valve
      - script.execute: set_circulation_state
    on_turn_off:
      - switch.turn_off: valve_1
      - delay: 100ms
      - switch.turn_off: valve_2
      - delay: 100ms
      - switch.turn_off: valve_3
      - delay: 100ms
      - switch.turn_off: valve_4
      - delay: 100ms
      - switch.turn_off: valve_5

number:
  - platform: template
    name: Flow setting ${room1_name}
    id: flow_set_1
    unit_of_measurement: L/min
    restore_value: true
    step: 0.5
    min_value: 0
    max_value: 5
    mode: slider
    optimistic: true
    entity_category: config

  - platform: template
    name: Flow setting ${room2_name}
    id: flow_set_2
    unit_of_measurement: L/min
    restore_value: true
    step: 0.5
    min_value: 0
    max_value: 5
    mode: slider
    optimistic: true
    entity_category: config

  - platform: template
    name: Flow setting ${room3_name}
    id: flow_set_3
    unit_of_measurement: L/min
    restore_value: true
    step: 0.5
    min_value: 0
    max_value: 5
    mode: slider
    optimistic: true
    entity_category: config

  - platform: template
    name: Flow setting ${room4_name}
    id: flow_set_4
    unit_of_measurement: L/min
    restore_value: true
    step: 0.5
    min_value: 0
    max_value: 5
    mode: slider
    optimistic: true
    entity_category: config

  - platform: template
    name: Flow setting ${room5_name}
    id: flow_set_5
    unit_of_measurement: L/min
    restore_value: true
    step: 0.5
    min_value: 0
    max_value: 5
    mode: slider
    optimistic: true
    entity_category: config

sensor:
#   - platform: adc
#     pin: ${pin_adc}
#     id: water_pressure_adc
#     name: Water pressure ADC
#     attenuation: auto
#     unit_of_measurement: "v"
#     update_interval: 1s
#     entity_category: "diagnostic"

#   - platform: template
#     lambda: return id(water_pressure_adc).state;
#     name: Water pressure
#     id: water_pressure
#     unit_of_measurement: "bar"
#     icon: "mdi:water-sync"
#     device_class: "pressure"
#     state_class: "measurement"
#     accuracy_decimals: 2
#     update_interval: 1s
#     filters:
#       - calibrate_linear:
#         - 0.27     -> 0
#         - 0.60     -> 0.9
#         #- 3.11651  -> 10
#       - quantile:
#           window_size: 60
#           send_every: 10
#           quantile: 0.9
          
#   - platform: pulse_counter
#     # name: "Underfloor flow"
#     pin: ${pin_water_pulse}
#     id: water_flow_pulse
#     unit_of_measurement: L/min
#     icon: mdi:pump
#     update_interval: 1s
#     filters:
#     - lambda: return (x / 27.0) * 60.0;
#     - quantile:
#           window_size: 60
#           send_every: 10
#           quantile: 0.9

  - platform: pulse_meter
    pin:
      number: ${pin_water_pulse}
      # inverted: true
      # mode:
      #   input: true
      #   pullup: true
    id: water_flow
    name: Underfloor flow
    device_class: water
    entity_category: diagnostic
    timeout: 10s
    unit_of_measurement: L/min
    filters:
      - throttle_average: 10s
      - filter_out: nan
      - multiply: 0.037  # (27 pulses per liter)
      - multiply: 60.0   # (s to min)
    ### For debugging RAW sensor
    # unit_of_measurement: 'pulses/second'
    # filters:
    #   # - filter_out: 0.0
    #   - throttle_average: 2s
    #   - filter_out: nan
    #   - multiply: 0.0166666667
    ###

  - platform: template
    id: flow_set_combined
    lambda: |-
      float total = 0;
      if (id(valve_1).state) {
        total += id(flow_set_1).state;
      }
      if (id(valve_2).state) {
        total += id(flow_set_2).state;
      }
      if (id(valve_3).state) {
        total += id(flow_set_3).state;
      }
      if (id(valve_4).state) {
        total += id(flow_set_4).state;
      }
      if (id(valve_5).state) {
        total += id(flow_set_5).state;
      }
      return total;
    entity_category: diagnostic

  - platform: dallas
    address: ${incomming_temp_adress}
    name: Incomming water temp
    id: incomming_temp
    entity_category: diagnostic

  - platform: dallas
    address: ${room1_temp_adress}
    name: Return temp ${room1_name}
    id: return_temp_1
    entity_category: diagnostic

  - platform: dallas
    address: ${room2_temp_adress}
    name: Return temp ${room2_name}
    id: return_temp_2
    entity_category: diagnostic

  - platform: dallas
    address: ${room3_temp_adress}
    name: Return temp ${room3_name}
    id: return_temp_3
    entity_category: diagnostic

  - platform: dallas
    address: ${room4_temp_adress}
    name: Return temp ${room4_name}
    id: return_temp_4
    entity_category: diagnostic

  - platform: dallas
    address: ${room5_temp_adress}
    name: Return temp ${room5_name}
    id: return_temp_5
    entity_category: diagnostic

  - platform: template
    name: Energy ${room1_name}
    id: energy_1
    unit_of_measurement: W
    device_class: POWER
    icon: mdi:radiator
    lambda: |-
      if (! id(valve_1).state || id(flow_set_combined).state == 0.0) {
        return 0.0;
      }
      float flow = id(flow_set_1).state / id(flow_set_combined).state * id(water_flow).state;
      float temp_diff = id(incomming_temp).state - id(return_temp_1).state;
      return flow * temp_diff * 1000.0 * 4.184 / 60.0;

  - platform: template
    name: Energy ${room2_name}
    id: energy_2
    unit_of_measurement: W
    device_class: POWER
    icon: mdi:radiator
    lambda: |-
      if (! id(valve_2).state || id(flow_set_combined).state == 0.0) {
        return 0.0;
      }
      float flow = id(flow_set_2).state / id(flow_set_combined).state * id(water_flow).state;
      float temp_diff = id(incomming_temp).state - id(return_temp_2).state;
      return flow * temp_diff * 1000.0 * 4.184 / 60.0;

  - platform: template
    name: Energy ${room3_name}
    id: energy_3
    unit_of_measurement: W
    device_class: POWER
    icon: mdi:radiator
    lambda: |-
      if (! id(valve_3).state || id(flow_set_combined).state == 0.0) {
        return 0.0;
      }
      float flow = id(flow_set_3).state / id(flow_set_combined).state * id(water_flow).state;
      float temp_diff = id(incomming_temp).state - id(return_temp_3).state;
      return flow * temp_diff * 1000.0 * 4.184 / 60.0;

  - platform: template
    name: Energy ${room4_name}
    id: energy_4
    unit_of_measurement: W
    device_class: POWER
    icon: mdi:radiator
    lambda: |-
      if (! id(valve_4).state || id(flow_set_combined).state == 0.0) {
        return 0.0;
      }
      float flow = id(flow_set_4).state / id(flow_set_combined).state * id(water_flow).state;
      float temp_diff = id(incomming_temp).state - id(return_temp_4).state;
      return flow * temp_diff * 1000.0 * 4.184 / 60.0;

  - platform: template
    name: Energy ${room5_name}
    id: energy_5
    unit_of_measurement: W
    device_class: POWER
    icon: mdi:radiator
    lambda: |-
      if (! id(valve_5).state || id(flow_set_combined).state == 0.0) {
        return 0.0;
      }
      float flow = id(flow_set_5).state / id(flow_set_combined).state * id(water_flow).state;
      float temp_diff = id(incomming_temp).state - id(return_temp_5).state;
      return flow * temp_diff * 1000.0 * 4.184 / 60.0;

text_sensor:
  - platform: homeassistant
    name: Heating status text ${room1_name}
    id: heat_status_text_1
    entity_id: ${room1_thermostat}
    attribute: hvac_action
    filters:
      - lambda: |-
          if (x == "heating") {
            id(valve_1).turn_on();
          } else {
            id(valve_1).turn_off();
          }
          return x;
    internal: true

  - platform: homeassistant
    name: Heating status text ${room2_name}
    id: heat_status_text_2
    entity_id: ${room2_thermostat}
    attribute: hvac_action
    filters:
      - lambda: |-
          if (x == "heating") {
            id(valve_2).turn_on();
          } else {
            id(valve_2).turn_off();
          }
          return x;
    internal: true

  - platform: homeassistant
    name: Heating status text ${room3_name}
    id: heat_status_text_3
    entity_id: ${room3_thermostat}
    attribute: hvac_action
    filters:
      - lambda: |-
          if (x == "heating") {
            id(valve_3).turn_on();
          } else {
            id(valve_3).turn_off();
          }
          return x;
    internal: true

  - platform: homeassistant
    name: Heating status text ${room4_name}
    id: heat_status_text_4
    entity_id: ${room4_thermostat}
    attribute: hvac_action
    filters:
      - lambda: |-
          if (x == "heating") {
            id(valve_4).turn_on();
          } else {
            id(valve_4).turn_off();
          }
          return x;
    internal: true

  - platform: homeassistant
    name: Heating status text ${room5_name}
    id: heat_status_text_5
    entity_id: ${room5_thermostat}
    attribute: hvac_action
    filters:
      - lambda: |-
          if (x == "heating") {
            id(valve_5).turn_on();
          } else {
            id(valve_5).turn_off();
          }
          return x;
    internal: true

Great examples!

I have the same solution, but got tired of the ticks of the relays, since my actuators are 24VDC I switched to an esp 12F home made PCB (versions like this can be bought on aliexpress)

To control the outputs I use a MCP23017 I2C I/O multiplier
The same PCB controls LED lighting in my basement, with an 16 ch relay board with it’s own I/O multiplier.

I chose to make the outputs for the actuator a dimmable light, så I send a % to that “light” from node-red where I have a PID-node for each room.

My system is also water based with a heatpump and large storage tank.

The latest PCB now running tests.

i2c:
  sda: 21
  scl: 22
#  scan: true

dallas:
  - pin: GPIO23
sensor:
  - platform: dallas
    address: 0xa2000007afc68828
    name: "Buffertank top temp"
    resolution: 10
  - platform: dallas
    address: 0xb1000004f50a8928
    name: "Buffertank bund temp"
    resolution: 10
  - platform: dallas
    address: 0xce00000688753928
    name: "WC_Floor_temp"
    resolution: 11
  - platform: dallas
    address: 0x6703139794468028
    name: "Basement_freezer_temp"
    resolution: 9
  - platform: dallas
    address: 0x58030994973f4328
    name: "Basement_refrigerator_temp"
    resolution: 9
  - platform: dallas
    address: 0x0103079794190828
    name: "CV_frem_ved_Pumpe"
    resolution: 10
  - platform: dallas
    address: 0x10000004f54b8e28
    name: "CV_retur_ved_Pumpe" 
    resolution: 10
  - platform: dallas
    address: 0xd5000007af66fc28
    name: "VV_cirkulation_temp" 
    resolution: 9

mcp23017:
  - id: 'Relays_chip'
    address: 0x20
  - id: 'Mosfet_chip'
    address: 0x21



output:
  - platform: gpio
    id: "Relay_00"
    pin:
      mcp23xxx: Relays_chip
      number: 0
      mode:
        output: true
      inverted: True
  - platform: gpio
    id: "Relay_01"
    pin:
      mcp23xxx: Relays_chip
      number: 1
      mode:
        output: true
      inverted: True
  - platform: gpio
    id: "Relay_02"
    pin:
      mcp23xxx: Relays_chip
      number: 2
      mode:
        output: true
      inverted: True
  - platform: gpio
    id: "Relay_03"
    pin:
      mcp23xxx: Relays_chip
      number: 3
      mode:
        output: true
      inverted: True
  - platform: gpio
    id: "Relay_04"
    pin:
      mcp23xxx: Relays_chip
      number: 4
      mode:
        output: true
      inverted: True
  - platform: gpio
    id: "Relay_05"
    pin:
      mcp23xxx: Relays_chip
      number: 5
      mode:
        output: true
      inverted: True
  - platform: gpio
    id: "Relay_06"
    pin:
      mcp23xxx: Relays_chip
      number: 6
      mode:
        output: true
      inverted: True
  - platform: gpio
    id: "Relay_07"
    pin:
      mcp23xxx: Relays_chip
      number: 7
      mode:
        output: true
      inverted: True
  - platform: gpio
    id: "Relay_08"
    pin:
      mcp23xxx: Relays_chip
      number: 8
      mode:
        output: true
      inverted: True
  - platform: gpio
    id: "Relay_09"
    pin:
      mcp23xxx: Relays_chip
      number: 9
      mode:
        output: true
      inverted: True
  - platform: gpio
    id: "Relay_10"
    pin:
      mcp23xxx: Relays_chip
      number: 10
      mode:
        output: true
      inverted: True
  - platform: gpio
    id: "Relay_11"
    pin:
      mcp23xxx: Relays_chip
      number: 11
      mode:
        output: true
      inverted: True
  - platform: gpio
    id: "Relay_12"
    pin:
      mcp23xxx: Relays_chip
      number: 12
      mode:
        output: true
      inverted: True
  - platform: gpio
    id: "Relay_13"
    pin:
      mcp23xxx: Relays_chip
      number: 13
      mode:
        output: true
      inverted: True
  - platform: gpio
    id: "Relay_14"
    pin:
      mcp23xxx: Relays_chip
      number: 14
      mode:
        output: true
      inverted: True
  - platform: gpio
    id: "Relay_15"
    pin:
      mcp23xxx: Relays_chip
      number: 15
      mode:
        output: true
      inverted: True
  - platform: slow_pwm
    period: ${PWM_period}
    id: "Mosfet_00"
    pin:
      mcp23xxx: Mosfet_chip
      number: 0
      mode:
        output: true
      inverted: false
  - platform: slow_pwm
    period: ${PWM_period}
    id: "Mosfet_01"
    pin:
      mcp23xxx: Mosfet_chip
      number: 1
      mode:
        output: true
      inverted: false
  - platform: slow_pwm
    period: ${PWM_period}
    id: "Mosfet_02"
    pin:
      mcp23xxx: Mosfet_chip
      number: 2
      mode:
        output: true
      inverted: false
  - platform: slow_pwm
    period: ${PWM_period}
    id: "Mosfet_03"
    pin:
      mcp23xxx: Mosfet_chip
      number: 3
      mode:
        output: true
      inverted: false
  - platform: slow_pwm
    period: ${PWM_period}
    id: "Mosfet_04"
    pin:
      mcp23xxx: Mosfet_chip
      number: 4
      mode:
        output: true
      inverted: false
  - platform: slow_pwm
    period: ${PWM_period}
    id: "Mosfet_05"
    pin:
      mcp23xxx: Mosfet_chip
      number: 5
      mode:
        output: true
      inverted: false
  - platform: slow_pwm
    period: ${PWM_period}
    id: "Mosfet_06"
    pin:
      mcp23xxx: Mosfet_chip
      number: 6
      mode:
        output: true
      inverted: false
  - platform: slow_pwm
    period: ${PWM_period}
    id: "Mosfet_07"
    pin:
      mcp23xxx: Mosfet_chip
      number: 7
      mode:
        output: true
      inverted: false
  - platform: slow_pwm
    period: ${PWM_period}
    id: "Mosfet_08"
    pin:
      mcp23xxx: Mosfet_chip
      number: 8
      mode:
        output: true
      inverted: false
  - platform: slow_pwm
    period: ${PWM_period}
    id: "Mosfet_09"
    pin:
      mcp23xxx: Mosfet_chip
      number: 9
      mode:
        output: true
      inverted: false
  - platform: slow_pwm
    period: ${PWM_period}
    id: "Mosfet_10"
    pin:
      mcp23xxx: Mosfet_chip
      number: 10
      mode:
        output: true
      inverted: false
  - platform: slow_pwm
    period: ${PWM_period}
    id: "Mosfet_11"
    pin:
      mcp23xxx: Mosfet_chip
      number: 11
      mode:
        output: true
      inverted: false
  - platform: slow_pwm
    period: ${PWM_period}
    id: "Mosfet_12"
    pin:
      mcp23xxx: Mosfet_chip
      number: 12
      mode:
        output: true
      inverted: false
  - platform: slow_pwm
    period: ${PWM_period}
    id: "Mosfet_13"
    pin:
      mcp23xxx: Mosfet_chip
      number: 13
      mode:
        output: true
      inverted: false
  - platform: slow_pwm
    period: ${PWM_period}
    id: "Mosfet_14"
    pin:
      mcp23xxx: Mosfet_chip
      number: 14
      mode:
        output: true
      inverted: false
  - platform: slow_pwm
    period: ${PWM_period}
    id: "Mosfet_15"
    pin:
      mcp23xxx: Mosfet_chip
      number: 15
      mode:
        output: true
      inverted: false


light:
  - platform: binary
    output: Relay_00
    name: "Relay_0"
  - platform: binary
    output: Relay_01
    name: "Relay_01"
  - platform: binary
    output: Relay_02
    name: "Relay_02"
  - platform: binary
    output: Relay_03
    name: "Relay_03"
  - platform: binary
    output: Relay_04
    name: "Relay_04"
  - platform: binary
    output: Relay_05
    name: "Relay_05"
  - platform: binary
    output: Relay_06
    name: "Relay_06"
  - platform: binary
    output: Relay_07
    name: "Relay_07"
  - platform: binary
    output: Relay_08
    name: "Relay_08"
  - platform: binary
    output: Relay_09
    name: "Relay_09"
  - platform: binary
    output: Relay_10
    name: "Relay_10"
  - platform: binary
    output: Relay_11
    name: "Relay_11"
  - platform: binary
    output: Relay_12
    name: "Relay_12"
  - platform: binary
    output: Relay_13
    name: "Relay_13"
  - platform: binary
    output: Relay_14
    name: "Relay_14"
  - platform: binary
    output: Relay_15
    name: "Relay_15"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_00
    name: "Mosfet_00"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_01
    name: "Mosfet_01"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_02
    name: "Mosfet_02"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_02
    name: "Mosfet_02"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_03
    name: "Mosfet_03"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_04
    name: "Mosfet_04"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_05
    name: "Mosfet_05"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_06
    name: "Mosfet_06"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_07
    name: "Mosfet_07"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_08
    name: "Mosfet_08"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_09
    name: "Mosfet_09"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_10
    name: "Mosfet_10"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_11
    name: "Mosfet_11"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_12
    name: "Mosfet_12"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_13
    name: "Mosfet_13"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_14
    name: "Mosfet_14"
  - platform: monochromatic
    gamma_correct: 1
    output: Mosfet_15
    name: "Mosfet_15"

1 Like

Besides annoying ticks the mechanical relays have more disadvantages: they are prone to wear and tear, contact erosion, and mechanical failures. For our home I have developed my own electronics, because I was not satisfied with other existing solutions. It 's more or less a raspberry pi 5 with NVMe SDD running a Home Assistant server with a lot of floor-heating related IO, but you can also plug in a W32-ETH01 board. As I expect that more people will like my approach, I decided to create a crowdsupply project for it. You can find it here.

1 Like