httpmod erweiterung

Begonnen von justme1968, 02 September 2015, 16:27:45

Vorheriges Thema - Nächstes Thema

justme1968

hallo stefan,

ich bin gerade dabei eine klimaanlage für ein ganzes gebäude in fhem einzubinden. leider hat das ding nur ein ziemlich bescheidenes web interface. deshalb zunächst mal die idee das ganze basierend auf httpmod zu machen.

die readings die mich interessieren stecken alle in tabellen (siehe screenshot) und sind mit dem aktuellen eine regex pro reading mechanismus nicht besonders gut zu handhaben. zumal in einer tabelle schon mehrere räume stecken.

ich hatte zuerst mit dem gedanken gespielt die reading[0-9]*Name so zu erweitern das jeweils mehrere durch komma getrennte reading namen möglich sind und dann reading[0-9]*Regex so zu erweitern das jeweils mehrere match groups erlaubt sind. zusätzlich eine möglichkeit die reading namen aus dem tabellen titel zu holen. die tabellen per regex zu bearbeiten ist aber eigentlich schon unhandlich. für andere anwendungsfälle ist es aber etwas das du vielleicht noch einbauen magst.


für mein problem baue habe ich jetzt exec[0-9]*Function attribute eingeführt. hier kann man den namen einer routine aus 99_myUtils angeben die dann mit dem httpmod device hash und dem http buffer aufgerufen wird:        Log3 $name, 5, "$name: Read starts calling all Functions for HTTP Response to $type";
        foreach my $a (sort (grep (/exec[0-9]+Function/, keys %{$attr{$name}}))) {
            if(($a =~ /exec([0-9]+)Function/) && defined ($attr{$name}{"exec${1}Function"}) ) {
              my $func = AttrVal($name, "exec${1}Function", "");
              no strict "refs";     
                eval { &{$func}($hash,$buffer) };
                if( $@ ) {         
                    Log3 $name, 3, "$name: error calling $a $func: $@";
                }                   
              use strict "refs";   
            }                                                           
        }                           

das ganze wird in HTTPMOD_Read direkt nach der vorhanden schleife für die readings aufgerufen. damit kann ich die tabelle jetzt parsen ohne an das feste regex schema gebunden zu sein. in meiner routine rufe ich direkt readingsBulkUpdate für die erzeugten readings auf. das ganze funktioniert wunderbar und ist sehr flexibel.

als zusätzliche variante würde ich noch vorschlagen irgendwo konfigurierbar zu machen ob der aufruf innerhalb des bestehenden readingsBeginUpdate/readingsEndUpdate blocks erfolgt so wie jetzt oder erst nach dem readingsEndUpdate. damit könnte man dann z.b. die einzelnen zeilen für die räume direkt in readings für einen dummy pro raum verwandeln.

würdest du eine entsprechende version ins modul übernehmen?

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

StefanStrobel

Hallo Andre,

an eine Tabellen-Parse-Funktion habe ich noch nicht gedacht. Als nächstes wollte ich erst mal noch JSON einfacher unterstützen bzw. automatisch in Readings übersetzen lassen.

Die Idee mit der externen Funktion für Sonderfälle beim Parsen klingt plausibel. Da das aber sowieso eine Benutzer-Funktion wäre, frage ich mich ob es überhaupt sinnvoll ist, mehrere solche Funktionen nacheinander aufzurufen, oder ob nicht ein einzelnes "parseFunction" Attribut völlig ausreichend wäre.
Ich würde das auch generell nach dem readingsEndUpdate machen, dann ist man flexibler.

Als Name fände ich "parseFunction" oder wenn mehrere sinnvoll sind "parseFunction.*" naheliegender.
Würde das für Dich auch passen?

Gruss
    Stefan

justme1968

eine andere benennung der attribute passt genau so gut. ein aufruf nur nach readingsEndUpdate würde bedeuten das readings aus den reading.* attributen und aus der funktion immer in getrennten event blöcken kommen. ich hätte in meiner anwendung kein problem damit.

ob es ein oder mehrere attribute sind ist vermutlich eher geschmacksache als alles andere.

wenn du den aufruf einbaust wäre das klasse.


das auslesen meherer capture groups pro regex ist vielleicht für viele fast nützlicher als direkt tabellen zu unterstützen. das flexibel zu machen wird komplex. dafür müsste man noch eine syntax überlegen die auch spalten überspringen kann.

wie wäre es json und tabellen nicht direkt ins modul einzubauen sondern über hilfsfunktionen die z.b. einen hash über alle gefunden readings namen und werte zurück liefern die dann noch mal gefiltert werden können bevor sie zu readings werden? für json gibt es im forum ein beispiel das rekursiv alles in readings verwandelt.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

justme1968

hallo stefan,

noch ein wunsch/vorschlag:

wie es aussieht werde ich 16 httpmod devices verwenden. pro klima gerät eines. die konfiguration ist für alle fast identisch und leider ziemlich länglich. der eigentliche unterschied ist an einer hand voll stellen in den urls bzw den im post gesendeten daten eine device oder gruppen id. es wäre klasse wenn ich alle devices identisch konfigurieren könnte und nur an jeweils einer stelle per attribut eine variable setzen könnte die dann in den urls und daten ersetzt wird. ähnlich wie es mit der session aus $sid auch passiert.

hast du eine idee wie man das am einfachsten umsetzen könnte?

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

StefanStrobel

Hallo Andre,

Das mit der Funktion baue ich auf jeden Fall ein. Wird nur ein paar Tage dauern.
Das mit den Variablen hab ich mir auch schon mal überlegt. Auch innerhalb eines Devices habe ich Regexes und Header bzw. Post Daten, die sich nur minimal unterscheiden. Wenn man das für alle Readings oder Get / Set Bereiche übergreifend definiert und dabei eine Variable referenzieren könnte - ähnlich wie mit $sid - wäre das recht elegant.
Bisher habe ich das nicht umgesetzt, weil ich befürchte dass das Modul irgendwann so komplex wird, dass ein Anfänger gar keine Chance mehr hat.
Aber da hilft dann wohl nur noch eine neue Anleitung, die auf Deutsch in mehrere Kapitel und Vertiefungsstufen gegliedert ist.
Mal sehen, ich denke ich bau das trotzdem erst mal ein ;-)

Ein genetische Cookie-Handling hab ich auch noch auf der Liste. Wobei das auch als Erweiterung von HttpUtils sinnvoll sein könnte. Für ein SessionCookie bräuchte man sich dann keine Gedanken mehr über eigene Header, Regexes und $sid machen.


Gruß
   Stefan

justme1968

das klingt alles sehr gut :).

für die variablen würde es mir reichen wenn man den inhalt der readings referenzieren könnte da ich die gruppen id für das set aus der jeweiligen status seite auslesen kann.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

justme1968

noch eine kleinigkeit: es wäre gut wenn die set kommandos im normal fall nichts mehr zurück liefern/ausgeben. sonst erscheint in aktuellen fhemweb versionen immer ein popup. die rückgabe bei set ist eigentlich nur für fehler gedacht.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

justme1968

ich habe bei mir jetzt eine version die in HTTPMOD_DoSet über    $data =~ s/\$\{([a-z0-9._]+)\}/{
      my $x = ReadingsVal($name,$1,""); $x eq "" ? "\${$1}" : $x
    }/egi;
jeweils alle vorkommen von ${<reading>} durch den wert des gleich lautenden readings ersetzt wenn ein solches vorhanden ist. für $header und $url entsprechend.

das funktioniert für mich wunderbar.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

justme1968

hallo stefan,

ich habe gerade noch ein ganz anderes problem. scheinbar durch die vielen gleichzeitigen verbindungen bekomme ich von meiner gegenstelle ein connection refused. im prinzip würde ein neu anmelden helfen, im error fall versucht HTTPMOD_Read aber keine neue authentifizierung sondern bricht nur ab. d.h. auch passendes reAuthRegex hilft hier nicht.

ich habe mir jetzt so beholfen das return nur erfolgt wenn reAuthRegex nicht auch auf $err matched.

oder hast du eine andere idee wie man das lösen kann?

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

StefanStrobel

Hallo Andre,

Dass man auf ein connection refused mit erneutem Login reagieren kann, erscheint mir schon recht speziell. Aber so sind nun mal viele embedded web server - sehr speziell ;-)

Eine Option könnte auch ein dediziertes Attribut reAuthOnError sein, dem man optional eine Regex mitgeben kann, die dann nur für den Fehlerfall verwendet wird.

Ich muss mir das aber noch mal in Ruhe ansehen. Bisher bin ich leider noch nicht dazu gekommen wieder was an HTPMOD zu machen.

Gruss
    Stefan

justme1968

immerhin kommt noch ein 'connection refused' in der err nachricht :).

ein eigenes attribut würde natürlich genau so gut gehen.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

StefanStrobel

Hi Andre,

ich hab eine Neue Version gepostet, in der hoffentlich auch alle von Deinen Vorschlägen / Wünschen drin sind.
Bitte schau doch mal ob es für Dich so passt, oder ob ich noch etwas vergessen habe.
http://forum.fhem.de/index.php/topic,45176.0.html

für das Error-Matching ist jetzt in der Read-Funktion ein:
    if ($err) {
        $buffer = $buffer . "\r\n\r\n" . $err;                          # so err can be used in reAuthRegex matching
        readingsSingleUpdate ($hash, "LAST_ERROR", $err, 1)
            if (AttrVal($name, "showError", undef))
    }


Für die Ersetzungen bist Du mit dem Mode "expression" am flexibelsten. Da mache ich ein:

            } elsif ($mode eq 'expression') {
                eval {$string =~ s/$regex/$value/gee};
                if ($@) {
                    Log3 $name, 3, "$name: Replace: invalid regex / expression: /$regex/$value/gee - $@";
                }
            }


Gruss / Thanx
   Stefan

justme1968

das klingt seht gut. schaue ich mir so bald wie möglich an.

danke
andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968