Itho daalderop HRU 400 modbus ESPhome

Hi All,

As a few others have attempted here:
https://gathering.tweakers.net/forum/list_messages/1976492/0
and here:

I also have a HRU 400, but without any fancy zones or whatever so the config will need adjusting!

The Manual can be found here:

(page 31 or section 6.2 if you want to help along :slight_smile: )

Generic modbus question:

For some reason I cannot get 40101 till 40104 (or 100 till 103) not to display any form of logical serial number that matches the serial number of the device. How would you go about reading these modbus values

HRU specific question:

As I do not have any fancy zones on the unit so I would need to play with these values to set the fan on / off:

register 42012 (2011) 0 seems to be the auto mode? and 1 seems to be set the fan to the value 1-399 where 399 is max cap. (register 2010) I dont see the logic here, also there is “ask for ventilation inlet” and “ask for ventilation outlet” which seem to do the same thing so not sure if you need to set them the same at the same time?

Thanks in advance for the help :slight_smile:

1 Like

Did you ever figure this out?

I have the same setup: HRU400 w/o zones, connected via modbus.

I would like to control the ventilation level via home assistant, did you succeed?

Thanks

Hey,

I sure did, its working great!
Even have a fan tile for the WTW.

The only down side is, if you control the WTW trough HA the external remotes no longer work.
This is a limitation in the firmware of the HRU400…

Added a bypas setting for the HRU 400:

###
# Bypass
###
  # 0 = down 
  # 550 = open
  # Inside air is directed to the ourside without passing the heat exchanger
  # Thus cold outside air does not heat up from the hot inside air
  # Must be used with override mode to max 200 out of 399.. The unit should do this automatically...
  - platform: modbus_controller
    modbus_controller_id: hru
    name: "Bypass valve - on/off" # 0 = auto 1 = Manual
    id: HRU_bypass_valve_on_off
    register_type: holding
    address: 2033
    min_value: 0
    max_value: 1
    step: 1
    use_write_multiple: true
    icon: mdi:toggle-switch-variant

This still needs a automation in code that it also turns on your fan into manual mode and set it to 199 :slight_smile:

With:

    on_value_range:
      - above: 0.5
        then: 
          - number.set:
              id: HRU_fan_demand_value
              value: 199
      - below: 0.5
        then:
          - number.set:
              id: HRU_fan_demand_value
              value: 0.0

It will turn the above code into an actual functioning bypass valve :slight_smile:

I you stumble upon this conversation.
Currently all code / control can be found here:

i was wondering if someone could help me out. I have an HRU400 with an ESP32S2 mini connected to the HRU via RS485-modbus. the connection works, i can control everything but i have an annoying error. Whenever i have a sequence of addresses in the yaml it all works e.g. 2021, 2022, 2023.
image

but whenever i have a gap in the addresses e.g. 2021, 2022, 2023, 2034 everything is messed up. values will be mixed from 1 address to the other and random changes in values will occur.

image
as you can see, the “outside air fan” got he value 550 which is the value of the bypass valve. the outside air fan has a range of 0-399 so it can never be 550.

here is my yaml:

esphome:
  name: itho-hru
  friendly_name: itho-hru

esp32:
  board: lolin_s2_mini
  variant: esp32s2
  framework:
    type: arduino
#    version: 2.0.6
#    platform_version: 5.3.0

logger:
  level: DEBUG
  baud_rate: 0

# Enable Home Assistant API
api:
  encryption:
    key: "xxxxx"

ota:
  - platform: esphome
    password: "xxxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Itho-Hru Fallback Hotspot"
    password: "f0xSaMbuxcSi"

captive_portal:

web_server:
  port: 80

light:
  - platform: status_led
    name: "Status LED"
    id: HRU_status_led
    icon: "mdi:alarm-light"
#    restore_mode: ALWAYS_OFF
    pin:
      number: GPIO15
      inverted: false

modbus:
  id: modbus_hru
  flow_control_pin: GPIO7
  uart_id: uart_modbus_hru
  #send_wait_time: 2000ms

uart:
  - id: uart_modbus_hru
    tx_pin: GPIO11 # should be GPIO11, cannot be swapped
    rx_pin: GPIO9 # should be GPIO9, cannot be swapped
    baud_rate: 19200 # should be 19200, 9600=no difference, 38400=no difference
    parity: EVEN #should be EVEN, ODD=no difference, NONE=does not work
    data_bits: 8
    stop_bits: 1
  
modbus_controller:
  - id: hru
    address: 0x49 #   original: 72 = 0x48, 73 = 0x49
    modbus_id: modbus_hru
    update_interval: 5s
    setup_priority: -10
    command_throttle: 200ms
    offline_skip_updates: 100

substitutions:
  skip_updates: "5"
  skip_updates_errors: "10"
  skip_updates_advanced: "100"
  modbus_id: hru
  max_cap: "399"
  flap_max: "550"
  alert_icon: mdi:alert-circle
  max_error_number: "5"
  fan_speed_1: "100"
  fan_speed_2: "150"
  fan_speed_3: "200"
  fan_speed_4: "250"
  fan_speed_5: "300"
  fan_speed_6: "350"
  fan_speed_7: "399"

# packages:
  # remote_package:
    # url: https://github.com/william-sy/esphome-Itho-Daalderop-HRU400
    # ref: main
    # refresh: 0s
    # files: [
      # # Step 1: Choose a language:
      # esphome/i18n/EN.yaml,
      # #esphome/i18n/NL.yaml,
      # # Step 2: Choose the board you bought:
      # #esphome/boards/board-esp32-atom-lite.yaml,
      # #esphome/boards/board-esp32-atom-s3-lite.yaml,
      # # Step 4: Configure the general stuff:
      # #esphome/base/base.yaml,
      # esphome/base/fan.yaml,
      # #esphome/base/select.yaml,
      # #esphome/base/bypass.yaml,
      # #esphome/base/frostvalve.yaml,
      # #esphome/base/advanced.yaml,
      # #esphome/base/faultcodes.yaml,
      # # Add a comma here if you enable zones:
      # #esphome/base/general.yaml
      # # Step 5: Enable aditional zones if you have them:
      # #esphome/zones/zone_1.yaml,
      # #esphome/zones/zone_2.yaml,
      # #esphome/zones/zone_3.yaml,
      # #esphome/zones/zone_4.yaml,
      # # Step 6: Dont forget to remove the last comma

number:
  - name: outside air fan demand value 
    platform: modbus_controller
    modbus_controller_id: hru
    id: outside_air_fan_demand_value
    icon: mdi:home-import-outline
    register_type: holding
    address: 0x7DA #2021
    min_value: 0
    max_value: 399
    step: 1
    #initial_value: 0
    value_type: U_WORD
  #   use_write_multiple: true
  # #   # on_value_range:
  #     # - above: 2.0
  #       # then: 
  #         # - number.set:
  #             # id: fan_demand_on_off
  #             # value: 1.0
  #     # - below: 1.0
  #       # then:
  #         # - number.set:
  #             # id: fan_demand_on_off
  #             # value: 0.0
  - name: Bypass position
    id: bypass_position
    address: 0x7F0 #2032
    #value_type: U_WORD
    min_value: 0
    max_value: ${flap_max}
    step: 50
    #initial_value: 0
    register_type: holding
    platform: modbus_controller
    use_write_multiple: true
    modbus_controller_id: ${modbus_id}
    icon: mdi:valve
  - name: Bypass manual control on/off
    address: 0x7F1 #2033
    id: bypass_valve_manual_control_on_off
    #value_type: U_WORD
    min_value: 0
    max_value: 1
    step: 1
    #initial_value: 0
    register_type: holding
    platform: modbus_controller
    modbus_controller_id: ${modbus_id}
    use_write_multiple: true
    icon: mdi:toggle-switch-variant

the yaml above is with address gaps. you can see 2021, 2032 and 2033. then it goes wrong. whenever i comment out the 2021, the addresses are sequencial and the entities work again.

does anyone know how to solve this “gap” problem?

Use this:
send_wait_time: 500ms

With gaps you may need disable this:
use_write_multiple: true

Don’t use skip_updates it don’t work (still have bug?) and cause problems.

I only used modbus and number on this:

[[easyhan/esphome/t44-x04-soil.yaml at bf66f7420093fae44a5c152d52807c5a43550bc4 · nikito7/easyhan · GitHub]]