Hello everyone!
I want to tell how I connected the industrial I/O module MU210-403 from OWEN to the Home Assistant. Using the modbus tcp protocol.
The 24 outputs of the module are controlled by a single bitmask, which looks like 0000 0000 0000 0000 0000 0000. Asynchronous recording of output states is not suitable.
Input Output Module Parameters
Name of the parameter | Parameter Value | Data type |
---|---|---|
address of the status record | 470 | Unsigned 32 |
state reading address | 468 | Unsigned 32 |
My config folder structure:
config/
├──command_line/
│ └── mu210_403_comand_line.yaml
├── python_scripts/
│ └── bit_mask_modbus.py
├── sensors/
│ └── mu210_403_status_output.yaml
├── switches/
│ └── mu210_403_switches.yaml
└── configuration.yaml
Actions:
- Install the python “pymodbus.client” module
- Connect folders in the file “configuration.yaml” and add commands
Summary
sensor: !include_dir_merge_list sensors/
switch: !include_dir_merge_list switches/
command_line: !include_dir_merge_list command_line/
shell_command:
mu210_403_set_bit: "python3 /config/python_scripts/bit_mask_modbus.py u32 192.168.77.5 502 1 470 write {{ bit }} {{ value }}"
change the data “192.168.77.5 502” to your IP and port
3. Creating a “yaml” file in the “command_line” folder
Summary
- sensor:
name: mu210_403_bit_mask
command: "python3 /config/python_scripts/bit_mask_modbus.py u32 192.168.77.5 502 1 468 read | grep 'dec:' | sed -E 's/.*\\(dec: ([0-9]+)\\).*/\\1/'"
scan_interval: 2
value_template: "{{ value | int(0) }}"
change the data “192.168.77.5 502” to your IP and port
- Create a file in the “python_scripts” folder “bit_mask_modbus.py”. The script is universal and can read and write data like u8 u16 u32 u64. Tested on u16 and u32
Summary
import sys
import time
from pymodbus.client import ModbusTcpClient
def usage():
print("Usage:")
print(" python3 mu_bitmask.py <type> <ip> <port> <slave_id> <address> read")
print(" python3 mu_bitmask.py <type> <ip> <port> <slave_id> <address> write <bit> <value>")
print(" <type> - u8, u16, u32, u64")
print(" <bit> - 1..8 (u8), 1..16 (u16), 1..32 (u32), 1..64 (u64)")
print(" <value> - 0 or 1")
sys.exit(1)
if len(sys.argv) < 7:
usage()
mask_type = sys.argv[1]
ip = sys.argv[2]
port = int(sys.argv[3])
slave_id = int(sys.argv[4])
address = int(sys.argv[5])
action = sys.argv[6]
if mask_type not in ("u8", "u16", "u32", "u64"):
usage()
if mask_type == "u8":
reg_count = 1
bit_max = 8
mask_fmt = "{:08b}"
elif mask_type == "u16":
reg_count = 1
bit_max = 16
mask_fmt = "{:016b}"
elif mask_type == "u32":
reg_count = 2
bit_max = 32
mask_fmt = "{:032b}"
elif mask_type == "u64":
reg_count = 4
bit_max = 64
mask_fmt = "{:064b}"
client = ModbusTcpClient(ip, port=port)
client.connect()
time.sleep(0.3)
try:
rr = client.read_holding_registers(address=address, count=reg_count, slave=slave_id)
if rr.isError():
print("Read error")
sys.exit(2)
if mask_type == "u8":
reg_val = rr.registers[0]
mask = reg_val & 0xFF
elif mask_type == "u16":
mask = rr.registers[0]
elif mask_type == "u32":
mask = (rr.registers[1] << 16) | rr.registers[0]
elif mask_type == "u64":
mask = (
(rr.registers[3] << 48)
| (rr.registers[2] << 32)
| (rr.registers[1] << 16)
| rr.registers[0]
)
if action == "read":
print(f"Current mask: {mask_fmt.format(mask)} (dec: {mask})")
for i in range(bit_max):
print(f"Bit {i+1}: {(mask >> i) & 1}")
elif action == "write":
if len(sys.argv) != 9:
usage()
bit = int(sys.argv[7])
value = int(sys.argv[8])
if not (1 <= bit <= bit_max) or value not in (0, 1):
usage()
if value:
mask |= (1 << (bit - 1))
else:
mask &= ~(1 << (bit - 1))
if mask_type == "u8":
# Сохраняем старшие 8 бит регистра
new_reg_val = (reg_val & 0xFF00) | (mask & 0xFF)
values = [new_reg_val]
elif mask_type == "u16":
values = [mask]
elif mask_type == "u32":
low = mask & 0xFFFF
high = (mask >> 16) & 0xFFFF
values = [low, high]
elif mask_type == "u64":
regs = [
mask & 0xFFFF,
(mask >> 16) & 0xFFFF,
(mask >> 32) & 0xFFFF,
(mask >> 48) & 0xFFFF,
]
values = regs
rq = client.write_registers(address=address, values=values, slave=slave_id)
if rq.isError():
print("Write error")
sys.exit(3)
print(f"Bit {bit} set to {value}. New mask: {mask_fmt.format(mask)} (dec: {mask})")
else:
usage()
finally:
client.close()
- Creating a “yaml” file in the “sensors” folder (these are my configurations, so outputs 19-24 are inverted).
Summary
- platform: template
sensors:
mu210_403_output_1_state:
unique_id: "mu210_403_output_1_state"
friendly_name: "Ванная свет состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(1) %}
on
{% else %}
off
{% endif %}
mu210_403_output_2_state:
unique_id: "mu210_403_output_2_state"
friendly_name: "Ванная подсветка состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(2) %}
on
{% else %}
off
{% endif %}
mu210_403_output_3_state:
unique_id: "mu210_403_output_3_state"
friendly_name: "Прихожая свет состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(4) %}
on
{% else %}
off
{% endif %}
mu210_403_output_4_state:
unique_id: "mu210_403_output_4_state"
friendly_name: "Гардероб свет состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(8) %}
on
{% else %}
off
{% endif %}
mu210_403_output_5_state:
unique_id: "mu210_403_output_5_state"
friendly_name: "Коридор подсветка состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(16) %}
on
{% else %}
off
{% endif %}
mu210_403_output_6_state:
unique_id: "mu210_403_output_6_state"
friendly_name: "Коридор свет состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(32) %}
on
{% else %}
off
{% endif %}
mu210_403_output_7_state:
unique_id: "mu210_403_output_7_state"
friendly_name: "Спальня первый свет состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(64) %}
on
{% else %}
off
{% endif %}
mu210_403_output_8_state:
unique_id: "mu210_403_output_8_state"
friendly_name: "Спальня второй свет состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(128) %}
on
{% else %}
off
{% endif %}
mu210_403_output_9_state:
unique_id: "mu210_403_output_9_state"
friendly_name: "Спальня левый светильник состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(256) %}
on
{% else %}
off
{% endif %}
mu210_403_output_10_state:
unique_id: "mu210_403_output_10_state"
friendly_name: "Спальня левый правый состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(512) %}
on
{% else %}
off
{% endif %}
mu210_403_output_11_state:
unique_id: "mu210_403_output_11_state"
friendly_name: "Тулет свет состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(1024) %}
on
{% else %}
off
{% endif %}
mu210_403_output_12_state:
unique_id: "mu210_403_output_12_state"
friendly_name: "Туалет подсветка состояние: "
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(2048) %}
on
{% else %}
off
{% endif %}
mu210_403_output_13_state:
unique_id: "mu210_403_output_13_state"
friendly_name: "Кухня свет состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(4096) %}
on
{% else %}
off
{% endif %}
mu210_403_output_14_state:
unique_id: "mu210_403_output_14_state"
friendly_name: "Кабинен первый свет состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(8192) %}
on
{% else %}
off
{% endif %}
mu210_403_output_15_state:
unique_id: "mu210_403_output_15_state"
friendly_name: "Кабинен второй свет состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(16384) %}
on
{% else %}
off
{% endif %}
mu210_403_output_16_state:
unique_id: "mu210_403_output_16_state"
friendly_name: "Гостиная первый свет состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(32768) %}
on
{% else %}
off
{% endif %}
mu210_403_output_17_state:
unique_id: "mu210_403_output_17_state"
friendly_name: "Гостиная второй свет состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(65536) %}
on
{% else %}
off
{% endif %}
mu210_403_output_18_state:
unique_id: "mu210_403_output_18_state"
friendly_name: "Гостиная подсветка свет состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0))|bitwise_and(131072) %}
on
{% else %}
off
{% endif %}
mu210_403_output_19_state:
unique_id: "mu210_403_output_19_state"
friendly_name: "Вытяжка состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0) | bitwise_and(262144)) == 0 %}
on
{% else %}
off
{% endif %}
mu210_403_output_20_state:
unique_id: "mu210_403_output_20_state"
friendly_name: "Спальня вентилятор конвектора состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0)) | bitwise_and(524288) == 0 %}
on
{% else %}
off
{% endif %}
mu210_403_output_21_state:
unique_id: "mu210_403_output_21_state"
friendly_name: "Спальня и гардероб розетки состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0)) | bitwise_and(1048576) == 0 %}
on
{% else %}
off
{% endif %}
mu210_403_output_22_state:
unique_id: "mu210_403_output_22_state"
friendly_name: "Балкон розетки состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0)) | bitwise_and(2097152) == 0 %}
on
{% else %}
off
{% endif %}
mu210_403_output_23_state:
unique_id: "mu210_403_output_23_state"
friendly_name: "Гостиная розетки состояние:"
value_template: >
{% if not (states('sensor.mu210_403_bit_mask')|int(0)) | bitwise_and(4194304) == 0 %}
on
{% else %}
off
{% endif %}
mu210_403_output_24_state:
unique_id: "mu210_403_output_24_state"
friendly_name: "Ванная и прихожая розетки состояние:"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0)) | bitwise_and(8388608) == 0%}
on
{% else %}
off
{% endif %}
- Creating a “yaml” file in the “switches” folder (these are my configurations, so outputs 19-24 are inverted).
Summary
- platform: template
switches:
mu210_403_output_1:
friendly_name: "Ванная свет"
icon_template: >-
{% if is_state('sensor.mu210_403_output_1_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_1_switch"
value_template: "{{ is_state('sensor.mu210_403_output_1_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 1
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 1
value: 0
mu210_403_output_2:
friendly_name: "Ванная подсветка"
icon_template: >-
{% if is_state('sensor.mu210_403_output_2_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_2_switch"
value_template: "{{ is_state('sensor.mu210_403_output_2_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 2
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 2
value: 0
mu210_403_output_3:
friendly_name: "Прихожая свет"
icon_template: >-
{% if is_state('sensor.mu210_403_output_3_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_3_switch"
value_template: "{{ is_state('sensor.mu210_403_output_3_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 3
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 3
value: 0
mu210_403_output_4:
friendly_name: "Гардероб свет"
icon_template: >-
{% if is_state('sensor.mu210_403_output_4_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_4_switch"
value_template: "{{ is_state('sensor.mu210_403_output_4_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 4
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 4
value: 0
mu210_403_output_5:
friendly_name: "Коридор подсветка"
icon_template: >-
{% if is_state('sensor.mu210_403_output_5_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_5_switch"
value_template: "{{ is_state('sensor.mu210_403_output_5_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 5
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 5
value: 0
mu210_403_output_6:
friendly_name: "Коридор свет"
icon_template: >-
{% if is_state('sensor.mu210_403_output_6_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_6_switch"
value_template: "{{ is_state('sensor.mu210_403_output_6_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 6
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 6
value: 0
mu210_403_output_7:
friendly_name: "Спальня первый свет"
icon_template: >-
{% if is_state('sensor.mu210_403_output_7_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_7_switch"
value_template: "{{ is_state('sensor.mu210_403_output_7_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 7
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 7
value: 0
mu210_403_output_8:
friendly_name: "Спальня второй свет"
icon_template: >-
{% if is_state('sensor.mu210_403_output_8_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_8_switch"
value_template: "{{ is_state('sensor.mu210_403_output_8_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 8
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 8
value: 0
mu210_403_output_9:
friendly_name: "Спальня левый светильник"
icon_template: >-
{% if is_state('sensor.mu210_403_output_9_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_9_switch"
value_template: "{{ is_state('sensor.mu210_403_output_9_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 9
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 9
value: 0
mu210_403_output_10:
friendly_name: "Спальня правый светильник"
icon_template: >-
{% if is_state('sensor.mu210_403_output_10_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_10_switch"
value_template: "{{ is_state('sensor.mu210_403_output_10_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 10
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 10
value: 0
mu210_403_output_11:
friendly_name: "Тулет свет"
icon_template: >-
{% if is_state('sensor.mu210_403_output_11_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_11_switch"
value_template: "{{ is_state('sensor.mu210_403_output_11_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 11
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 11
value: 0
mu210_403_output_12:
friendly_name: "Туалет подсветка"
icon_template: >-
{% if is_state('sensor.mu210_403_output_12_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_12_switch"
value_template: "{{ is_state('sensor.mu210_403_output_12_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 12
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 12
value: 0
mu210_403_output_13:
friendly_name: "Кухня свет"
icon_template: >-
{% if is_state('sensor.mu210_403_output_13_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_13_switch"
value_template: "{{ is_state('sensor.mu210_403_output_13_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 13
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 13
value: 0
mu210_403_output_14:
friendly_name: "Кабинен первый свет"
icon_template: >-
{% if is_state('sensor.mu210_403_output_14_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_14_switch"
value_template: "{{ is_state('sensor.mu210_403_output_14_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 14
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 14
value: 0
mu210_403_output_15:
friendly_name: "Кабинет второй свет"
icon_template: >-
{% if is_state('sensor.mu210_403_output_15_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_15_switch"
value_template: "{{ is_state('sensor.mu210_403_output_15_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 15
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 15
value: 0
mu210_403_output_16:
friendly_name: "Гостиная первый свет"
icon_template: >-
{% if is_state('sensor.mu210_403_output_16_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_16_switch"
value_template: "{{ is_state('sensor.mu210_403_output_16_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 16
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 16
value: 0
mu210_403_output_17:
friendly_name: "Гостиная второй свет"
icon_template: >-
{% if is_state('sensor.mu210_403_output_17_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_17_switch"
value_template: "{{ is_state('sensor.mu210_403_output_17_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 17
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 17
value: 0
mu210_403_output_18:
friendly_name: "Гостиная подсветка"
icon_template: >-
{% if is_state('sensor.mu210_403_output_18_state', 'on') %}
mdi:lightbulb
{% else %}
mdi:lightbulb-outline
{% endif %}
unique_id: "mu210_403_output_18_switch"
value_template: "{{ is_state('sensor.mu210_403_output_18_state', 'on') }}"
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 18
value: 1
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 18
value: 0
mu210_403_output_19:
friendly_name: "Вытяжка"
icon_template: >-
{% if (states('sensor.mu210_403_bit_mask')|int(0) | bitwise_and(262144)) == 0 %}
mdi:hvac
{% else %}
mdi:hvac-off
{% endif %}
unique_id: "mu210_403_output_19_switch"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0) | bitwise_and(262144)) == 0 %}
on
{% else %}
off
{% endif %}
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 19
value: 0
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 19
value: 1
mu210_403_output_20:
friendly_name: "Спальня вентилятор конвектора"
icon_template: >-
{% if (states('sensor.mu210_403_bit_mask')|int(0) | bitwise_and(524288)) == 0 %}
mdi:fan
{% else %}
mdi:fan-off
{% endif %}
unique_id: "mu210_403_output_20_switch"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0) | bitwise_and(524288)) == 0 %}
on
{% else %}
off
{% endif %}
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 20
value: 0
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 20
value: 1
mu210_403_output_21:
friendly_name: "Спальня и гардероб розетки"
icon_template: >-
{% if (states('sensor.mu210_403_bit_mask')|int(0) | bitwise_and(1048576)) == 0 %}
mdi:power-socket-eu
{% else %}
mdi:power-plug-off
{% endif %}
unique_id: "mu210_403_output_21_switch"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0) | bitwise_and(1048576)) == 0 %}
on
{% else %}
off
{% endif %}
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 21
value: 0
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 21
value: 1
mu210_403_output_22:
friendly_name: "Балкон розетки"
icon_template: >-
{% if (states('sensor.mu210_403_bit_mask')|int(0) | bitwise_and(2097152)) == 0 %}
mdi:power-socket-eu
{% else %}
mdi:power-plug-off
{% endif %}
unique_id: "mu210_403_output_22_switch"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0) | bitwise_and(2097152)) == 0 %}
on
{% else %}
off
{% endif %}
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 22
value: 0
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 22
value: 1
mu210_403_output_23:
friendly_name: "Гостиная розетки"
icon_template: >-
{% if (states('sensor.mu210_403_bit_mask')|int(0) | bitwise_and(4194304)) == 0 %}
mdi:power-socket-eu
{% else %}
mdi:power-plug-off
{% endif %}
unique_id: "mu210_403_output_23_switch"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0) | bitwise_and(4194304)) == 0 %}
on
{% else %}
off
{% endif %}
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 23
value: 0
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 23
value: 1
mu210_403_output_24:
friendly_name: "Ванная и прихожая розетки"
icon_template: >-
{% if (states('sensor.mu210_403_bit_mask')|int(0) | bitwise_and(8388608)) == 0 %}
mdi:power-socket-eu
{% else %}
mdi:power-plug-off
{% endif %}
unique_id: "mu210_403_output_24_switch"
value_template: >
{% if (states('sensor.mu210_403_bit_mask')|int(0) | bitwise_and(8388608)) == 0 %}
on
{% else %}
off
{% endif %}
turn_on:
service: shell_command.mu210_403_set_bit
data:
bit: 24
value: 0
turn_off:
service: shell_command.mu210_403_set_bit
data:
bit: 24
value: 1
- Reload Home Assistant
I also connected another MU210-402 module. It has 16 outputs and you need to be careful reading data type Unsigned 32, writing data type Unsigned 16.
shell_command:
mu210_402_set_bit: "python3 /config/python_scripts/bit_mask_modbus.py u16 192.168.77.7 502 1 470 write {{ bit }} {{ value }}"
- sensor:
name: mu210_402_bit_mask
command: "python3 /config/python_scripts/bit_mask_modbus.py u32 192.168.77.7 502 1 468 read | grep 'dec:' | sed -E 's/.*\\(dec: ([0-9]+)\\).*/\\1/'"
scan_interval: 2
value_template: "{{ value | int(0) }}"