Aqotec RM360 over Modbus, Part 3: Safe Writes and Automations

Safe RM360 write automations for Home Assistant: mode selection, float32 offsets, value bounds, and no startup write storms.

Share
Aqotec RM360 over Modbus, Part 3: Safe Writes and Automations

After read-only sensors and a safe energy counter, the next step is controlled writes.

The important rule: write only when the user changes something. Do not write on every Home Assistant start and do not mirror sensors back into registers.

This part covers regular setpoints and operating-mode writes. External room temperature is slightly different because it is intentionally periodic; I split that into Part 4.

Heating circuit 2 mode

For my RM360, heating circuit 2 uses register 41197.

The mode mapping is:

Mode Register value
Auto 0
Day 1
Night setback 2
Party 3
Off / frost protection 4

A small input_select is enough for the UI:

input_select:
  rm360_hc2_mode_set:
    name: "RM360 HC2 Mode"
    options:
      - "Auto"
      - "Day"
      - "Night"
      - "Party"
      - "Off"

And the automation writes only after a real user-side state change:

- id: rm360_hc2_mode_write
  alias: RM360 HC2 Mode Write
  mode: restart
  triggers:
    - trigger: state
      entity_id: input_select.rm360_hc2_mode_set
  conditions:
    - condition: template
      value_template: >
        {{
          trigger.from_state is not none
          and trigger.from_state.state not in ['unknown', 'unavailable']
          and trigger.to_state is not none
          and trigger.to_state.state != trigger.from_state.state
        }}
  actions:
    - delay: "00:00:01"
    - action: modbus.write_register
      data:
        hub: rm360
        slave: 1
        address: 41197
        value: >
          {% set m = {
            'Auto': 0,
            'Day': 1,
            'Night': 2,
            'Party': 3,
            'Off': 4
          } %}
          {{ m[states('input_select.rm360_hc2_mode_set')] | int }}

Float32 correction values

Some RM360 values are float32, which means two 16-bit registers must be written as one Modbus FC16 operation.

Example for a day correction value:

- id: rm360_day_offset_write
  alias: RM360 Day Offset Write
  mode: restart
  triggers:
    - trigger: state
      entity_id: input_number.rm360_day_offset_set
  conditions:
    - condition: template
      value_template: >
        {% set value = trigger.to_state.state | float(none) %}
        {{
          trigger.from_state is not none
          and trigger.from_state.state not in ['unknown', 'unavailable', 'none', '']
          and value is not none
          and -4.0 <= value <= 4.0
          and trigger.to_state.state != trigger.from_state.state
        }}
  actions:
    - delay: "00:00:02"
    - action: modbus.write_register
      data:
        hub: rm360
        slave: 1
        address: 41214
        value: >
          {% set value = states('input_number.rm360_day_offset_set') | float %}
          {% set raw = value | pack(">f") %}
          {{ [unpack(raw, ">H", offset=0), unpack(raw, ">H", offset=2)] }}

The same pattern works for the night correction and for heating-circuit-specific offsets. Adjust the register and value range, but keep the guardrails.

Final checks before regular write automations

Before enabling write automations:

  • verify every register against the controller documentation
  • keep the first write small and reversible
  • check the RM360 display after each first write
  • avoid writing during Home Assistant startup
  • keep read sensors and write helpers separate

The remaining special case is the external room temperature for heating circuit 2. That needs both Home Assistant automation and manual RM360 service-menu configuration, so it gets its own Part 4.


Series navigation

Previous step: Aqotec RM360 over Modbus, Part 2: The Energy Counter Workaround

Next step: Aqotec RM360 over Modbus, Part 4: External Room Temperature for HC2