FHEM runs Python (fhem_pythonbinding)

Begonnen von dominik, 23 Oktober 2020, 20:50:56

Vorheriges Thema - Nächstes Thema

dominik

Hallo zusammen,

ich habe nun ein paar Monate daran gearbeitet eine Schnittstelle in FHEM für Python zu bauen. Nachdem ich damit schon einige Module entwickelt habe und somit erste Tests sehr vielversprechend sind, wollte ich hier auch in der Entwicklerrunde darüber informieren.

Warum Python?
Ich war in meinen laufenden Modulentwicklungen immer wieder vor der Herausforderung gestanden, dass es keine oder nur wenige Libraries gab die ich verwenden konnte. Somit musste ich immer sehr viel Zeit in die Entwicklung von Grund auf stecken. Python bietet eine Vielzahl an Modulen die mir die Entwicklung erleichtern - siehe auch https://pypi.org/. Das hat sich in den letzten Wochen bestätigt, innerhalb kurzer Zeit habe ich 14 Module geschrieben, darunter auch neue Sachen wie ring Doorbell, Xiaomi Gateway3, Nespresso Bluetooth, ...

Heißt das ich kann nun native Python Module schreiben?
Ja! Noch dazu wird asyncio verwendet, was viele Vorteile bei der asynchronen Programmierung mit sich bringt.

Wie funktioniert das?
Ganz einfach, es läuft neben FHEM noch ein Python Server, der wird von FHEM aus gestartet/beendet. FHEM verbindet sich via WebSocket zum Python Server und sendet die Information was in Python auszuführen ist (Define, Set, ...). Alle Module werden durch den Typ "PythonModule" definiert und stellen damit die Verbindung via DevIo zu Python her.
Details dazu hier: https://github.com/dominikkarall/fhem_pythonbinding#call-flow

Welche anderen Vorteile bieten WebSockets?
Alle Module die für das Python Binding entwickelt werden, können sowohl lokal oder auf einem remote Device laufen. Das erlaubt jegliche "Range Extension" für Bluetooth oder ähnliches. Im Modul muss dafür nichts speziell programmiert werden.

Läuft schon alle stabil?
Mehr oder weniger, ich wage noch nicht "ja" zu sagen. Einige User testen bereits erfolgreich und aktuell gibt es kaum Rückmeldungen zu Fehlern.

Welche Module gibt es bereits?
Hier die wahrscheinlich interessantesten:
- GoogleCast
- DLNA DMR
- EQ3BT
- Nespresso BLE
- Ring Doorbell / Chime / Cam
- Wiener Linien Abfahrtszeiten
- Xiaomi Gateway 3
- Xiaomi Tokens via MiCloud
Die gesamte List ist hier zu finden: https://github.com/dominikkarall/fhem_pythonbinding#fhem-python-binding-beta-might-not-be-stable

Nun, und wie kann ich das testen?
Einfach der Installationsanleitung (6 Schritte) folgen:
https://github.com/dominikkarall/fhem_pythonbinding#installation

Wie kann ich selbst ein Modul in Python schreiben?
Kopiere dazu einfach den helloworld Ordner und benenne Ordner, Python Datei und Class um. Danach kannst du schon mal ein define machen und ausprobieren ob es klappt.

Kann ich Standard FHEM Funktionen nutzen?
Ja, readingsSingleUpdate, etc. ist nutzbar. Achtung, nicht alle Funktionen sind aktuell implementiert. Sieht dann so aus:
await fhem.readingsSingleUpdate(self.hash, "state", "active", 1)

Wer Interesse hat, kann gerne testen und mir Rückmeldung geben oder Pull requests / Issues auf github aufmachen. Vielleicht können wir das irgendwann auch mal in den Main Code von FHEM aufnehmen und Standard machen, das möchte ich hier jedoch nicht diskutieren. Mir geht es vorerst darum Erfahrungen zu sammeln und eine schnellere Entwicklung vorantreiben.

Viel Spaß!
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

zap

Dein Beispiel oben mit dem Reading Update: Warum steht da ein await davor? In dem Fall würde das Update nicht asynchron erfolgen, oder? Zumindest wenn await das gleiche bedeutet wie bei Nodejs.
2xCCU3, Fenster, Rollläden, Themostate, Stromzähler, Steckdosen ...)
Entwicklung: FHEM auf AMD NUC (Ubuntu)
Produktiv inzwischen auf Home Assistant gewechselt.
Maintainer: FULLY, Meteohub, HMCCU, AndroidDB

dominik

Zitat von: zap am 24 Oktober 2020, 17:39:07
Dein Beispiel oben mit dem Reading Update: Warum steht da ein await davor? In dem Fall würde das Update nicht asynchron erfolgen, oder? Zumindest wenn await das gleiche bedeutet wie bei Nodejs.

Genau, await ist wie in NodeJS. In Python nutze ich asyncio (https://docs.python.org/3/library/asyncio.html). Jede Nachricht von FHEM ist ein eigener Task in asyncio. Somit läuft jedes Modul "parallel".

Alte Libraries, die noch nicht asyncio nutzen und somit "richtig" blockieren, können in einen asyncio Thread ausgelagert werden und laufen dann ebenfalls in der asyncio Loop. Neue Libraries nutzen bereits asyncio und müssen daher nie in einen eigenen Thread ausgelagert werden.
Z.B. kann ein kompletter HTTP Download mit der aiohttp Lib durchgeführt werden ohne dafür einen extra Thread zu erstellen. Das asyncio ist wirklich genial wenn man es mal durchschaut hat.
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

Prof. Dr. Peter Henning


dominik

#4
Ich habe gerade eine Image Recognition mit TensorFlow Lite integriert :)

Man kann nun Snapshots der Webcam speichern und diese auswerten lassen. TensorFlow Lite erkennt 91 Objekte (Person, Vogel, ...).
Die Installation setzt folgendes voraus:
https://github.com/dominikkarall/fhem_pythonbinding/blob/master/FHEM/bindings/python/lib/object_detection/README.md

Anbei ein Bild damit man sich das ganze vorstellen kann was da passiert...in FHEM werden die entsprechendes Readings dafuer erstellt.
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

zap

Das scheint Potenzial zu haben. Mal gesponnen: Möglicherweise ein Weg, FHEM sanft von Perl auf etwas moderneres umzustellen. Vor allem die strikte Trennung von Threads und Asynchronität wären ein enormer Fortschritt.

Vielleicht stelle ich eines meiner einfacheren Module mal auf Python um. Der Haken ist halt, dass man trotzdem nicht um eine komplette Neuentwicklung rum kommt. Aber es eilt ja nicht, da beides parallel bzw miteinander funktioniert.
2xCCU3, Fenster, Rollläden, Themostate, Stromzähler, Steckdosen ...)
Entwicklung: FHEM auf AMD NUC (Ubuntu)
Produktiv inzwischen auf Home Assistant gewechselt.
Maintainer: FULLY, Meteohub, HMCCU, AndroidDB

Christoph Morrison

Zitat von: zap am 25 Oktober 2020, 15:16:32
Das scheint Potenzial zu haben. Mal gesponnen: Möglicherweise ein Weg, FHEM sanft von Perl auf etwas moderneres umzustellen. Vor allem die strikte Trennung von Threads und Asynchronität wären ein enormer Fortschritt.

Vorneweg: Ich habe nix gegen Python und benutze die Sprache auch, aber:

Vielleicht wäre ein Weg, erstmal Perl überhaupt zu benutzen, inkl. der Myriaden von Paketen, die CPAN anbietet. Richard hatte hier ja viele, viele wunde Punkte benannt, aber ich kann aktuell nur wenige Fortschritte und gar keine Strategie sehen.

dominik

Zitat von: Christoph Morrison am 25 Oktober 2020, 15:56:25
Vorneweg: Ich habe nix gegen Python und benutze die Sprache auch, aber:

Vielleicht wäre ein Weg, erstmal Perl überhaupt zu benutzen, inkl. der Myriaden von Paketen, die CPAN anbietet. Richard hatte hier ja viele, viele wunde Punkte benannt, aber ich kann aktuell nur wenige Fortschritte und gar keine Strategie sehen.

Leider bietet cpan aber nicht so viele Libraries wie Python in dem Bereich wo ich Module schreibe, ein paar Beispiele aus meinen letzten Modulen:
- Bluetooth / BLE: Konnte bis jetzt keine Perl Library finden die funktioniert. In Python gibt es gleich mehrere.
- DLNA: Leider ebenfalls nichts was "einfach" funktioniert
- Chromecast: Nichts vorhanden
- EQ3BT: Nichts vorhanden
- TensorFlow Lite: Nichts vorhanden

Das letzte Beispiel mit Object Recognition in Bildern hat mich da nochmals bestätigt, ich habe das Modul innerhalb eines Tages gebaut. Das hätte ich in Perl nie in der Zeit geschafft.

Wie in meinem Post oben schon erwähnt, es geht hier nicht darum FHEM mit Python neu aufzubauen, ich will damit einfach nur schneller Module entwickeln können und davon sollen gerne andere auch profitieren. Daher stelle ich das alles zur Verfügung.
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

dominik

Zitat von: zap am 25 Oktober 2020, 15:16:32
Das scheint Potenzial zu haben. Mal gesponnen: Möglicherweise ein Weg, FHEM sanft von Perl auf etwas moderneres umzustellen. Vor allem die strikte Trennung von Threads und Asynchronität wären ein enormer Fortschritt.

Vielleicht stelle ich eines meiner einfacheren Module mal auf Python um. Der Haken ist halt, dass man trotzdem nicht um eine komplette Neuentwicklung rum kommt. Aber es eilt ja nicht, da beides parallel bzw miteinander funktioniert.

Würde mich freuen wenn du auch eines deiner Module mal in Python probierst, da aktuell nur ich selbst Module entwickelt habe. Ich nutze Visual Studio Code (unter Linux) dazu, da geht das echt schnell dahin.
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik

Prof. Dr. Peter Henning

Auch wenn unser "Handbuch Programmiersprachen" inzwischen 14 Jahre alt ist, sind viele der darin vorgenommenen Vergleiche nach wie vor gültig.
Eine Sprache wie Perl ist nicht bereits deshalb schlecht, weil sie schon lange existiert. Ganz im Gegenteil erlaubt sie viele Dinge, die in Python nicht möglich sind - und ist darum insbesondere für Leute geeignet, die keine oder wenig Programmierkenntnisse haben.

Wir müssten also eigentlich einen anderen Weg gehen, als jetzt dem Perl-Kern von FHEM die Ausführung von Python-Modulen zu ermöglichen.

Nämlich den Kern von FHEM - beginnend mit der Hauptschleife - in Python neu zu bauen und mit einem Wrapper für Perl zu versehen, der bestehende FHEM-Module nach wie vor zu nutzen erlaubt.

LG

pah

zap

Ich will Perl hier nicht verteufeln. Mit geht es darum, Features nutzen zu können, die neue Programmiersprachen wie Python oder NodeJS bereitstellen. Klar, kann man alles irgendwie auch in Perl nachbauen. Ob der Aufwand sinnvoll ist, lasse ich mal dahingestellt.
Dinge wie Asynchronität sind schön, richtig wichtig wäre m.E. die prozessuale Trennung der Module.

Python ist auch nicht schwerer zu lernen als Perl, meiner Meinung nach sogar leichter. Es muss ja auch nicht zwingend Python sein. Es kann auch Kotlin, Javascript/NodeJs oder etwas anderes sein. Es gibt gerade bei den Neueinsteigern in die Smarthome Entwicklung wesentlich mehr Leute, die die o.g. Sprachen beherrschen als Perl.
2xCCU3, Fenster, Rollläden, Themostate, Stromzähler, Steckdosen ...)
Entwicklung: FHEM auf AMD NUC (Ubuntu)
Produktiv inzwischen auf Home Assistant gewechselt.
Maintainer: FULLY, Meteohub, HMCCU, AndroidDB

dominik

Zur Info, ich habe gerade noch object_detection um Videostream erweitert.

Damit kann man nun in Videos Personen/Tiere/... erkennen lassen.

Siehe:
https://github.com/dominikkarall/fhem_pythonbinding/blob/master/FHEM/bindings/python/lib/object_detection/README.md

Im README Beispiel wird der Livestream von ServusTV analysiert :) Das sollte dann auch mit Kamera Streams funktionieren, ich selbst habe leider keine.
fhempy -  https://github.com/fhempy/fhempy: GoogleCast, Tuya, UPnP, Ring, EQ3BT, Nespresso, Xiaomi, Spotify, Object Detection, ...
Kaffeespende: https://paypal.me/todominik