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?