New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFE: Support Helios KWL Modbus implementation #5185
Comments
Updated version of my script. Python noob, please excuse 😄 #!/usr/bin/env python
from pymodbus.client.sync import ModbusTcpClient as ModbusClient
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.payload import BinaryPayloadBuilder
import logging
import argparse
import fcntl, sys, os
import re
SLAVE_ID = 180
FIRST_REGISTER_ADDR = 0x01
# testing modbus communication
def main(ip, variable, rtr):
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(endian=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,
endian=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)
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) Working with this sensor config: # documentation: https://www.heliosventilatoren.de/mbv/kwl-modbus_gateway_82269_0714_d_e_f.pdf
- platform: command_line
name: Betriebsart
value_template: "{% if value.split ('=')[1] == '1' %}manuell{% elif value.split ('=')[1] == '0' %}automatisch{% endif %}"
command: '/home/homeassistant/.homeassistant/helios/helios.py helios.fritz.box 5 v00101'
- platform: command_line
name: Lüfterstufe
value_template: "{{value.split ('=')[1]}}"
command: '/home/homeassistant/.homeassistant/helios/helios.py helios.fritz.box 5 v00102'
- platform: command_line
name: Temperatur Außenluft
value_template: "{{value.split ('=')[1]}}"
unit_of_measurement: '°C'
command: '/home/homeassistant/.homeassistant/helios/helios.py helios.fritz.box 8 v00104'
- platform: command_line
name: Temperatur Zuluft
value_template: "{{value.split ('=')[1]}}"
unit_of_measurement: '°C'
command: '/home/homeassistant/.homeassistant/helios/helios.py helios.fritz.box 8 v00105'
- platform: command_line
name: Temperatur Fortluft
value_template: "{{value.split ('=')[1]}}"
unit_of_measurement: '°C'
command: '/home/homeassistant/.homeassistant/helios/helios.py helios.fritz.box 8 v00106'
- platform: command_line
name: Temperatur Abluft
value_template: "{{value.split ('=')[1]}}"
unit_of_measurement: '°C'
command: '/home/homeassistant/.homeassistant/helios/helios.py helios.fritz.box 8 v00107'
- platform: command_line
name: Lüfter Zuluft RPM
value_template: "{{value.split ('=')[1]}}"
command: '/home/homeassistant/.homeassistant/helios/helios.py helios.fritz.box 8 v00348'
- platform: command_line
name: Lüfter Abluft RPM
value_template: "{{value.split ('=')[1]}}"
command: '/home/homeassistant/.homeassistant/helios/helios.py helios.fritz.box 8 v00349' Nevertheless it would be nice if there existed a better way of doing this. Home Assistant is great 😃 |
Important fact: due to the fancy nature of the Helios KWL Modbus implementation, only one script at a time must be executed. Otherwise the values are overwritten in the register and hence wrong values retrieved. This is the reason for the locking mechanism in the python script - If this gets implemented into HA, this needs to be maintained as well! |
There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates. Please make sure to update to the latest Home Assistant version and check if that solves the issue. Let us know if that works for you by adding a comment 👍 |
I am also fine if this is closed and can be found here as a reference. Demand does not seem too high ;-) |
Please support the fancy Helios KWL implementation of Modbus. https://www.heliosventilatoren.de/mbv/kwl-modbus_gateway_82269_0714_d_e_f.pdf
They require that at first the desired variable is written into a register and with the subsequential read from the holding registers, the value is returned.
Setting of values looks similar, just enter the variable name = value, e.g. v00102=1 to set the fan to level 1.
helios.txt
Example:
Temperatur Zuluft = v00105
First step: Write this into the register after the payload has been encoded. The documentation about the number of registers to read is either wrong or I don't get it ;-)
Second step: retrieve values:
Output:
homeassistant@homeassistant:~/.homeassistant/helios$ python helios.py v00105=17.7
Working example file attached.
The text was updated successfully, but these errors were encountered: