Hi,
back in the days I hacked my own command_line
script to retrieve data from my Helios KWL device.
This is the script:
#!/usr/bin/env python3.6
import logging
import argparse
import sys
import re
from pymodbus.client.sync import ModbusTcpClient as ModbusClient
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.payload import BinaryPayloadBuilder
SLAVE_ID = 180
FIRST_REGISTER_ADDR = 0x01
# read or write data from or to modbus via TCP, Helios KWL specific
def main(ip, variable, rtr):
try:
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.ERROR)
# stupid workaround to use the correct number of registers
rtr = rtr + 3
if rtr < 8:
rtr = 8
client = ModbusClient(ip, 502)
client.connect()
builder = BinaryPayloadBuilder(byteorder=Endian.Big,
wordorder=Endian.Little)
builder.add_string(variable + '\0')
payload = builder.build()
client.write_registers(FIRST_REGISTER_ADDR, payload,
skip_encode=True, unit=SLAVE_ID)
result = client.read_holding_registers(
FIRST_REGISTER_ADDR, rtr, unit=SLAVE_ID)
output = BinaryPayloadDecoder.fromRegisters(result.registers,
byteorder=Endian.Little,
wordorder=Endian.Little).decode_string(rtr)
# get rid of null bytes
# http://chase-seibert.github.io/blog/2011/05/20/stripping-control-characters-in-python.html
output = re.sub(u'([\u0000])', "", output.decode(
sys.getdefaultencoding()))
except Exception as e:
print(e)
else:
print(output)
if __name__ == "__main__":
#pid_file = '/tmp/helios.pid'
#fp = open(pid_file, 'w')
# try:
# fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
# except IOError:
# # another instance is running
# sys.exit(1)
# fp.write(str(os.getpid()))
parser = argparse.ArgumentParser(description='Helios KWL Modbus interface')
parser.add_argument('ip', help='IP address of Modbus slave')
parser.add_argument(
'registers', help='Number of registers to read. Can be obtained from the KWL documentation.')
parser.add_argument(
'variable', help='Variable to read. If value should be set, append =value, e.g. v00102=1 to set fan to level 1.')
args = parser.parse_args()
main(args.ip, args.variable, int(args.registers))
# fp.close()
# os.unlink(pid_file)
Not beautiful but it works
I use it via command_line
integration as follows:
# documentation modbus: https://www.heliosventilatoren.de/mbv/kwl-modbus_gateway_82269_0714_d_e_f.pdf
# error codes: http://www.heliosventilatoren.de/1alt/mbv/kwl_easycontrols_82200_0116_v_2.20_d_e_f.pdf
- platform: command_line
name: Mode
value_template: "{% if value.split ('=')[1] == '1' %}manual{% elif value.split ('=')[1] == '0' %}auto{% endif %}"
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 5 v00101'
- platform: command_line
name: Fan level
value_template: "{{value.split ('=')[1]}}"
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 5 v00102'
- platform: command_line
name: Outdoor air temp
value_template: "{{value.split ('=')[1]}}"
unit_of_measurement: '°C'
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 8 v00104'
- platform: command_line
name: Supply air temp
value_template: "{{value.split ('=')[1]}}"
unit_of_measurement: '°C'
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 8 v00105'
- platform: command_line
name: Outgoing air temp
value_template: "{{value.split ('=')[1]}}"
unit_of_measurement: '°C'
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 8 v00106'
- platform: command_line
name: Extract air temp
value_template: "{{value.split ('=')[1]}}"
unit_of_measurement: '°C'
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 8 v00107'
- platform: command_line
name: Supply air fan speed
value_template: "{{value.split ('=')[1]}}"
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 8 v00348'
unit_of_measurement: 'rpm'
- platform: command_line
name: Extract air fan speed
value_template: "{{value.split ('=')[1]}}"
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 8 v00349'
unit_of_measurement: 'rpm'
- platform: command_line
name: Errors
value_template: "{{value.split ('=')[1]}}"
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 5 v01300'
- platform: command_line
name: Warnings
value_template: "{{value.split ('=')[1]}}"
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 5 v01301'
- platform: command_line
name: Infos
value_template: "{{value.split ('=')[1]}}"
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 5 v01302'
- platform: command_line
name: Error ID
value_template: "{{value.split ('=')[1]}}"
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 9 v01123'
- platform: command_line
name: Warning ID
value_template: "{{value.split ('=')[1]}}"
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 6 v01124'
- platform: command_line
name: Info ID
value_template: "{{value.split ('=')[1]}}"
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 6 v01125'
- platform: command_line
name: Filter change remaining time
value_template: "{{float(value.split ('=')[1]) / 60 / 24 | round(2)}}"
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 10 v01033'
- platform: command_line
name: Party mode status
value_template: "{% if value.split ('=')[1] == '1' %}on{% elif value.split ('=')[1] == '0' %}off{% endif %}"
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 5 v00094'
- platform: command_line
name: Party mode duration
value_template: "{{value.split ('=')[1]}}"
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 6 v00091'
- platform: command_line
name: Party mode level
value_template: "{{value.split ('=')[1]}}"
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 5 v00092'
- platform: command_line
name: Party mode remaining time
value_template: "{{value.split ('=')[1]}}"
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 7 v00093'
unit_of_measurement: 'minutes'
- platform: command_line
name: Bypass
value_template: "{{value.split ('=')[1]}}"
command: '/home/hass/homeassistant/helios/helios.py helios.fritz.box 6 v02119'
I now wanted to transform this to the native Modbus component but I don’t get it to work.
Current config from configuration.yaml
:
modbus:
type: tcp
host: helios.fritz.box
port: 502
The according yaml in the sensors directory - I tried different values but I always receive 2019-03-24 21:31:56 ERROR (SyncWorker_13) [homeassistant.components.modbus.sensor] No response from hub default, slave 180, register 1
- platform: modbus
registers:
- name: modbus test
slave: 180
register: 1
register_type: holding
count: 1
Any clues, hints? Thank you!