Ich werfe mal eine andere (Software) Lösung in den Ring. Nachdem wir in unser Haus mit einer Helios KWL eingezogen sind, bestand Integrationsbedarf in homee . Ist das Ergebnis von zwei Stunden scripten an einem verregneten Sonntag - daher auch noch nicht super hübsch .
Helios KWL bietet eine Modbus TCP Schnittstelle an. Diese erfordert, dass die KWL im Netzwerk verfügbar ist und die modbus Schnittstelle in der KWL Webkonfiguration aktiviert ist (Konfiguration -> Gerät -> Gebäudeleittechnik -> Modbus Aktiviert:). Mit meinem folgenden Python Script auf einem Raspberry kann man dann per homee Webhook Befehle an den KWL senden.
Nach dem Starten des scripts läuft dauerhaft ein Webserver auf dem Raspberry (bis das Script wieder gestoppt wird). Z.B. beim Aufruf von http://raspberry_ip:8087/partymodus_an sendet der Raspberry drei Befehle an die KWL per modbus TCP: Lüfterstufe = 4, Laufzeit = 180min, Partymodus = an. Damit schaltet die KWL dann für 3h in den Lüftermodus 4. Lässt sich auch alles schön im Webserver des KWL nachverfolgen.
Im Moment ist Ruhemodus an / aus, Partybetrieb an / aus und Zuluft Temperatur implementiert, wobei letzteres nur Ready-only ist und dem Testen des Scripts dient. Das Script kann anhand der guten Dokumentation des Herstellers “FUNKTIONS- UND SCHNITTSTELLENBESCHREIBUNG Modbus Gateway TCP/IP” beliebig erweitert werden.
Funktioniert für mich perfekt. So kann man z.B. per FT55 den Partymodus aktivieren und dadurch die Lüftungsanlage auf die höchste Stufe stellen. Zudem möchte ich darüber im Sommer gewisse Lüftungssteuerungszenarien abbilden (z.B. bei sinkender Aussentemperatur nachts das tagsüber erwärmte Haus durch gesteigerte Lüftungsleistung abkühlen). Es gilt lediglich zu beachten, dass lediglich ein Befehl zur gleichen Zeit an die KWL gesendet wird, da die Modbus Implementierung mit Registern arbeitet.
Hier der aktuelle Stand des Scripts für Interessierte (Verwendung auf eigene Gefahr - hier geht’s immerhin um die frische Luft im Haus ):
#!/usr/bin/python
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
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
import time
# Starts a web server and serve as webhook interface to steer the helios KWL
# E.g. homee -> webhook via HTTP -> raspberry running this script -> modbus TCP -> helios KWL
# Based on the work published here: https://github.com/home-assistant/home-assistant/issues/5185
# Call the webserver via: http://IP_WEBSERVER:PORT/BEFEHL
# Supported commands: zuluft, partymodus_an, partymodus_aus, ruhebetrieb_an, ruhebetrieb_aus
# More details on commands in document: FUNKTIONS- UND SCHNITTSTELLENBESCHREIBUNG FUNCTIONAL AND INTERFACE DESCRIPTION Modbus Gateway TCP/IP
SLAVE_ID = 180
FIRST_REGISTER_ADDR = 0x01
KWL_IP = 'helios' # IP of KWL system
WEB_SERVER_PORT_NUMBER = 8087 # port number for webserver
def kwl_comm_start(ip, variable, rtr):
try:
kwl_com = kwl_comm(ip, variable, rtr)
return kwl_com
except:
print "Error in communication"
return "Error in communication"
def kwl_comm(ip, variable, rtr):
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.ERROR)
rtr = rtr + 3
if rtr < 8:
rtr = 8
client = ModbusClient(ip, 502)
client.connect()
builder = BinaryPayloadBuilder(byteorder=Endian.Little,
wordorder=Endian.Big)
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.Big).decode_string(rtr)
output = re.sub(u'([\u0000])', "", output)
client.close()
return(output)
class webHandler(BaseHTTPRequestHandler):
#Handler for the GET requests
def do_GET(self):
print self.path.lower()
self.send_response(200)
self.send_header('Content-type','text/html')
self.end_headers()
if self.path.lower()=="/zuluft":
kwl_comm_out = kwl_comm_start(KWL_IP, 'v00105', 8)
elif self.path.lower()=="/partymodus_an":
kwl_comm_out = kwl_comm_start(KWL_IP, 'v00091=180', 6)
kwl_comm_out = kwl_comm_out + " " + kwl_comm_start(KWL_IP, 'v00092=4', 5)
kwl_comm_out = kwl_comm_out + " " + kwl_comm_start(KWL_IP, 'v00094=1', 5)
elif self.path.lower()=="/partymodus_aus":
kwl_comm_out = kwl_comm_start(KWL_IP, 'v00094=0', 5)
elif self.path.lower()=="/ruhebetrieb_an":
kwl_comm_out = kwl_comm_start(KWL_IP, 'v00096=180', 6)
kwl_comm_out = kwl_comm_out + " " + kwl_comm_start(KWL_IP, 'v00097=0', 5)
kwl_comm_out = kwl_comm_out + " " + kwl_comm_start(KWL_IP, 'v00099=1', 5)
elif self.path.lower()=="/ruhebetrieb_aus":
kwl_comm_out = kwl_comm_start(KWL_IP, 'v00099=0', 5)
else:
kwl_comm_out = "No valid request"
return self.wfile.write(kwl_comm_out)
try:
server = HTTPServer(('', WEB_SERVER_PORT_NUMBER), webHandler)
print 'Started KWL server on port ' , WEB_SERVER_PORT_NUMBER
server.serve_forever()
except KeyboardInterrupt:
print 'Shutting down the KWL web server'
server.socket.close()
Und so sieht der Webhook aus (läuft bei mir auf dem homeean Raspberry mit):