Neue HTTPMOD Version mit zahlreichen Änderungen eingecheckt

Begonnen von StefanStrobel, 05 März 2016, 20:45:47

Vorheriges Thema - Nächstes Thema

StefanStrobel

Eine neue Version von HTTPMOD ist nun eingecheckt.

Folgendes ist neu:
- direktes Parsen von JSON inkl. automatischer Erzeugung von Readings für jedes Objekt
- Parsen von HTML-Daten und XML-Daten per XPath ist besser integriert und kann mit einem XPath mehrere Readings setzen
- Parsen von Regexes mit mehreren capture groups kann mehrere Readings setzen. Die Readings enden dabei automatisch auf -01, -02 etc. wobei die Länge der angehängten Nummern ebenfalls gesteuert werden kann.
- Regexes können per Attribut RegOpt z.B. mit /g verwendet werden um alle Matches in einem Schritt in Readings zu parsen
- dynamische Ersetzungen für URL, Header und Post Daten
- Reaktion auf Readings, die nicht aktualisiert wurden
- Erweiterte Dokumentation
- Maps können auch Leerzeichen im Text enthalten
- Die HTTP-Response nach einem set-Befehl kann nun auch geparsed werden und get-Befehle können Übergabewerte wie bei set-Befehlen verwenden (Attribue set01ParseResponse, getXYTextArg etc.)
- automatisches Cookie-Handling um das Handling von Session-IDs zu vereinfachen (Attribut enableCookies)
- Bei manueller Verwaltung der Session ID kann nun auch XPath oder JSON zum Extrahieren der Session ID verwendet werden. (Attribute idJSON, idXPath etc.)
- ParseFunction zum Einklinken eigener Parse-Funktionen
- getKeyValue integriert um das versteckte Speichern von Passwörtern zu ermöglichen
- diverse Bug Fixes und Kleinigkeiten wie sslArgs, httpVersion, authRetries, clearSIdBeforeAuth, showError etc.

HTTPMOD hat sich intern an vielen Stellen geändert, so dass eine Parsing-Anweisung (Regex oder auch XPath) mehrere Readings erzeugen kann.
Beispiel:

attr myDevice reading02Regex something[ \t]+([\d\.]+)[ \t]+([\d\.]+)
attr myDevice reading02Name Temp
   

hier enthält die Regex zwei capture groups, die jeweils auf eine Zahl matchen.
Dabei werden zwei Readings erzeugt:

Temp-1
Temp-2


man kann diesen Readings auch eigene Namen geben. Dazu kann man die Attribute reading02-1Name, reading02-2Name etc. angeben. z.B.:

attr myDevice reading02-1Name AussenTemp
attr myDevice reading02-2Name InnenTemp
   

Entsprechend kann man alle anderen Attribute für die Aufbereitung und Formattierung der Readings auch mit Nummer-Nummer spezifizieren.
In den meisten Fällen wird jedoch der bisherige Weg, bei dem für jedes Reading eine eigene Regex angegeben wird, der einfachste bleiben.
   
aus der Doku zu JSON:
Wenn ein Webservice Daten im JSON-Format schickt, kann HTTPMOD diese jetzt direkt parsen und aus den Objekten Readings erzeugen.
Das folgende Beispiel fragt Daten von einem Poolmanager ab (noch ohne Readings):

define test2 HTTPMOD none 0
attr test2 get01Name Chlor
attr test2 getURL http://192.168.70.90/cgi-bin/webgui.fcgi
attr test2 getHeader1 Content-Type: application/json
attr test2 getHeader2 Accept: */*
attr test2 getData {"get" :["34.4008.value"]}


Die HTTP-Response enthält dann folgende Daten:

{
"data": {
"34.4008.value": "0.25"
},
"status":       {
"code": 0
},
"event":        {
"type": 1,
"data": "48.30000.0"
}
}


Um bisher den Wert 0.25 in das Reading Chlor zu bekommen, musste man eine Regex wie folgt definieren:

attr test2 get01Regex 34.4008.value":[ \t]+"([\d\.]+)"


Mit dem neuen JSON-Parsing könnte man statt dessen das Objekt in seiner Hierarchie adressieren:

attr test2 get01JSON data_34.4008.value


oder - wenn die Benennung der Reading keine Rolle spielt, kann man auch automatisch aus allen Objekten ein Reading erzeugen und den Pfad in der Hierarchie als Namen verwenden. (Ich habe mich hier an einem Code-Beispiel von Andre orientiert)
Dafür gibt es das folgende Attribut:


attr test2 extractAllJSON


Das gilt dann für alle gelesenen Daten in dieser Modul-Instanz und erzeigt aus obigen Daten die folgenden Readings:

data_34.4008.value 0.25
event_data 48.30000.0
event_type 1
status_code 0


Alternativ kann man auch schreiben:


attr test2 get01ExtractAllJSON


dann werden nur beim get Kommando get01 alle Objekte extrahiert.

aus der Doku zu XPath:

Eine andere Alternative zum Parsen von HTTP-Responses ist die Verwendung von XPath.
In der bisherigen Erweiterung von HTTPMOD für XPath hatte man einen XPath mit "xpath:" in Regexes angegeben.
Die neue Integration hat dafür ein eigenes Attribut. Wenn man HTML-Daten mit XPath parsen möchte ist es:


(reading|get)[0-9]+XPath


und für echte XML-Daten:

(reading|get)[0-9]+XPath-Strict


Im Beispiel enthält eine HTTP-Response die folgenden XML-Daten:

<root xmlns:foo="http://www.foo.org/" xmlns:bar="http://www.bar.org">
<actors>
<actor id=&quot;1&quot;>Peter X</actor>
<actor id=&quot;2&quot;>Charles Y</actor>
<actor id=&quot;3&quot;>John Doe</actor>
</actors>
</root>


Mit der XPath-Syntax könnte man schreiben:


attr myDevice reading01Name Actor
attr myDevice reading01XPath-Strict //actor[2]/text()


Das erzeugt ein Reading mit dem Namen "Actor" und dem Wert "Charles Y".

Da XPath-Angaben wie Regexes mit mehreren capture groups auch zu mehreren Treffern führen können, greift auch hier die Neuerung von HTTPMOD, bei der mit einer Anweisung mehrere Readings erzeugt werden :


attr myDevice reading01Name Actor
attr myDevice reading01XPath-Strict //actor/text()


Hier würden folgende Readings erzeugt:   


Actor-1 Peter X
Actor-2 Charles Y
Actor-3 John Doe
      

Für HTML-Daten funktioniert das entsprechend, jedoch statt mit XPath-Strict einfach mit XPath.

Zu Replacements:

Manchmal möchte man einzelne Teile einer URL, eines Headers oder der Post-Daten dynamisch ersetzen um z.B. das aktuelle Datum darin einzubauen oder weitere Daten an den Server zu senden. Mit den neuen Replacements kann man dafür beliebige Teile dieser Daten durch Text, den Inhalt von Readings oder Internals oder sogar mit Perl-Expressions ersetzen. Die Attribute dafür lauten:


replacement[0-9]*Regex
replacement[0-9]*Mode
replacement[0-9]*Value
[gs]et[0-9]*Replacement[0-9]*Value


Für eine Ersetzung definiert man immer einen regulären Ausdruck, der dann direkt vor dem Absenden des Requests gegen URL, Header und Post-Daten gematcht wird.
Die Art, wie dann ersetzt wird, gibt man mit dem Mode an. Wenn mode "reading" enthält, dann wird Value als Name eines Readings oder als Device:Reading interpretiert und der Wert des Readings wird an die Stelle des Matches gesetzt. der Mode "internal" funktioniert entsprechend mit Internals.
Für Profis gibt es den Mode "expression", bei dem der Wert von Value als Perl-Expression ausgewertet wird.

Beispiel:

attr mydevice getData {"get" :["%%value%%.value"]}
attr mydevice replacement01Mode text
attr mydevice replacement01Regex %%value%%

attr mydevice get01Name Chlor
attr mydevice get01Replacement01Value 34.4008

attr mydevice get02Name Something
attr mydevice get02Replacement01Value 31.4024


Hier wird %%value%% als Platzhalter fpr die Ersetzung fediniert.
Für alle Get-Kommandos gibt es ähnliche HTTP-Post Daten, die sich nur an einer Zahl unterscheiden. Deshalb sind die Post-Daten als "getData" definiert und gelten so für alle Get-Befehle. Auf Ebene der individuellen Get-Befehle wird dann nur noch ein Name und der zu ersetzende Wert angegeben.

Mit dem Mode "expression" kann man noch flexiblere Ersetzungen definieren:
         

attr mydevice replacement01Mode expression
attr mydevice replacement01Regex {{([^}]+)}}
attr mydevice replacement01Value ReadingsVal("mydevice", $1, "")
attr mydevice getData {"get" :["{{temp}}.value"]}


In diesem Beispiel alles innerhalb von doppelten geschweiften Klammern wird als Ersetzung erkannt und der Text dazwischen steht in der Ersetzungs-Expression als $1 zur Verfügung. Im Beispiel wird es als Parameter an ReadingsVal übergeben.

Zu MaxAge:

Bisher bleiben einmal gesetzte Readings bei HTTPMOD bestehen, auch wenn das abgefragte Gerät nicht mehr antwortet.
Am Timestamp der Readings kann man erkennen, dass sie veraltet sind und man konnte mit anderen Modulen wie Watchdog reagieren wenn ein bestimmtes Alter überschritten wurde.
Auf häufige Nachfrage von Anwendern ist nun ein Feature in HTTPMOD gelandet, mit dem man direkt in HTTPMOD bei jedem Reading angeben kann, wie lange das Reading gültig bleibt, falls es nicht mehr aktualisiert wird. Dazu kann man ein maximales Alter in Sekunden und eine Ersetzung mit den folgenden Attributen definieren:


(reading|get)[0-9]*(-[0-9]+)?MaxAge
(reading|get)[0-9]*(-[0-9]+)?MaxAgeReplacementMode
(reading|get)[0-9]*(-[0-9]+)?MaxAgeReplacement


Falls ein solches Attribut definiert wird, prüft HTTPMOD bei jedem Aufruf der internen Lese-Funktion, welche Readings zu alt sind und wendet auf diese dann die Ersetzung an. Als Mode für die Ersetzung steht dabei nur "text", "delete" und "expression" zur Verfügung.
MaxAge wird in Sekunden angegeben und innerhalb einer Ersetzungs-Expression kann mit $val der frühere Wert verwendet werden.

Beispiel:

attr PM readingMaxAge 300<br>
attr PM readingMaxAgeReplacement "outdated - was " . $val <br>
attr PM readingMaxAgeReplacementMode expression


In diesem Beispiel wird MaxAge generisch für alle Readings angebenen, die mit einem reading-Attribut definiert wurden. Entsprechend könnte man es auch für ein einzelnes Reading oder einen Get-Befehl angeben (wie oben bei Format, Expr etc.)
Beim ReplacementMode delete wird ein veraltetes Reading gelöscht.

Integration von getKeyValue
setKeyValue und getKeyValue wurden eingebaut, damit man Passwörter außerhalb der Konfiguration speichern kann.
Zum Setzen muss enableControlSet auf 1 stehen, dann gibt es einem Set-Befehl mit Option storeKeyValue. Dem kann man einen key, z.B. password und einen Wert, z.B. geheim geben. z.B.:

set storeKeyValue password geheim
   

Zum Verwenden des Passwortes definiert man ein eigenes Replacement mit Mode key, z.B.:

attr mydevice get05Name profile
attr mydevice get05URL http://www.mydevice.local/getprofile?password=%%password%%
attr mydevice replacement02Mode key
attr mydevice replacement02Regex %%password%%
attr mydevice get05Replacement02Value password
   

zu SSL
Für Leute mit SSL-Problemen gibt es das neue Attribut sslArgs. Das kann z.B. so gesetzt werden:

attr myDevice sslArgs SSL_verify_mode,SSL_VERIFY_NONE
   

Dann findet keine Verifikation mehr statt, was die Sicherheit aushebelt, aber möglicherweise nötig ist, wenn man Geräte mit illegalen Zertifikaten auslesen möchte und die Zertifikate nicht ausgetauscht werden können. Der Wert des Attributes wird in einen Hash gewandelt und an HttpUtils übergeben.
Ebenso gibt es die neuen Attribute sslVersion und httpVersion. Die Werte werden jeweils an HttpUtils durchgereicht.


Weitere Details stehen in der Doku bzw. im Code :-).

Änderungen an bestehenden Attributen
Einige Attribute aus früheren Versionen von HTTPMOD sind in der neuen Version nicht mehr sinnvoll oder inkonsistent. Sie sollten für die neue Version angepasst werden. Im Log wird daher bei alten Attributen eine entsprechende Meldung erzeugt. Um die Änderungen zu vereinfachen bietet HTTPMOD nun den set-Befehl upgradeAttributres an (wenn das Attribute enableControlSet auf 1 gesetzt ist). set upgradeAttributes schreibt die alten Attribute in das neue Format um und entfernt überflüssig gewordene Attribute.

Im einzelnen sind dies:
readingsNameXY wird zu einem nummerierten readingZZName.
readingsRegexXY und ReadingsExprXY werden entsprechend umbenannt.
IDRegex wird zu IdRegex.

Aus readingXYRegex-Attributen, die mit xpath: beziehungsweise xpath-strict: beginnen wird ein readingXYXPath beziehungsweise readingXYXPath-Strict. Gleiches gilt für getXYRegex mit xpath: oder xpath-strict:
Bei konvertierten xpath / xpath-strict Regexes wird zusätzliche ein Attribut readingXYRecombineExpr join(\",\", \@matchlist) erzeugt, da die neue Syntax per default mehrere Readings für mehrere Werte erzeugt. Die Alte Variante hatte die Werte in einem Reading und durch Kommas getrennt abgelegt. readingXYRecombineExpr sorgt für die Rückwärtskompatibilität bzw. dafür, dass einzelne Werte wieder zu einem Reading zusammengesetzt werden.
enableXPath und enableXPath-Strict sind jetzt überflüssig und werden gelöscht.

setXYExpr wird zu setXYIExpr, da es bisher nur für die Eingabeverarbeitung gedacht war. In der neuen Version kann auch die HTTP-Reponse auf einen set-Befehl geparsed und verarbeitet werden. Dafür ist dann das Attribut setXYOExpr gedacht.
Entsprechend wrd setXYMap zu setXYIMap sowie getXYExpr zu getXYOExpr und getXYMap zu getXYOMap.
readingXYExpr wird zu readingXYOExpr und readingXYMap zu readingXYOMap. O steht dabei immer für Output / Ausgabeverarbeitung und I für Input / Eingabeverarbeitung.

Weitere Details im Forum: https://forum.fhem.de/index.php/topic,45176.0.html

Gruss
    Stefan

StefanStrobel

ein weiteres Update von HTTPMOD ist nun eingecheckt.
Neben zahlreichen Bugfixes gibt es die folgenden neuen Attribute:

- alignTime
- deleteIfUnmatched
- deleteOnError
- alwaysNum

Details im Forum: https://forum.fhem.de/index.php/topic,45176.150.html
und in der CommandRef. Das Wiki ist leider noch nicht aktualisiert.

Gruss
    Stefan