[gelöst] vallox_websocket_api mit fhem koppeln

Begonnen von ch.eick, 20 August 2019, 16:21:51

Vorheriges Thema - Nächstes Thema

ch.eick

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 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
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

Otto123

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
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

ch.eick

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
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

Otto123

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
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

ch.eick

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
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

Otto123

#5
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" keinen Rückgabewert liefern sondern ins Log schreiben.
Oder steh gerade völlig daneben :)
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

ch.eick

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");
}
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

Otto123

#7
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.
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

ch.eick

#8
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.
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

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ß.
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

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?
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

Otto123

#11
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
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

ch.eick

#12
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
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

#13
Die vorherige Kopplung zur Vallox Cloud ist hier

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.
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

#14
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
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick