Template Climate Action Modbus Not Work

Hi everyone I have fancoils that can be managed via modbus but i cannot use standard modbus integration from home assistant to set climate devices because i have to read/write single bits of some registers to read/set actions. In particular we have:

  • reg 0 : current temperature (r)
  • reg 201 : target_temperature (r/w)
  • reg 233 : operation mode: heat (3) / cool (5)
  • reg 201 - bit 1,2,3 : fan mode (auto 000/ min 001 / night 010 / max 011)
  • reg 201 - bit 8 : stand-by on/off

So for example if I need to set fan mode to “night” without touch the other bits i need to: get current value from register 201, set bit 1 and 3 to “0” and finally set bit 2 to “1”. Translating to a template we have:
{{ states('sensor.fc_soggiorno_prg') | int | bitwise_and(65530) | bitwise_or(2) }}

In order to do that I have created modbus sensor and template_binary_sensors that read info from fancoils and custom_components from jcwillox-hass-template-climate to create template_climate_entities. The .yaml configurations are like so:

configuration.yaml

# riello fancoils (modbus RS485 network)
modbus:
  - name: "fancoil_hub"
    port: /dev/ttyUSB0
    type: serial
    method: rtu
    baudrate: 9600
    bytesize: 8
    stopbits: 1
    parity: N

    sensors:  !include_dir_merge_list fancoil_hub/modbus_sensors/
    climates: !include fancoil_hub/modbus_climate.yaml

template:
  - binary_sensor: !include_dir_merge_list fancoil_hub/template_binary_sensors
  
climate: !include_dir_merge_list fancoil_hub/template_climates

modbus_sensors

# FANCOIL SOGGIORNO - MODBUS SENSORS
# ----------------------------------

# TEMPERATURA ARIA
# Temperatura Aria AIR {R}
- name: "fc_soggiorno_t1"
  unique_id: "v1_T1"
  slave: 2
  scan_interval: 15
  scale: 0.1
  precision: 1
  min_value: 0
  max_value: 100
  device_class: temperature
  state_class: measurement
  unit_of_measurement: °C
  address: 0

### and so on for the other registers ....  ###

template_binary_sensors

# FANCOIL SOGGIORNO - BINARY SENSORS
# ----------------------------------

# FLAG CONFIGURAZIONE {R/W}
# Modalità Stand-By
- name: "fc_soggiorno_mod_stdby"
  unique_id: "v1_MOD_STDBY"
  state: "{{ states('sensor.fc_soggiorno_prg')|int|bitwise_and(128) > 0 }}"
# Blocco Tastiera
- name: "fc_soggiorno_key_lock"
  unique_id: "v1_KEY_LOCK"
  state: "{{ states('sensor.fc_soggiorno_prg')|int|bitwise_and(16) > 0 }}"
# Modo Ventilatore: AUTO
- name: "fc_soggiorno_mod_auto"
  unique_id: "v1_MOD_AUTO"
  state: "{{ states('sensor.fc_soggiorno_prg')|int|bitwise_and(7) == 0 }}"
# Modo Ventilatore: MIN
- name: "fc_soggiorno_mod_min"
  unique_id: "v1_MOD_MIN"
  state: "{{ states('sensor.fc_soggiorno_prg')|int|bitwise_and(7) == 1 }}"
# Modo Ventilatore: NOTTE
- name: "fc_soggiorno_mod_notte"
  unique_id: "v1_MNOTTE"
  state: "{{ states('sensor.fc_soggiorno_prg')|int|bitwise_and(7) == 2 }}"
# Modo Ventilatore: MAX
- name: "fc_soggiorno_mod_max"
  unique_id: "v1_MOD_MAX"
  state: "{{ states('sensor.fc_soggiorno_prg')|int|bitwise_and(7) == 3 }}"

#  ... and so on for the others ....  #

template_climate:

- platform: climate_template
  name: Soggiorno
  unique_id: v1_climate_template
  min_temp: 16
  max_temp: 28
  precision: 0.1
  temp_step: 0.5
  swing_modes:
    - "on"
    - "off"
  modes:
    - "heat"
    - "cool"
  fan_modes:
    - "auto"
    - "low"
    - "medium"
    - "high"

  availability_template: "{{is_state('binary_sensor.fc_soggiorno_com_err','off')}}"

  current_temperature_template: "{{states('sensor.fc_soggiorno_t1')}}"
  target_temperature_template: "{{states('sensor.fc_soggiorno_sp')}}"

  swing_mode_template: "{{iif(is_state('binary_sensor.fc_soggiorno_stdby','off'), 'on', 'off')}}"

  hvac_mode_template: "{{iif(is_state('sensor.fc_soggiorno_man','3'), 'heat', 'cool')}}"

  hvac_action_template: >
    {% if is_state('binary_sensor.fc_soggiorno_mod_raff','on') %}
    heating
    {% elif is_state('binary_sensor.fc_soggiorno_mod_risc','on') %}
    cooling
    {% else %}
    idle
    {% endif %}

  fan_mode_template: >
    {% if is_state('binary_sensor.fc_soggiorno_mod_auto','on') %}
    auto
    {% elif is_state('binary_sensor.fc_soggiorno_mod_notte','on') %}
    low
    {% elif is_state('binary_sensor.fc_soggiorno_mod_min','on') %}
    medium
    {% else %}
    max
    {% endif %}


  set_temperature:
    - service: modbus.write_register
      data:
        hub: fancoil_hub
        slave: 2
        address: 231
        value: "{{ state_attr('climate.soggiorno', 'temperature') | int * 10}}"

  set_hvac_mode:
    - service: modbus.write_register
      data:
        hub: fancoil_hub
        slave: 2
        address: 233
        value: "{{iif(is_state('climate.soggiorno','heat'), 3, 5) | int }}"

  set_fan_mode:
    - service: modbus.write_register
      data:
        hub: fancoil_hub
        slave: 2
        address: 201
        value: >
          {% if is_state_attr('climate.soggiorno','fan_mode', 'auto') %}
          {{ states('sensor.fc_soggiorno_prg') | int | bitwise_and(65528) }}
          {% elif is_state_attr('climate.soggiorno','fan_mode', 'low') %}
          {{ states('sensor.fc_soggiorno_prg') | int | bitwise_and(65530) | bitwise_or(2) }}
          {% elif is_state_attr('climate.soggiorno','fan_mode', 'medium') %}
          {{ states('sensor.fc_soggiorno_prg') | int | bitwise_and(65529) | bitwise_or(1) }}
          {% else %}
          {{ states('sensor.fc_soggiorno_prg') | int | bitwise_and(65531) | bitwise_or(3) }}
          {% endif %}

  set_swing_mode:
    - service: modbus.write_register
      data:
        hub: fancoil_hub
        slave: 2
        address: 201
        value: >
          {% if is_state_attr('climate.soggiorno','swing_mode', 'on') %}
          {{ states('sensor.fc_soggiorno_prg') | int | bitwise_or(128) }}
          {% else %}
          {{ states('sensor.fc_soggiorno_prg') | int | bitwise_and(65407) }}
          {% endif %}

The problem is that i cannot do any action with the climate_template entity. All values are read in the correct way and if i change register values via command-line with modpoll changes are reflected correctly but if I try to set something from the template_climate entity nothing happens and the original value is restored.

If I try to run modbus_write_register services alone in the home assistant developer tab they work.

In the logs i get the following:
[homeassistant.helpers.script.soggiorno] Soggiorno: Running script requires passing in a context

I miss something but i cannot figure out what’s wrong… Can someone tell me what’s wrong?

1 Like

The climate_template is a custom component. Perhaps post the question / issue in that repo?

Thank you. I have already open an issue.

The climate_template custom component seems to me the perfect way to achieve my goal to have a climate component fully functional (with temperature, fan modes and operation mode) with the possibility of doing bitwise operation on modbus registers as i need.

The standard modbus climate component doesn’t allow me to do that or am i missing something?

Do you know other ways of having a climate component fully functional but with the possibility to do bitwise operation on the registers before reading/writing them?