Hallo zusammen,
ich habe mal wieder Teilerfolge :-)
Momentan habe ich eine Vallox MV 270 über die Vallox Cloud mit dem httpmod gekoppelt. Das möchte ich ändern und dann direkt mit der KWL über websockets kommunizieren.
Hierzu habe ich https://github.com/yozik04/vallox_websocket_api (https://github.com/yozik04/vallox_websocket_api) mit python3.5 installiert.
Das läuft zumindest für die Abfragen der Vallox bereits von der shell Ebene mit den Python Aufrufen ganz gut.
Status mit Python in der shell
$ python3.5 ./test_status_temp.py
{'A_CYC_TEMP_EXHAUST_AIR': 23.2,
'A_CYC_TEMP_EXTRACT_AIR': 23.2,
'A_CYC_TEMP_OUTDOOR_AIR': 20.1,
'A_CYC_TEMP_SUPPLY_AIR': 21.2,
'A_CYC_TEMP_SUPPLY_CELL_AIR': 20.4}
Könnte mir nun einer sagen, wonach ich im Forum suchen soll, um das z.B. in einen Dummy zu bekommen?
Den Aufruf eines Skripts bekomme ich sicher noch hin, da habe ich bereits Beispiele gefunden, beim Output habe ich dann noch so meinen Knoten im Kopf.
Aus meinem httpmod hätte ich schon mal die readings Namen als Anhaltspunkt.
Viele Grüße
Christian
Hallo Christian,
es gibt auch eine "API" für python
# python fhem API https://github.com/domschl/python-fhem
Für die Shell hab ich mal was gebaut um FHEM über HTTP anzusprechen. Allerdings ist da keine python Version dabei.
https://heinz-otto.blogspot.com/2019/02/fhem-http-client.html
Prinzipiell könntest Du aber auch das shell Script nehmen :)
Gruß Otto
Zitat
es gibt auch eine "API" für python
# python fhem API https://github.com/domschl/python-fhem
Okay, das habe ich just in diesem Moment gefunden :-)
Zitat
Für die Shell hab ich mal was gebaut um FHEM über HTTP anzusprechen. Allerdings ist da keine python Version dabei.
https://heinz-otto.blogspot.com/2019/02/fhem-http-client.html
Prinzipiell könntest Du aber auch das shell Script nehmen :)
Das schaue ich mir auch mal an.
Bei beiden Varianten würde FHEM das Skript starten und der Skript-Output dann aktiv mit "set" Kommandos zum FHEM kommen.
Das habe ich auch schon mal in einem "TV-Programm" Skript gesehen.
Gibt es denn auch eine Möglichkeit beim FHEM-Skript-Aufruf direkt von Stdout zu lesen und das dann in readings zu packen?
Ich vermute, da muss man sicher ein Modul schreiben :-)
Gruß
Christian
Zitat von: ch.eick am 20 August 2019, 16:55:36
Gibt es denn auch eine Möglichkeit beim FHEM-Skript-Aufruf direkt von Stdout zu lesen und das dann in readings zu packen?
Ich vermute, da muss man sicher ein Modul schreiben :-)
Wie meinst Du das?
Ich vermute mal so:
{my $reading=qx(bash ShellScript1.sh);;fhem("setreading Dummy Reading1 $reading")}
In $reading steht der Rückgabewert (stdout) vom ShellScript.sh.
Aber so etwas ist blockierend! Deshalb ist es besser Du setzt die Readings aus dem Script "von außen" in fhem.
Gruß Otto
Okay.
ich habe da noch das gefunden:
define testdummy dummy
attr testdummy webCmd on:off
define testdummywert dummy
define act_on_testdummy notify testdummy {\
my $rueckgabe = "php /home/pi/testdummy.php &";;\
fhem("set testdummywert $rueckgabe;;");;\
}
Was aber Deinem Beispiel entspricht.
Gruß
Christian
Zitatmy $rueckgabe = "php /home/pi/testdummy.php &"
Ich möchte behaupten, das ist Unsinn.
Erstens liefert das nur einen String, zweitens würde ein FHEM Aufruf in "Shellscript" (https://commandref.fhem.de/#command) keinen Rückgabewert liefern sondern ins Log schreiben.
Oder steh gerade völlig daneben :)
Und noch ne Frage.
Wäre das denn für FHEM auch blockierend?
####################################
# Python-Test #
####################################
sub TestLesen(){
my $returnCode = system( "python /home/pi/testscript.py" );
fhem("setReading TestPython TestPython $returnCode");
}
system() liefert nur eine 1 zurück!
Und etwas nicht blockierendes kann nichts zurückliefern! Der Code muss ja warten aufs Ergebnis und das blockiert :)
Deswegen: Entweder es geht schnell und stört nicht oder man stößt es aus FHEM nur an und das Script schreibt selbst über HTTP oder Telnet selbst wieder zurück.
Zitat von: Otto123 am 20 August 2019, 17:15:07
system() liefert nichts zurück als eine 1!
Stimmt, da steht ja auch returnCode
Zitat von: Otto123 am 20 August 2019, 17:13:16
Ich möchte behaupten, das ist Unsinn.
Erstens liefert das nur einen String, zweitens liefert der FHEM Aufruf in "Shellscript" keinen Rückgabewert sondern schreibt ins Log.
Oder steh gerade völlig daneben :)
In diesem Fall würde die Stdout in die Variable geschrieben
$ text=`echo Meine Skript Ausgabe &`
$ echo $text
Meine Skript Ausgabe
Jedoch kann es zu Syncronisationsproblemen kommen, denn der Prozess im Hintergrung kann ja noch schreiben, wenn der nächste Befehl ausgeführt wird.
define act_on_testdummy notify testdummy {\
my $rueckgabe = "php /home/pi/testdummy.php &";;\ <==== Das dürfte doch nicht warten???
fhem("set testdummywert $rueckgabe;;");;\ <===== Und dann dürfte hier noch nicht alles drin stehen???
Würde denn dann das notify blockieren wenn das "&" weg ist und das Skript eventuell niemals endet???
Update: Das hat Otto schon beantwortet.
Zitat von: Otto123 am 20 August 2019, 17:15:07
system() liefert nur eine 1 zurück!
Und etwas nicht blockierendes kann nichts zurückliefern! Der Code muss ja warten aufs Ergebnis und das blockiert :)
Deswegen: Entweder es geht schnell und stört nicht oder man stößt es aus FHEM nur an und das Script schreibt selbst über HTTP oder Telnet selbst wieder zurück.
Das leuchtet ein. Vielen dank für den Denkanstoß.
Und einen hab ich noch.
Die Konfiguration wäre dann nun in der Theorie ein notify, das im Hintergrung ein Skript laufen lässt. Im Skript wird dann folgender FHEM Befehl abgesetz.
setreading KWL output {'A_CYC_TEMP_EXHAUST_AIR': 23.2, 'A_CYC_TEMP_EXTRACT_AIR': 23.2, 'A_CYC_TEMP_OUTDOOR_AIR': 20.1, 'A_CYC_TEMP_SUPPLY_AIR': 21.2, 'A_CYC_TEMP_SUPPLY_CELL_AIR': 20.4}
Kann ich das dann elegant im Dummy als json zerlegen, sodass es einzelne readings werden?
Also zunächst der Fall:
my $rueckgabe = "php /home/pi/testdummy.php &";;\
Hier steht doch nichts weiter wie:
my $rueckgabe = "willi" ???
Was willst Du mit dem String willi machen? Du könntest
qx($rueckgabe)
machen
Dann würde das ausgeführt, aber da am Ende ein & steht wird nicht gewartet. Demzufolge landet keine Ausgabe im String $rueckgabe, bestenfalls irgendein Status. Die Ausgabe nach stdout passiert doch erst ein Jahr später :)
Zur letzen Idee: Probier doch sowas einfach aus, das hilft ungemein. Ich habe es getan, das Ergebins
Internals:
CFGFN
FUUID 5d5c2f9d-f33f-27f7-a3f9-593e29982f269d1a
NAME KWL
NR 85869
STATE ???
TYPE dummy
READINGS:
2019-08-20 19:36:33 output {'A_CYC_TEMP_EXHAUST_AIR': 23.2, 'A_CYC_TEMP_EXTRACT_AIR': 23.2, 'A_CYC_TEMP_OUTDOOR_AIR': 20.1, 'A_CYC_TEMP_SUPPLY_AIR': 21.2, 'A_CYC_TEMP_SUPPLY_CELL_AIR': 20.4}
Attributes:
Aber klar so in etwa geht das, Dein Script setzt über eine Schnittstelle die setreading's an FHEM per Telnet oder HTTP ab:
setreading KWL A_CYC_TEMP_EXHAUST_AIR 23.2
setreading KWL A_CYC_TEMP_EXTRACT_AIR 23.2
setreading KWL A_CYC_TEMP_OUTDOOR_AIR 20.1
setreading KWL A_CYC_TEMP_SUPPLY_AIR 21.2
Oder schau mal hier rechts und links, da steht was von mqtt und json - vielleicht passt da irgendwo dein String dazu :)
Ich habe leider von beidem so gut wie keine Ahnung.
Gruß Otto
Hallo zusammen,
heute gab es einen ersten Durchbruch.
Das Vallox KWL device, das die JSON Daten entgegen nimmt und als readings expandiert.
defmod KWL expandJSON KWL:output:.\{.*}
Ein wenig Python
vallox_websocket_api in einem Unterverzeichnis von fhem entpacken.
python3.5 -m pip install vallox_websocket_api
python3.5 -m pip install fhem
Eine Passwort Datei anlegen
FHEM sollte bereits mit https und Username/Password konfiguriert sein.
-rw------- 1 fhem fhem 53 Aug 21 18:45 pwd.json
cat pwd.json
{
"username": "user",
"password": "passwort"
}
Das Testskript
# import logging
# logging.basicConfig(level=logging.DEBUG)
import fhem
import json
import asyncio
from vallox_websocket_api import Client
import sys
kwl = sys.argv[1]
web = sys.argv[2]
try:
with open('pwd.json', 'r') as f:
credentials=json.load(f)
except Exception as e:
print('Something went wrong: {}'.format(e))
client = Client(kwl)
async def run():
# Alles auslesen
metrics = await client.fetch_metrics()
# oder nur bestimmte Werte
# metrics = await client.fetch_metrics([
# 'A_CYC_TEMP_EXHAUST_AIR',
# 'A_CYC_TEMP_EXTRACT_AIR',
# 'A_CYC_TEMP_OUTDOOR_AIR',
# 'A_CYC_TEMP_SUPPLY_AIR',
# 'A_CYC_TEMP_SUPPLY_CELL_AIR'
# ])
message = json.dumps(metrics)
# auf stdout anzeigen
# from pprint import pprint
# pprint(message)
fh = fhem.Fhem(web, protocol="https", port=8083, username=credentials["username"], password=credentials["password"])
fh.send_cmd("setreading KWL output " + message)
asyncio.get_event_loop().run_until_complete(run())
Das Skript aufrufen
$ python3.5 ./test_status.py <IP der KWL> <IP des FHEM Server>
Zum Aufräumen der readings ist dieser Aufruf ganz gut
deletereading KWL [A|C|EXT|RANGE|WS].*
Die mit Otto besprochene Skript Ausführung kann dann jetzt auch noch eingebaut werden.
Viele Grüße
Christian
Die vorherige Kopplung zur Vallox Cloud ist hier
https://forum.fhem.de/index.php/topic,45176.msg879350.html#msg879350 (https://forum.fhem.de/index.php/topic,45176.msg879350.html#msg879350)
zu finden. Bei der Lösung ist bereits auch eine Steuerung der Vallox MV 270 möglich.
Wer das probieren möchte, der müsste jedoch den aktuellsten Eintrag in dem Thread verwenden. Es hatte darmals etwas gedauert, bis die Lösung inklusive "set" funktionierte.
Hallo zusammen,
jetzt versuche ich gerade das Skript mit at im FHEM aufzurufen, jedoch scheint die ssl Umgebung unterschiedlich zu sein.
defmod KWL_poll at +*00:05:00 {system("/usr/bin/python /opt/fhem/python/bin/kwl_status.py <IP der KWL> <IP des FHEM Server>")}
Failed to send msg, len=0, <urlopen error _ssl.c:704: The handshake operation timed out>
No valid answer on send when expecting csrf.
Failed to send msg, len=0, <urlopen error _ssl.c:704: The handshake operation timed out>
No valid answer on send when expecting csrf.
CSRF token not available!
Failed to send msg, len=185, <urlopen error _ssl.c:704: The handshake operation timed out>
2019.08.22 12:13:54 1: FHEMWEB SSL/HTTPS error: SSL accept attempt failed (peer: <IP des FHEM Server>)
2019.08.22 12:13:55 1: FHEMWEB SSL/HTTPS error: SSL accept attempt failed (peer: <IP des FHEM Server>)
2019.08.22 12:13:55 1: FHEMWEB SSL/HTTPS error: SSL accept attempt failed (peer: <IP des FHEM Server>)
Das gleiche Kommand als user fhem in der unix session läuft tadellos.
import fhem
import json
import asyncio
from vallox_websocket_api import Client
import sys
kwl = sys.argv[1]
web = sys.argv[2]
try:
with open('/opt/fhem/python/pwd.json', 'r') as f:
credentials=json.load(f)
except Exception as e:
print('Something went wrong: {}'.format(e))
client = Client(kwl)
async def run():
# metrics = await client.fetch_metrics()
metrics = await client.fetch_metrics([
'A_CYC_TEMP_EXHAUST_AIR',
'A_CYC_TEMP_EXTRACT_AIR',
'A_CYC_TEMP_OUTDOOR_AIR',
'A_CYC_TEMP_SUPPLY_AIR',
'A_CYC_TEMP_SUPPLY_CELL_AIR'
])
message = json.dumps(metrics)
# from pprint import pprint
# pprint(message)
fh = fhem.Fhem(web, protocol="https", port=8083, username=credentials["username"], password=credentials["password"])
fh.send_cmd("setreading KWL output " + message)
asyncio.get_event_loop().run_until_complete(run())
$ ps -ef |grep perl
fhem 8576 1 17 10:18 pts/0 00:22:24 /usr/bin/perl ./fhem.pl ./fhem.cfg
Was muss ich da noch für Zauberworte sprechen, um die HTTPS Umgebung beim "system()" Aufruf zum Laufen zu bekommen?
Gruß
Christian
Hallo Christian,
mir scheint eher hier das Problem? CSRF token not available!
Aber ich verstehe auch gerade nicht wirklich welchen Weg Du gehst :-\
Wer soll mit SSL reden udn wo klappt es nicht? Dein FHEM Server mag es nicht? Dein KWL mag es nicht?
Gruß Otto
Zitat von: Otto123 am 22 August 2019, 14:05:54
Hallo Christian,
mir scheint eher hier das Problem? CSRF token not available!
Aber ich verstehe auch gerade nicht wirklich welchen Weg Du gehst :-\
Wer soll mit SSL reden udn wo klappt es nicht? Dein FHEM Server mag es nicht? Dein KWL mag es nicht?
Gruß Otto
Die Verbindung ist aus dem Python Skript zum FHEM Server.
Das Skript wird mit system() aufgerufen. Userid und Passwort kommen aus einer Datei.
Es ist das identische Skript, das ich mit dem User fhem aufrufe.
Ich vermute das Environment vom User fhem und das Environment vom system() Aufruf aus dem FHEM Server könnten unterschiedlich sein.
Wie wir es gestern besprochen hatten baut jetzt das Python Skript mit https eine Verbindung zum FHEM auf, um mit setreading die Daten zu übergeben.
Hallo nochmal,
ich habe den selben Post hier https://forum.fhem.de/index.php/topic,63816.msg968825.html#msg968825 (https://forum.fhem.de/index.php/topic,63816.msg968825.html#msg968825) nochmal eingetragen, da es eventuell mit dem "Python FHEM API-Modul" zutun haben könnte.
Sorry, ich wusste ansonsten nicht, wie ich beides zusammen kriegen sollte.
Christian
Update:
Bei Aufruf des Skriptes mit system(...&) tritt das Problem nicht auf.
https://forum.fhem.de/index.php/topic,63816.msg970207.html#msg970207 (https://forum.fhem.de/index.php/topic,63816.msg970207.html#msg970207)
Viele Grüße
Christian
Und nun geht es weiter....
Das Auslesen der Vallox MV 270 funktioniert nun.
Jetzt würde ich gerne das Profil wechseln, was in der Vallox Cloud folgender maßen möglich ist.
HTTPMOD Attribute
set01Data {"20545":{"value":15,"minutesflag":true,"modbus":20545,"disabled":false},"65550":{"value":$val,"modbus":65550},"65603":{"value":30,"minutesflag":true,"modbus":65603,"disabled":false}}
set01IMap 0:Anwesend, 1:Abwesend, 2:Stosslueften, 3:Kaminfunktion
set01Name KWL_Set_Profil
Das einzig Variable beim setzen der JSON Werte ist hierbei "65550" mit Value "[0|1|2|3]"
Wie könnte ich jetzt eine eqivalenten Aufruf im vallox_websocket_api verwenden?
Ich habe bereits etwas wie hier gefunden, komme jedoch mit den zu verwendenden JSON Variablen nicht ganz klar.
client.set_settable_address('A_CYC_MODE', int)
await client.set_values({
'A_CYC_MODE': 0, #Minutes
})
Wer kann mir da mal bitte etwas Hilfestellung geben?
Viele Grüße
Christian
Update:
Mit diesem Code kann man die Profile 0,1 und 3 ansteuern, jedoch ist das Profil 2 (boost; Stoßlüften) nicht funktionstüchtig.
# import logging
# logging.basicConfig(level=logging.DEBUG)
import json
import asyncio
from vallox_websocket_api import Vallox, PROFILE
import sys
kwl = sys.argv[1]
try:
with open('/opt/fhem/python/pwd.json', 'r') as f:
credentials=json.load(f)
except Exception as e:
print('Something went wrong: {}'.format(e))
client = Vallox(kwl) # Vallox unit IP
async def run():
await client.get_profile() # RETURNS a PROFILE.* value
# Hier bitte eins auswählen
await client.set_profile(PROFILE.HOME) # Permanently HOME profile
# await client.set_profile(PROFILE.AWAY) # Permanently AWAY profile
# await client.set_profile(PROFILE.FIREPLACE) # FIREPLACE mode for configured timeout
# Dies hat noch nicht funktioniert, oder wurde von mir falsch angewendet
# await client.set_profile(PROFILE.FIREPLACE, 120) # FIREPLACE mode for 120 min
# await client.set_profile(PROFILE.FIREPLACE, 65535) # FIREPLACE mode, never TIMEOUT
# await client.set_profile(PROFILE.EXTRA) # EXTRA mode for configured timeout
# await client.set_profile(PROFILE.EXTRA, 65535) # EXTRA mode, never TIMEOUT
# await client.set_profile(PROFILE.EXTRA, 120) # EXTRA mode for 120 min
asyncio.get_event_loop().run_until_complete(run())
Und hier ein Log vom Profil 2 (EXTRA)
Es kommt eine INFO, jedoch schaltet die Vallox nicht, wie bei den drei anderen, in dieses Profil um.
Die Laufzeitveränderungen aus dem beispiel habe ich ebenfalls ohne Erfolg getestet.
DEBUG:asyncio:Using selector: EpollSelector
DEBUG:websockets.protocol:client - state = CONNECTING
DEBUG:websockets.protocol:client - event = connection_made(<_SelectorSocketTransport fd=6 read=idle write=<idle, bufsize=0>>)
DEBUG:websockets.protocol:client - state = OPEN
DEBUG:websockets.protocol:client > Frame(fin=True, opcode=2, data=b'\x03\x00\xf6\x00\x00\x00\xf9\x00', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=2, data=b'\x00$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x08\x00\n\x00\x00\x00\x00\x00\x00\x00[_\xec\xa0\x00\x01\x00\x05 ?\xbb\x11\x0c\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x00\x1eu\nvPvSu\ruv\x00\x01\x00\x00\x04\x01\x04\xb6\x00<\x00\x00\x00\x00\x00\x00\x00\x00\x01\xc7\x02\xf0\x00\x02\x00\x00\x00<\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00W\xc5\x03\xe8\xff\xff\xff\xff\xff\xff\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x02\x15\xfe\x00\x95\x000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x07\x00\x14\x00\x13\x00\x1c\x00\x08\x00\x13\x00\x03\x00\x07\x00X\x00i\x00\x01\x00\x00\x00\x00\x00\x00\x00\x07\x002\x002\x00\x01\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\xc0\xa8\xb2\x01\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xc0\xa8\xb2\x0bC,wu?\xdaC\n\x92\n\x97\xb5\x91\xb5\xf2\xc4\x00L\x00L\x00\x01\x00\xc0\x01\x01\x00%\x002\x002\x002\x00\x00\x009\x03\x84\x00\x00p\x8f\x002\x002\x00\n\x00\x00\x00\x00\x00\x01\x00\x00\x00\x14p\x8f\x00\x00\x00\x00\x00\x01\x00\x00\x00\x1ep\x8f\x00\x00\x00\x00\x00\x01\x00\x00\x00Kp\x8f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x007\x00\x0f\x00\x0b\x02v\x00\x00\x00\x00h\xbf\x00\x01\x00\x05\x9c\xaa\x00\x00\x00\x14\x01h\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x1e\x00\x0f\x00\x14\x00\n\x00\x12\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x03\xe9\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x01\x00\x00\x00\n\x002\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x01\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x01\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client - state = CLOSING
DEBUG:websockets.protocol:client > Frame(fin=True, opcode=8, data=b'\x03\xe8', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=8, data=b'', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client - event = eof_received()
DEBUG:websockets.protocol:client - event = connection_lost(None)
DEBUG:websockets.protocol:client - state = CLOSED
DEBUG:websockets.protocol:client x code = 1005, reason = [no reason]
DEBUG:websockets.protocol:client - state = CONNECTING
DEBUG:websockets.protocol:client - event = connection_made(<_SelectorSocketTransport fd=6 read=idle write=<idle, bufsize=0>>)
DEBUG:websockets.protocol:client - state = OPEN
DEBUG:websockets.protocol:client > Frame(fin=True, opcode=2, data=b'\x03\x00\xf6\x00\x00\x00\xf9\x00', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=2, data=b'\x00$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x08\x00\n\x00\x00\x00\x00\x00\x00\x00[_\xec\xa0\x00\x01\x00\x05 ?\xbb\x11\x0c\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x00\x1eu%vkvPt\xeeui\x00\x01\x00\x00\x04\x01\x04\xb7\x00<\x00\x00\x00\x00\x00\x00\x00\x00\x01\xc7\x02\xf4\x00\x00\x00\x00\x00<\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00W\xc5\x03\xe8\xff\xff\xff\xff\xff\xff\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x02\x15\xfe\x00\x95\x000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x07\x00\x14\x00\x13\x00\x1c\x00\x08\x00\x13\x00\x03\x00\x07\x00X\x00i\x00\x01\x00\x00\x00\x00\x00\x00\x00\x07\x002\x002\x00\x01\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\xc0\xa8\xb2\x01\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xc0\xa8\xb2\x0bC,wu?\xdaC\n\x92\n\x97\xb5\x91\xb5\xf2\xc4\x00L\x00L\x00\x01\x00\xc0\x01\x01\x00%\x002\x002\x002\x00\x00\x009\x03\x84\x00\x00p\x8f\x002\x002\x00\n\x00\x00\x00\x00\x00\x01\x00\x00\x00\x14p\x8f\x00\x00\x00\x00\x00\x01\x00\x00\x00\x1ep\x8f\x00\x00\x00\x00\x00\x01\x00\x00\x00Kp\x8f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x007\x00\x0f\x00\x0b\x02v\x00\x00\x00\x00h\xbf\x00\x01\x00\x05\x9c\xaa\x00\x00\x00\x14\x01h\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x1e\x00\x0f\x00\x14\x00\n\x00\x12\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x03\xe9\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x01\x00\x00\x00\n\x002\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x01\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x01\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client - state = CLOSING
DEBUG:websockets.protocol:client > Frame(fin=True, opcode=8, data=b'\x03\xe8', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=8, data=b'', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client - event = eof_received()
DEBUG:websockets.protocol:client - event = connection_lost(None)
DEBUG:websockets.protocol:client - state = CLOSED
DEBUG:websockets.protocol:client x code = 1005, reason = [no reason]
INFO:root:Setting unit to EXTRA profile for 10 minutes
DEBUG:websockets.protocol:client - state = CONNECTING
DEBUG:websockets.protocol:client - event = connection_made(<_SelectorSocketTransport fd=6 read=idle write=<idle, bufsize=0>>)
DEBUG:websockets.protocol:client - state = OPEN
DEBUG:websockets.protocol:client > Frame(fin=True, opcode=2, data=b'\x08\x00\xf9\x00\x04\x12\x00\x00\x05\x12\x00\x00\x06\x12\n\x00\x1a7', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=2, data=b'\x02\x00\xf5\x00\xf7\x00', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client - state = CLOSING
DEBUG:websockets.protocol:client > Frame(fin=True, opcode=8, data=b'\x03\xe8', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=8, data=b'', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client - event = eof_received()
DEBUG:websockets.protocol:client - event = connection_lost(None)
DEBUG:websockets.protocol:client - state = CLOSED
DEBUG:websockets.protocol:client x code = 1005, reason = [no reason]
Jetzt bin ich schon sooooo nah dran und bräuchte dann doch noch Unterstützung.
Vielen Dank im Voraus
Christian
Update
Nun gehen alle Profile, es war ein Anfänger Fehler.
Im Beispiel auf GitHup https://github.com/yozik04/vallox_websocket_api (https://github.com/yozik04/vallox_websocket_api) war einfach nur das BOOST Prifile nicht angegeben, konnte aber mit logik einfach ergänzt werden.
await client.set_profile(PROFILE.BOOST) # BOOST profile for configured time ( 30 minutes )
So einfach kann es sein...
Viele Grüße
Christian
Update 20190906 15:59 Es wurde noch die aktive Profil Erkennung eingebaut.
Die Steuerung besteht nun aus den drei folgenden FHEM definitionen:
defmod KWL_Control dummy
attr KWL_Control comment Profile \
1=Anwesend/Home,\
2=Abwesend/Away,\
3=Stosslueften/Boost,\
4=Kaminfunktion/Fireplace\
attr KWL_Control group KWL
attr KWL_Control icon audio_eq
attr KWL_Control readingList Profil
attr KWL_Control room Heizung->System
attr KWL_Control setList Profil:slider,1,1,4
attr KWL_Control sortby 01
attr KWL_Control stateFormat {sprintf("innen %d °C, Zuluft %d °C, Abluf %d °C, außen %d °C | %s %s| %s", \
ReadingsVal("KWL_Status","A_CYC_TEMP_EXTRACT_AIR","?"),\
ReadingsVal("KWL_Status","A_CYC_TEMP_SUPPLY_AIR","?"),\
ReadingsVal("KWL_Status","A_CYC_TEMP_EXHAUST_AIR","?"),\
ReadingsVal("KWL_Status","A_CYC_TEMP_OUTDOOR_AIR","?"),\
ReadingsVal("KWL_Status","EXT_CYC_STATE","?"),\
ReadingsVal("KWL_Status","EXT_CYC_CELL_STATE","?"),\
ReadingsVal("KWL_Status","EXT_CYC_TIME","?")\
)}
setstate KWL_Control innen 22 °C, Zuluft 21 °C, Abluf 22 °C, außen 19 °C | Home Bypass| 15:54
# Hier habe ich veränderliche Variablen plaziert, die z.B. beim Skriptaufruf verwendet werden.
setstate KWL_Control 2019-09-05 18:44:30 FHEM_Ip-Adress x.x.x.x
setstate KWL_Control 2019-09-05 18:44:50 KWL_Ip-Adress x.x.x.x
defmod KWL_Status expandJSON KWL_Status:output:.\{.*}
attr KWL_Status comment Das Device wird über ein Python Skript im reading output befüllt.\
deletereading KWL [A|C|EXT|RANGE|WS].*\
CYC_CELL_STATE 0=WRG, 1= KRG, 2= Bypass, 3=Defrost\
CYC_STATE 0=HOME, 1=AWAY
attr KWL_Status group KWL
attr KWL_Status icon Ventilator_wind
attr KWL_Status room Heizung->System
attr KWL_Status sortby 02
attr KWL_Status userReadings EXT_CYC_TIME { sprintf("%0.2i:%0.2i",ReadingsVal("$name","A_CYC_HOUR",""), ReadingsVal("$name","A_CYC_MINUTE","")) } ,\
EXT_CYC_DATE { sprintf("20%i.%0.2i.%0.2i",ReadingsVal("$name","A_CYC_YEAR",""), ReadingsVal("$name","A_CYC_MONTH",""), ReadingsVal("$name","A_CYC_DAY","")) } ,\
EXT_CYC_FILTER_CHANGED_DATE { sprintf("20%i.%0.2i.%0.2i",ReadingsVal("$name","A_CYC_FILTER_CHANGED_YEAR",""), ReadingsVal("$name","A_CYC_FILTER_CHANGED_MONTH",""), ReadingsVal("$name","A_CYC_FILTER_CHANGED_DAY","") ) },\
EXT_CYC_STATE {\
if (ReadingsVal("$name","A_CYC_BOOST_TIMER","?") > 0 ) {sprintf("%s", "Boost")}\
elsif (ReadingsVal("$name","A_CYC_FIREPLACE_TIMER","?") > 0 ) {sprintf("%s", "Fireplace")}\
elsif (ReadingsVal("$name","A_CYC_STATE","?") == 0 ) {sprintf("%s", "Home")}\
else {sprintf("%s", "Away")}\
}, \
EXT_CYC_CELL_STATE {\
if (ReadingsVal("$name","A_CYC_CELL_STATE","?") == 0 ) {sprintf("%s", "WRG")}\
elsif (ReadingsVal("$name","A_CYC_CELL_STATE","?") == 1 ) {sprintf("%s", "KRG")}\
elsif (ReadingsVal("$name","A_CYC_CELL_STATE","?") == 2 ) {sprintf("%s", "Bypass")}\
elsif (ReadingsVal("$name","A_CYC_CELL_STATE","?") == 3 ) {sprintf("%s", "Defrost")}\
else {sprintf("%s", "?")}\
}
Hier habe ich mich für ein DOIF entschieden, um alle Steuerungsaktivitäten aus einer Definition heraus zu steuern.
1) Sobald im Dummy das Profil geändert wird
2) Alle 5 Minuten den Status abfragen
3) Wenn das KWL_Status.pl Skript den Output ins FHEM geschrieben hat wird mit expandJSON alles in readings geschrieben und im Anschluss der Intervall Timer noch publiziert.
defmod KWL_Call DOIF ##\
## Ändert sich in KWL_Control das Profil, dann sende es zur KWL\
##\
([KWL_Control:Profil])\
({system("/usr/bin/python /opt/fhem/python/bin/kwl_set_profil.py ".ReadingsVal("KWL_Control","KWL_Ip-Adress","?")." ".ReadingsVal("KWL_Control","Profil","?")." &")}\
{fhem("setreading KWL_Control KWL_next_polling ".ReadingsVal("KWL_Call","timer_01_c02","?"))}\
{fhem("setreading KWL_Status KWL_next_polling ".ReadingsVal("KWL_Call","timer_01_c02","?"))}\
{Log 1, "KWL Profil geändert"})\
##\
## Abfrage der KWL in 5 Minuten Intervallen\
##\
DOELSEIF ([+00:05:00])\
{system("/usr/bin/python /opt/fhem/python/bin/kwl_status.py ".ReadingsVal("KWL_Control","KWL_Ip-Adress","?")." ".ReadingsVal("KWL_Control","FHEM_Ip-Adress","?")." &")}\
{Log 1, "KWL polling"}\
##\
## Publiziere den Intervall Timer\
##\
DOELSEIF ([KWL_Status:EXT_CYC_TIME])\
{fhem("setreading KWL_Control KWL_next_polling ".ReadingsVal("KWL_Call","timer_01_c02","?"))}\
{fhem("setreading KWL_Status KWL_next_polling ".ReadingsVal("KWL_Call","timer_01_c02","?"))}\
{Log 1, "KWL new intervall"}
attr KWL_Call alias KWL_Call
attr KWL_Call checkReadingEvent 1
attr KWL_Call cmdState Profil geändert|KWL polling|KWL polling finished
attr KWL_Call do always
attr KWL_Call group KWL
attr KWL_Call icon file_manpage
attr KWL_Call room Heizung->System
attr KWL_Call sortby 04
attr KWL_Call verbose 0
Und dann noch den folgenden zwei Python Skripten:
fhem@raspberrypi:~/python/bin$ pwd
/opt/fhem/python/bin
fhem@raspberrypi:~/python/bin$ cat kwl_set_profil.py
# import logging
# logging.basicConfig(level=logging.DEBUG)
import json
import asyncio
from vallox_websocket_api import Vallox, PROFILE
import sys
kwl = sys.argv[1]
profile = sys.argv[2]
try:
with open('/opt/fhem/python/pwd.json', 'r') as f:
credentials=json.load(f)
except Exception as e:
print('Something went wrong: {}'.format(e))
client = Vallox(kwl) # Vallox unit IP
async def run():
await client.get_profile() # RETURNS a PROFILE.* value
if profile == "1":
await client.set_profile(PROFILE.HOME) # Permanently HOME profile
elif profile == "2":
await client.set_profile(PROFILE.AWAY) # Permanently AWAY profile
elif profile == "3":
await client.set_profile(PROFILE.BOOST) # BOOST profile for configured time ( 30 minutes )
elif profile == "4":
await client.set_profile(PROFILE.FIREPLACE) # FIREPLACE mode for configured timeout
else:
await client.set_profile(PROFILE.AWAY) # Permanently AWAY profile
asyncio.get_event_loop().run_until_complete(run())
fhem@raspberrypi:~/python/bin$ pwd
/opt/fhem/python/bin
fhem@raspberrypi:~/python/bin$ cat kwl_status.py
# import logging
# logging.basicConfig(level=logging.DEBUG)
import fhem
import json
import asyncio
from vallox_websocket_api import Client
import sys
kwl = sys.argv[1]
web = sys.argv[2]
try:
with open('/opt/fhem/python/pwd.json', 'r') as f:
credentials=json.load(f)
except Exception as e:
print('Something went wrong: {}'.format(e))
client = Client(kwl)
async def run():
# metrics = await client.fetch_metrics()
metrics = await client.fetch_metrics([
'A_CYC_TEMP_EXHAUST_AIR',
'A_CYC_TEMP_EXTRACT_AIR',
'A_CYC_TEMP_OUTDOOR_AIR',
'A_CYC_TEMP_SUPPLY_AIR',
'A_CYC_TEMP_SUPPLY_CELL_AIR',
'A_CYC_MODE',
'A_CYC_STATE',
'A_CYC_FAN_SPEED',
'A_CYC_CELL_STATE',
'A_CYC_IN_BYPASS',
'A_CYC_MACHINE_MODEL',
'A_CYC_DAY',
'A_CYC_MONTH',
'A_CYC_YEAR',
'A_CYC_HOUR',
'A_CYC_MINUTE',
'A_CYC_MACHINE_MODEL',
'A_CYC_MACHINE_TYPE',
'A_CYC_FILTER_CHANGED_DAY',
'A_CYC_FILTER_CHANGED_MONTH',
'A_CYC_FILTER_CHANGED_YEAR',
'A_CYC_REMAINING_TIME_FOR_FILTER',
'A_CYC_BOOST_TIMER',
'A_CYC_FIREPLACE_TIMER',
'A_CYC_EXTRA_TIMER'
])
message = json.dumps(metrics)
from pprint import pprint
# pprint(message)
# pprint(metrics)
fh = fhem.Fhem(web, protocol="https", port=8083, username=credentials["username"], password=credentials["password"])
fh.send_cmd("setreading KWL_Status output " + message)
asyncio.get_event_loop().run_until_complete(run())
Ich habe bei mir standardmäßig bereits python auf python3 umgestellt, da ich bisher kein python verwendet habe.
pi@raspberrypi:~ $cd /usr/bin
pi@raspberrypi:~ $ ls -l /usr/bin/python
lrwxrwxrwx 1 root root 7 Aug 22 11:19 /usr/bin/python -> python3
pi@raspberrypi:~ $ sudo rm python
pi@raspberrypi:~ $ sudo ln -s python3 python
pi@raspberrypi:~ $ python --version
Python 3.5.3
Dann noch die Python Erweiterungen nicht vergessen
fhem@raspberrypi:~/python/bin$ pip install vallox-websocket-api
Collecting vallox-websocket-api
Using cached https://www.piwheels.org/simple/vallox-websocket-api/vallox_websocket_api-2.2.0-py2.py3-none-any.whl
Collecting construct<3.0.0,>=2.9.0 (from vallox-websocket-api)
Using cached https://www.piwheels.org/simple/construct/construct-2.9.45-py3-none-any.whl
Collecting websockets<8.0,>=7.0 (from vallox-websocket-api)
Using cached https://www.piwheels.org/simple/websockets/websockets-7.0-cp35-cp35m-linux_armv6l.whl
Installing collected packages: construct, websockets, vallox-websocket-api
Successfully installed construct-2.9.45 vallox-websocket-api-2.2.0 websockets-7.0
fhem@raspberrypi:~/python/bin$ pip install fhem
Collecting fhem
Downloading https://www.piwheels.org/simple/fhem/fhem-0.6.2-py2.py3-none-any.whl
Installing collected packages: fhem
Successfully installed fhem-0.6.2
Viele Grüße
Christian