Neues Python FHEM API-Modul auf PyPI

Begonnen von domschl, 01 Januar 2017, 12:15:41

Vorheriges Thema - Nächstes Thema

domschl

Das ist noch holper-pyhton ;-)

    fh = fhem.Fhem("" + web + "", protocol="https", port=8083, username="" + format(credentials["username"]) + "" , password="" + format(credentials["password"]) + "")


Einfacher:

    fh = fhem.Fhem("" + web + "", protocol="https", port=8083, username=credentials["username"] , password=credentials["password"])


ch.eick

#46
Zitat von: domschl am 21 August 2019, 18:56:46
Das ist noch holper-pyhton ;-)

Ich habe ja heute das erste mal Python gelesen  :'( nicht schimpfen.

schon erledigt

fh = fhem.Fhem(web, protocol="https", port=8083, username=credentials["username"], password=credentials["password"])


Und was ist mit?

fh.send_cmd("setreading KWL output " + message)


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

domschl

Zum Namen vom Python-Modul, da das ja letztlich doch öfter diskutiert wird:

- Es ist im Python-Land gang und gäbe, daß eine Client-API einfach so wie der Server heißt. Z.b. zugriff auf die Redis-Datenbank geht über "import redis"
- Das gleiche Prinzip wird auch im FHEM verwendet: Viele der Module heissen genauso wie das Produkt/die Software auf die sie zugreifen.

Übersehe ich da was?

domschl

das setreading ist ok: es werden ja nur zwei Strings zusammengebaut.

Da gibt's keinen Grund das komplizierter zu machen.

ch.eick

Zitat von: domschl am 21 August 2019, 19:10:07
Zum Namen vom Python-Modul, da das ja letztlich doch öfter diskutiert wird:

- Es ist im Python-Land gang und gäbe, daß eine Client-API einfach so wie der Server heißt. Z.b. zugriff auf die Redis-Datenbank geht über "import redis"
- Das gleiche Prinzip wird auch im FHEM verwendet: Viele der Module heissen genauso wie das Produkt/die Software auf die sie zugreifen.

Übersehe ich da was?

Wenn das so Python Standard ist, dann würde ich das auch so unterstützen.
Works as designed

Ich hatte nur bisher diese Begründung nirgends gelesen.

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

ch.eick

Hallo zusammen und entschuldigt bitte, dass ich diesen Post hier wiederhole.
Ich denke hier passt er besser rein.

jetzt versuche ich gerade das Python 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>")}


Für die Kopplung verwende ich das Python FHEM API-Modul, das bei Aufruf über system() folgende Fehler ausgibt.
In dieser Laufzeitumgebung scheint es ein Problem mit "CSRF token not available!" zu geben.

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

ch.eick

#51
Moin,

Ihr könntet mir sehr weiterhelfen.
Leider habe ich keine Python Kenntnisse, doch die erste Implementierung ist sehr vielversprechend und ich würde diese Python Fhem Kopplung wirklich gerne verwenden.

Dieser Aufruf als Benutzer fhem in einer Shell funktioniert

DEBUG:Fhem:Setting up opener on: https://<IP Adresse>:8083/
DEBUG:Fhem:Cmd:
DEBUG:Fhem:Cmd-enc:

INFO:Fhem:Request: https://<IP Adresse>:8083/fhem

DEBUG:Fhem:Sending: setreading KWL output {"A_CYC_TEMP_EXHAUST_AIR": 32.3, "A_CYC_TEMP_SUPPLY_AIR": 27.4, "A_CYC_TEMP_EXTRACT_AIR": 26.3, "A_CYC_TEMP_OUTDOOR_AIR": 33.0, "A_CYC_TEMP_SUPPLY_CELL_AIR": 26.1}

DEBUG:Fhem:Cmd: setreading KWL output {"A_CYC_TEMP_EXHAUST_AIR": 32.3, "A_CYC_TEMP_SUPPLY_AIR": 27.4, "A_CYC_TEMP_EXTRACT_AIR": 26.3, "A_CYC_TEMP_OUTDOOR_AIR": 33.0, "A_CYC_TEMP_SUPPLY_CELL_AIR": 26.1}

DEBUG:Fhem:Cmd-enc: setreading%20KWL%20output%20%7B%22A_CYC_TEMP_EXHAUST_AIR%22%3A%2032.3%2C%20%22A_CYC_TEMP_SUPPLY_AIR%22%3A%2027.4%2C%20%22A_CYC_TEMP_EXTRACT_AIR%22%3A%2026.3%2C%20%22A_CYC_TEMP_OUTDOOR_AIR%22%3A%2033.0%2C%20%22A_CYC_TEMP_SUPPLY_CELL_AIR%22%3A%2026.1%7D

INFO:Fhem:Request: https://<IP Adresse>:8083/fhem?XHR=1&cmd=setreading%20KWL%20output%20%7B%22A_CYC_TEMP_EXHAUST_AIR%22%3A%2032.3%2C%20%22A_CYC_TEMP_SUPPLY_AIR%22%3A%2027.4%2C%20%22A_CYC_TEMP_EXTRACT_AIR%22%3A%2026.3%2C%20%22A_CYC_TEMP_OUTDOOR_AIR%22%3A%2033.0%2C%20%22A_CYC_TEMP_SUPPLY_CELL_AIR%22%3A%2026.1%7D


Und so sieht der Debug mit dem Aufruf über ein FHEM Notify aus.

defmod KWL_poll at +*01:00:00 {system("/usr/bin/python /opt/fhem/python/bin/kwl_status.py <IP kwl> <IP FHEM>")}


DEBUG:Fhem:Setting up opener on: https://<IP FHEM>:8083/
DEBUG:Fhem:Cmd:
DEBUG:Fhem:Cmd-enc:

INFO:Fhem:Request: https://<IP FHEM>:8083/fhem

ERROR:Fhem:Failed to send msg, len=0, <urlopen error _ssl.c:704: The handshake operation timed out>
ERROR:Fhem:No valid answer on send when expecting csrf.

DEBUG:Fhem:Sending: setreading KWL output {"A_CYC_TEMP_EXTRACT_AIR": 26.5, "A_CYC_TEMP_SUPPLY_AIR": 27.7, "A_CYC_TEMP_SUPPLY_CELL_AIR": 26.2, "A_CYC_TEMP_EXHAUST_AIR": 32.5, "A_CYC_TEMP_OUTDOOR_AIR": 33.0}
DEBUG:Fhem:Not connected, trying to connect...
DEBUG:Fhem:Cmd:
DEBUG:Fhem:Cmd-enc:

INFO:Fhem:Request: https://<IP FHEM>:8083/fhem

ERROR:Fhem:Failed to send msg, len=0, <urlopen error _ssl.c:704: The handshake operation timed out>
ERROR:Fhem:No valid answer on send when expecting csrf.
ERROR:Fhem:CSRF token not available!

DEBUG:Fhem:Cmd: setreading KWL output {"A_CYC_TEMP_EXTRACT_AIR": 26.5, "A_CYC_TEMP_SUPPLY_AIR": 27.7, "A_CYC_TEMP_SUPPLY_CELL_AIR": 26.2, "A_CYC_TEMP_EXHAUST_AIR": 32.5, "A_CYC_TEMP_OUTDOOR_AIR": 33.0}

DEBUG:Fhem:Cmd-enc: setreading%20KWL%20output%20%7B%22A_CYC_TEMP_EXTRACT_AIR%22%3A%2026.5%2C%20%22A_CYC_TEMP_SUPPLY_AIR%22%3A%2027.7%2C%20%22A_CYC_TEMP_SUPPLY_CELL_AIR%22%3A%2026.2%2C%20%22A_CYC_TEMP_EXHAUST_AIR%22%3A%2032.5%2C%20%22A_CYC_TEMP_OUTDOOR_AIR%22%3A%2033.0%7D

INFO:Fhem:Request: https://<IP FHEM>:8083/fhem?XHR=1&cmd=setreading%20KWL%20output%20%7B%22A_CYC_TEMP_EXTRACT_AIR%22%3A%2026.5%2C%20%22A_CYC_TEMP_SUPPLY_AIR%22%3A%2027.7%2C%20%22A_CYC_TEMP_SUPPLY_CELL_AIR%22%3A%2026.2%2C%20%22A_CYC_TEMP_EXHAUST_AIR%22%3A%2032.5%2C%20%22A_CYC_TEMP_OUTDOOR_AIR%22%3A%2033.0%7D
ERROR:Fhem:Failed to send msg, len=185, <urlopen error _ssl.c:704: The handshake operation timed out>


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

Und noch ein Status :-)

Ich habe nun bei dem system() Aufruf das Kommando mit "&" in den Hintergrung geschickt.
Eventuell kann mir ja jemand jetzt erklären, warum es nun läuft???

defmod KWL_poll at +*01:00:00 {system("/usr/bin/python /opt/fhem/python/bin/kwl_status.py <IP KWL> <IP FHEM> &")}


Bei system(... &) läuft die https Verbindung vom Python zum FHEM nun.

DEBUG:Fhem:Setting up opener on: https://<IP FHEM>:8083/
DEBUG:Fhem:Cmd:
DEBUG:Fhem:Cmd-enc:

INFO:Fhem:Request: https://<IP FHEM>:8083/fhem

DEBUG:Fhem:Sending: setreading KWL output {"A_CYC_TEMP_SUPPLY_AIR": 27.6, "A_CYC_TEMP_SUPPLY_CELL_AIR": 26.1, "A_CYC_TEMP_EXTRACT_AIR": 26.4, "A_CYC_TEMP_EXHAUST_AIR": 32.0, "A_CYC_TEMP_OUTDOOR_AIR": 32.5}

DEBUG:Fhem:Cmd: setreading KWL output {"A_CYC_TEMP_SUPPLY_AIR": 27.6, "A_CYC_TEMP_SUPPLY_CELL_AIR": 26.1, "A_CYC_TEMP_EXTRACT_AIR": 26.4, "A_CYC_TEMP_EXHAUST_AIR": 32.0, "A_CYC_TEMP_OUTDOOR_AIR": 32.5}

DEBUG:Fhem:Cmd-enc: setreading%20KWL%20output%20%7B%22A_CYC_TEMP_SUPPLY_AIR%22%3A%2027.6%2C%20%22A_CYC_TEMP_SUPPLY_CELL_AIR%22%3A%2026.1%2C%20%22A_CYC_TEMP_EXTRACT_AIR%22%3A%2026.4%2C%20%22A_CYC_TEMP_EXHAUST_AIR%22%3A%2032.0%2C%20%22A_CYC_TEMP_OUTDOOR_AIR%22%3A%2032.5%7D

INFO:Fhem:Request: https://<IP FHEM>:8083/fhem?XHR=1&cmd=setreading%20KWL%20output%20%7B%22A_CYC_TEMP_SUPPLY_AIR%22%3A%2027.6%2C%20%22A_CYC_TEMP_SUPPLY_CELL_AIR%22%3A%2026.1%2C%20%22A_CYC_TEMP_EXTRACT_AIR%22%3A%2026.4%2C%20%22A_CYC_TEMP_EXHAUST_AIR%22%3A%2032.0%2C%20%22A_CYC_TEMP_OUTDOOR_AIR%22%3A%2032.5%7D


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

domschl

Release 0.6.3 ist nun auf PyPi verfügbar.

Bugfixes:
* Bug von @TK67 bzgl. Exception Meldungen bei Socket-Verbindungen sollte gelöst sein,
* Bug von party-pansen bzgl. crashes bei ungesichertem parsen von FhemEventQueue datetimes gelöst,
* Der Selbst-Test checked jetzt auf die FhemEventQueue Klasse.

Details zu den Versionen und fixes https://github.com/domschl/python-fhem#history
Update wie immer mit:

pip install -U fhem

ROMASI

Hallo, ich dreh am Rad
Erst mal Danke für die Tolle Anleitung zum Einbinden des Vallox-Lüfters Konkret habe ich einen Vallox mv520. Auf der Shell Ebene funktionieren deine py-scripte auch prima, aber wenn ich das aus FHEM heraus aufrufe bekomme ich den gleichen Fehler wie bei dir hier im Thread kurz zuvor beschrieben:
2019.10.30 11:01:56 1: KWL Profil geändert
Traceback (most recent call last):
  File "/opt/fhem/python/bin/kwl_set_profil.py", line 8, in <module>
    from vallox_websocket_api import Vallox, PROFILE
ImportError: No module named 'vallox_websocket_api'


Wenn ich kwl_status.py aus FHEM heraus aufgerufen wird erscheint der gleiche Fehler jedoch mit der FHEM-API
ImportError: No module named 'fhem'


Ich rufe die Scripte auf mit:
{system("/usr/bin/python3.5 /opt/fhem/python/bin/kwl_set_profil.py IPKWS.x.x.x IP-Fehm.x.x.x &")}

Das API Python Paket habe ich installiert mit:
sudo pip3 install vallox_websocket_api
sudo pip3 install fhem


Wie gesagt über den Shell-Auftuf mit dem User Pi funktioniert alles.
Die Py-Scripts stehen auch wie in deinem Beispiel unter /opt/fhem/python/bin

Ich konnte aus dem weiteren Verlauf der Antworten hier im Forum aber nicht ersehen wie du den Fehler weg bekommen hast.

Eventuell kann mir hier jemand auf die Sprünge helfen.

Viele Grüße
Ronald


ch.eick

#55
Hallo Ronald,

ich habe bei mir die Installation genau so wie beschrieben vorgenommen.

fhem@raspberrypi:~$ python --version
Python 3.5.3

Wie man im Python die installierte Version der Module abfragt habe ich noch nicht gefunden. Ich kenne mich mit Python nicht aus.
Ich bin nur in der Lage die verstreuten Codemuster zu kombinieren :-)
Hier nochmal eins meiner aktuellen Skripte. Am Anfang sind für das Debugging zwei Zeilen auskommentiert, das könntest Du ja mal einschalten und die Meldungen verfolgen. Zum Ende des Skriptes sind auch noch zwei print Ausgaben, damit man auf der Shell die gelesenen Werte sehen kann.

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',
      'A_CYC_EXTRA_TIMER_ENABLED',
      'A_CYC_EXTRA_ENABLED',
      'A_CYC_EXTRA_EXTR_FAN',
      'A_CYC_EXTRA_SUPP_FAN'
    ])

    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())


Die Module habe ich auch mit dem user pi installiert.
Ich meine es war auch wichtig in welche Pythen Version man die Module installiert. Deshalb habe ich das Python unter /usr/bin direkt auf Version python3 verlinkt

pi@raspberrypi:~ $ cd /usr/bin

# sudo rm python
# sudo ln -s python3 python

pi@raspberrypi:/usr/bin $ ls -l python*
lrwxrwxrwx 1 root root       7 Aug 22 11:19 python -> python3
lrwxrwxrwx 1 root root       9 Jan 24  2017 python2 -> python2.7
-rwxr-xr-x 1 root root 3166320 Sep 26  2018 python2.7
lrwxrwxrwx 1 root root      36 Sep 26  2018 python2.7-config -> arm-linux-gnueabihf-python2.7-config
lrwxrwxrwx 1 root root      16 Jan 24  2017 python2-config -> python2.7-config
lrwxrwxrwx 1 root root       9 Jan 20  2017 python3 -> python3.5
-rwxr-xr-x 2 root root 3976256 Sep 27  2018 python3.5
lrwxrwxrwx 1 root root      36 Sep 27  2018 python3.5-config -> arm-linux-gnueabihf-python3.5-config
-rwxr-xr-x 2 root root 3976256 Sep 27  2018 python3.5m
lrwxrwxrwx 1 root root      37 Sep 27  2018 python3.5m-config -> arm-linux-gnueabihf-python3.5m-config
lrwxrwxrwx 1 root root      16 Jan 20  2017 python3-config -> python3.5-config
lrwxrwxrwx 1 root root      10 Jan 20  2017 python3m -> python3.5m
lrwxrwxrwx 1 root root      17 Jan 20  2017 python3m-config -> python3.5m-config
lrwxrwxrwx 1 root root      16 Jan 24  2017 python-config -> python2.7-config


EDIT:
Und so kann man die Modulversion überprüfen:

fhem@raspberrypi:~$ python
Python 3.5.3 (default, Sep 27 2018, 17:25:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import fhem
>>> fhem.__version__
'0.6.3'

################################### Hier scheint keine Version eingetragen zu sein, aber zumindest wird es gefunden. ###########
>>> import vallox_websocket_api
>>> vallox_websocket_api.__version__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'vallox_websocket_api' has no attribute '__version__'



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

ROMASI

Hallo Christian
Vielen Dank für deine schnelle Antwort, ich beschäftige mich nun schon einige Zeit mit dem Problem und nach Lesen in etlichen Foren und Python Beschreibungen konnte ich das Problem:
"Nicht Laden der python import Module aus Fhem heraus"
lösen.
Dein Vorschlag auf Python3 als Standardversion umzustellen ist bei mir leider fehlgeschlagen. Ich habe auch mehrfach gelesen, dass diese Umstellung auf dem Raspi nicht empfohlen wird. Daher installiere ich die API-Pakete mit pip3 anstatt mit pip. Dein Python-skript starte ich aus Fhem heraus dann mit:
({system("/usr/bin/python3 /opt/fhem/python/bin/kwl_set_profil.py ....
Meinen eigentlichen Fehler konnte ich mit dem Befehl
pip3 show fhem
feststellen.  Da ich die API-Pakete mit pip3 ohne 'sudo' installiert hatte waren die Module nur für dem 'pi' User verfügbar und nicht aus Fhem heraus!
Richtig muss es heisen:
sudo pip3 install fhen
sudo pip3 install vallox-websocket-api

Dann sind die Pakete unter /usr/local/iib/... für alle User verfügbar
Was man dann wie dargestellt kontrollieren kann:
pi@fhem-sh-si:~ $ pip3 show fhem
Name: fhem
Version: 0.6.3
Summary: Python API for FHEM home automation server
Home-page: http://github.com/domschl/python-fhem
Author: Dominik Schloesser
Author-email: dsc@dosc.net
License: MIT
Location: /usr/local/lib/python3.5/dist-packages
Requires:
pi@fhem-sh-si:~ $


Jetzt funktioniert alles prima und ich kann die Vallox Lüftung dank deiner Skripts aus Fhem heraus steuern und auslesen.

Viele Grüße
Ronald

ch.eick

#57
Super, das freut mich.
Wie gesagt habe ich nur Beispiele kombiniert. Den Code haben andere geschrieben.

kwl_set_profile.py

fhem@raspberrypi:~/python/bin$ cat kwl_set_profil.py
# import logging
# logging.basicConfig(level=logging.DEBUG)

import fhem
import json
import asyncio
from vallox_websocket_api import Vallox, PROFILE

import sys
kwl     = sys.argv[1]
web     = sys.argv[2]
profile = sys.argv[3]

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
    elif profile == "5":
         await client.set_profile(PROFILE.EXTRA)     # EXTRA mode for configured timeout
    else:
         await client.set_profile(PROFILE.AWAY)      # Permanently AWAY profile


    fh = fhem.Fhem(web, protocol="https", port=8083, username=credentials["username"], password=credentials["password"])

    fh.send_cmd("set KWL_Call cmd_2")

asyncio.get_event_loop().run_until_complete(run())


kwl_status.py

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',
      'A_CYC_EXTRA_TIMER_ENABLED',
      'A_CYC_EXTRA_ENABLED',
      'A_CYC_EXTRA_EXTR_FAN',
      'A_CYC_EXTRA_SUPP_FAN'
    ])

    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())




Und hier die FHEM Integration

Diese Dummy representiert die KWL mit ihrem Status und dem Profil
Über einen Slider kann das Profil von 1-5 eingestellt werden.
Bei mit ist in der Vallox KWL das Profiel Stoßlüften mit 70% konfiguriert.
Mit dem EXTRA Profil habe ich dann die Möglichkeit für eine konfigurierte Zeit von 10 Minuten auf 100% Lüfter zu schalten. Das EXTRA Profil lässt sich nicht über das WEB Interface der Vallox konfigurieren, jedoch kann das mit einem Python Skript und dem Setzen der entsprechenden Register erledigt werden. Das Skript kommt am Ende dieses Posts.

defmod KWL_Control dummy
attr KWL_Control alias KWL_Control
attr KWL_Control comment Profile \
1=Anwesend/Home,\
2=Abwesend/Away,\
3=Stosslueften/Boost,\
4=Kaminfunktion/Fireplace\
5=Extra
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,5
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","?")\
)}


Hier wird der Status der KWL aufbereitet und das Profil aus verschiedenen Variablen ermittelt

defmod KWL_Status expandJSON KWL_Status:output:.\{.*}
attr KWL_Status alias KWL_Status
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_EXTRA_TIMER","?") > 0 ) {sprintf("%s", "Extra")}\
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", "?")}\
}


Das DOIF erledigt das Polling und die Kommunikation bei Änderungen wenn ein anderes Profil eingestellt wird.

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","FHEM_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


Hier das angekündigte Skript zum setzen des EXTRA Profils. Die Werte für die Lüfter und die Zeit kann jeder auf seine extra Wünsche einstellen :-)

fhem@raspberrypi:~/python/bin$ cat kwl_set_extra.py
# import logging
# logging.basicConfig(level=logging.DEBUG)

import fhem
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

    client.set_settable_address('A_CYC_EXTRA_ENABLED', int)
    client.set_settable_address('A_CYC_EXTRA_TIMER_ENABLED', int)

    # Setting Extra profile
    await client.set_values({
      'A_CYC_EXTRA_ENABLED': 1,
      'A_CYC_EXTRA_EXTR_FAN': 100,
      'A_CYC_EXTRA_SUPP_FAN': 100,
      'A_CYC_EXTRA_TIMER': 10,
      'A_CYC_EXTRA_TIMER_ENABLED': 1
      })

asyncio.get_event_loop().run_until_complete(run())




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

Forstling

Hallo

bei mir scheitert derzeit auch der Aufruf aus FHEM

Ich möchte einen PT1000 Temperaturfühler auslesen. Das funktioniert über einen MAX31865 Chip

Das Script kann ich ausführen und die Werte kommen auch bei FHEM an.

Wenn ich das Script über FHEM Aufrufe Schreibt es mir folgendes in Log:

Traceback (most recent call last):
  File "/opt/fhem/FHEM/Python/MAX31865.py", line 33, in <module>
    sensor = adafruit_max31865.MAX31865(spi, cs, wires=4)
  File "/usr/local/lib/python3.7/dist-packages/adafruit_max31865.py", line 107, in __init__
    config = self._read_u8(_MAX31865_CONFIG_REG)
  File "/usr/local/lib/python3.7/dist-packages/adafruit_max31865.py", line 123, in _read_u8
    device.write(self._BUFFER, end=1)
  File "/usr/local/lib/python3.7/dist-packages/busio.py", line 203, in write
    return self._spi.write(buf, start, end)
  File "/usr/local/lib/python3.7/dist-packages/adafruit_blinka/microcontroller/generic_linux/spi.py", line 49, in write
    self._spi.open(self._port, 0)
PermissionError: [Errno 13] Permission denied


Ich nehme an das ich hier ein Rechteproblem habe:

Kann mir jemand sagen wie ich das Löseß

amenomade

Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus