HTTP API

Begonnen von klaus.schauer, 12 Juli 2022, 19:17:28

Vorheriges Thema - Nächstes Thema

klaus.schauer

Gibt es schon eine allgemein verwendbare HTTP API in Fhem mit der man set- und get-Befehle der Devices ausführen und deren Readings abfragen könnte, z. B. per

http://<ip-addr>:8085/api/set?device=<devname>&cmd=<cmd>
http://<ip-addr>:8085/api/get?device=<devname>&cmd=<cmd>
http://<ip-addr>:8085/api/read?device=<devname>&reading=<cmd>

oder wurde solch eine Funktionalität schon modulspezifisch verwendet?

rudolfkoenig


betateilchen

#2
oder vielleicht auch mit HTTPSRV?

Zitat  Provides a mini HTTP server plugin for FHEMWEB. It serves files from a given directory.
  It optionally accepts a query string to set readings of this device if an attribute allows the given reading<p>

  HTTPSRV is an extension to <a href="HTTPSRV">FHEMWEB</a>. You must install FHEMWEB to use HTTPSRV.</p>

Edit: ich glaube, das mit dem reading hatte ich falsch verstanden. Aber erste Versuche hier haben gerade gezeigt, dass HTTPSRV eine gute Basis sein könnte, eine solche API zu bauen :)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

klaus.schauer

Danke für die Tipps. HTTPSRV scheint wirklich eine gute Basis zu sein.

M.Schulze

Was hast du denn genau vor?

Ein Gerät mit einer vorgegebenen, fertigen HTTP API in FHEM integrieren?

Oder in deinem Gerät/Programm eine "FHEM friendly HTTP API" implementieren (z.B. mit POSTMAN), um sie "auch" mit FHEM zu nutzen, und ggf. auch zu standardisieren?


"FHEM friendly HTTP API" = "FHEM HTTP API" gibt es ja aktuell nicht. Weder eine API noch die Module dafür.


MfG
Muss ich das Licht aus machen?

klaus.schauer

Ziel ist es, Fhem Devices von externen Systemen aus über eine html-API zu steuern, auszulesen und zu beschreiben. Die erste Idee für die html-Sequenzen ist:

http://<ip-addr>:8083/fhem/api/set?device=<devname>&cmd=<cmd>
http://<ip-addr>:8083/fhem/api/get?device=<devname>&cmd=<cmd>
http://<ip-addr>:8083/fhem/api/read?device=<devname>&reading=<name>
http://<ip-addr>:8083/fhem/api/write?device=<devname>&reading=<name>&value=<val>

zap

Ich würde kein URL Encoding verwenden, sondern ein JSON API bauen (POST Requests). Ist sicherer, flexibler und es gibt sicher reichlich Beispiele dafür.

Beispiel:

POST http://ip:port/fhem/api

{
   "method": "set",
   "device": "myDev",
   "command": "state",
   "valuelist": [ 1, 2, 100 ]
}

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

klaus.schauer

Danke für die Anregung.

Ich verwende die Erweiterungsfunktion des zentralen Moduls FHEMWEB. Als Muster für das neue Modul dient das Modul HTTSRV. Soweit ich das beurteilen kann, übergibt FHEMWEB an ein plugin ausschließlich die url. Das klappt gut und ist für die Steuerung der Devices die einfachste Lösung.

Für die Rückgabewerte ist natürlich die JSON-Formatierung eine gute Alternative. 

klaus.schauer

Danke nochmals für die Tipps. Das Modul HTTPAPI ist jetzt fertig. Ich stelle es umgehend ins svn.

betateilchen


  my $fileName = $gPath . '/03_HTTPAPI.pm';


Bist Du sicher, dass das funktioniert?


  if(open(INPUTFILE, $fileName)) {
    binmode(INPUTFILE);
    @contents= <INPUTFILE>;


Zum Lesen von Dateien stellt FHEM die Funktion FileRead() bereit.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

klaus.schauer

Zitat von: betateilchen am 28 Juli 2022, 18:24:48

  my $fileName = $gPath . '/03_HTTPAPI.pm';


Bist Du sicher, dass das funktioniert?
Ne, ist aber schnell gelöst.

Zitat

  if(open(INPUTFILE, $fileName)) {
    binmode(INPUTFILE);
    @contents= <INPUTFILE>;


Zum Lesen von Dateien stellt FHEM die Funktion FileRead() bereit.
Wie praktisch, sehe ich mir an.

betateilchen

Zitat von: klaus.schauer am 28 Juli 2022, 20:42:10
Wie praktisch, sehe ich mir an.

hm... Du solltest aber auch an die Nutzer denken, die mit configDB arbeiten.

FileRead() unterscheidet beim Lesen zwischen fhem.cfg und configDB Installationen.
Wird configDB verwendet, will FileRead() die Datei aus der Datenbank lesen, dort wird die Moduldatei logischerweise nicht gefunden.
Da die Moduldatei immer aus dem Dateisystem gelesen werden muss, solltest Du das im Aufruf von FileRead() mit angeben.


Index: FHEM/02_HTTPAPI.pm
===================================================================
--- FHEM/02_HTTPAPI.pm (revision 26269)
+++ FHEM/02_HTTPAPI.pm (working copy)
@@ -210,7 +210,7 @@
sub HTTPAPI_CommandRef($) {
   my ($hash) = @_;
   my $fileName = $gPath . '/02_HTTPAPI.pm';
-  my ($err, @contents) = FileRead($fileName);
+  my ($err, @contents) = FileRead( { FileName => $fileName, ForceType => 'file' } );
   return ($hash, 404, 'close', "text/plain; charset=utf-8", encode($encoding, "error=404 Not Found, file $fileName not found")) if ($err);
   my $contents = join("\n", @contents);
   $contents =~ /\n=begin.html([\s\S]*)\n=end.html/gs;
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

klaus.schauer

Ändere ich natürlich. Gut dass der eine oder andere einen Überblick hat und sich meldet.