Neue Version von HTTPMOD mit neuen Features zum Testen

Begonnen von StefanStrobel, 05 Dezember 2015, 08:31:32

Vorheriges Thema - Nächstes Thema

StefanStrobel

Hier eine neue Version von HTTPMOD zum Testen.

Bitte gebt mir Feedback wenn Ihr Bugs findet.

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
- 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
- ParseFunction zum Einklinken eigener Parse-Funktionen
- diverse Bug Fixes und Kleinigkeiten

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" 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.)

Weitere Details stehen in der Doku bzw. im Code :-). Das Wiki muss erst noch aktualisiert werden.

EDIT:
7.12.15: neue Version angehängt
10.12.15 nochmal neue Version angehängt (Fehler im JSON parsing korrigiert und Attribut extractAllJSON auf Start mit kleinem "e" geändert damit es konsistent zum Rest ist.
22.12.15: neues Modul angehängt - Fehler beseitigt
28.12.15: neues Modul angehängt - setParseResponse Attribut
12.1.16: neues Modul angehängt - einfaches Cookie-Handling, Sid Extraktion und ReAuth Erkennung auch per JSON und XPath, Verbesserung bei den Replacements etc. (siehe späterer Post)
16.1.16: neue Version angehängt. Jetzt kann man auch bei get einen optionalen Wert mitgeben, der dann per Replacement in den HTTP-Request eingebaut werden kann. (siehe post vom 16.1.)
23.1.16 neue Version: Attribut RegOpt für Regex-Options wie g, AutoNumLen um Zahlen, die beim Reading-Namen automatusch angehängt werden wenn es mehrere Matches gibt, mit führenden Nullen zu formatieren, diverse Verbesserungen an der Doku, MATCHED_READINGS korrigiert
25.1.16: neue Version: das Verhalten beim Zufügen von Attributen zu userattr für fhemweb optimiert.
1.2.16: neue Version: ein Löschen von enableCookies löscht nun auch den Cookie-Speicher.
2.2.16: neue Version: Warnung gefixt, neue Attribute authRetries und clearSIdBeforeAuth, Auth wird nicht mehr gequeued sondern vorgezogen wenn nötig
4.2.16: kleine Änderung: bei fehlendem readingXXName wird unnamed-XX als Name verwendet oder falls readingXXJSON angegeben wurde der Wert dieses Attributs.
5.2.16: Warnung gefixt.
13.2.16: Neue Zwischenversion, IMap und OMap teilweise implementiert, httpVersion und sslVersion Attribute hinzugefügt.
14.2.16: Nochmal eine Zwischenversion: sslArgs können spezifiziert werden, z.B. attr myDevice sslArgs SSL_verify_mode,SSL_VERIFY_NONE
15.2.16: Neue Version: set storeKeyValue verwendet setKeyValue zum speichern z.B. von Passwörtern ausserhalb der Konfiguration. Ein neuer replacement mode "key" kann auf getKeyValue zugreifen. Map und Expr Attribute wurden zu IMap für Eingaben und OMap für Ausgaben, entsprechend IExpr und OExpr für Ein- bzw. Ausgaben. set upgradeAttributes zum automatischen anpassen der Attribute auf die neue Syntax.
20.2.16: Neue Version, $XML::XPath::SafeMode = 1 für XML Parser gesetzt um Memory Leak zu vermeiden

Gruss
    Stefan

BKSolo

Hallo Stefan, vielen Dank für die Bereitstellung. Meine ersten Erfahrungen auf dem Raspberry 2 sind.

Habe das Modul ausgetauscht und beim Restart im Logfile den Fehler " Can't locate JSON.pm in...." erhalten. Habe dieses mit
sudo apt-get install libjson-perl
behoben.

Erneuter Restart ergab im Logfile den Fehler " Can't locate HTML/TreeBuilder/XPath.pm in....". Vorgängig hatte ich mit
sudo apt-get install libxml-parser-perl libxml-xpath-perl libxml-TreeBuilder-perl
die Libraries installiert.
Bis jetzt konnte ich noch nichts finden was zusätzlich installiert werden müsste.
Ein "find" über die Installation zeigt mir das ich auf "/usr/share/perl5/XML/XPath.pm" das XPath.pm vorhanden ist.

Was mach ich falsch?
Danke, Bruno


Raspberry PI 2/3 - CUL-433(V3) - CUL-868 (V3) - Jeelink 868 - 433 S/E Eigenbau
TX29DTH-IT - FHT80B - FHT80TF - FS20KSE
FHEMobile 3.7r803 - Fhem2Fhem - Alpha2 - OZW672 - TelegramBot

justme1968

kurzer vorschlag vor dem testen: wie wäre es json und xpath nur dann anzubieten wenn die module auch installiert sind?

ich glaube das würde vielen problemen vorbeugen wenn die neue version eingecheckt wird und es hilft auch anwendern auf plattformen auf denen nicht so einfach ein perl modul nach zu installieren ist.

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

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

BKSolo

Hallo Andre, es wäre schade wenn wir die Module erst bekommen wenn diese "Fertig" und voll "Integriert" sind.
Ich war mit Alpha2 auf das XML angewiesen und sehr froh dass es diese ersten Versionen des Moduls gab. Es ist jedem freigestellt ob er es in einer frühen Version testen und einsetzen will.

Hallo Stefan, ich konnte in der Zwischenzeit den Fehler beheben mit
sudo cpan install HTML::TreeBuilder::XPath
und werde meine laufende Installation Alpha2 mit dem neuen Modul auf meinem Test-Raspberry testen.

Danke und Gruss, Bruno
Raspberry PI 2/3 - CUL-433(V3) - CUL-868 (V3) - Jeelink 868 - 433 S/E Eigenbau
TX29DTH-IT - FHT80B - FHT80TF - FS20KSE
FHEMobile 3.7r803 - Fhem2Fhem - Alpha2 - OZW672 - TelegramBot

justme1968

#4
ich glaube du hast mich falsch verstanden ...

es ging darum features im fhem modul nur dann zu aktivieren wenn die benötigten Perl module auch vorhanden sind.

dann muss man nicht perl module installieren die man für sich selber nicht braucht, und es wird später wenn die neue version eingecheckt wird keinen aufschrei geben weil die hälfte der bestehenden defines plötzlich weg ist.

es ging nicht darum den funktionsumfang einzuschränken oder keine vor vorversionen mehr herauszugeben. ganz im gegenteil.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

frank

Zitates ging darum features im fhem modul nur dann zu aktivieren wenn die benötigten Perl module auch vorhanden sind.
meine fritzbox würde die idee sehr begrüssen.  :)
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

StefanStrobel

Hallo,

so war es auch gedacht :-)
Das Laden von JSON und XPath ins Modul erfolgt nur, wenn die entsprechenden Attribute verwendet werden.
Allerdings war noch ein Tippfehler drin, so dass dann bei fehlender Lib ein Crash statt nur einer Meldung kam.
Eval {} ist halt doch was anderes als eval """"...
Ich aktualisiere gleich den ersten Post mit der neuen Version.

Gruss
    Stefan

BKSolo

Ich habe mit der neusten Version meine Alpha2 Implementierung angepasst (in http://forum.fhem.de/index.php/topic,42040.msg366947.html#msg366947 beschrieben).
Dabei verwende ich die neue Möglichkeit der mehrfachen XML-Werte.

define Alpha2 HTTPMOD http://xxx.xxx.xxx.xxx/data/dynamic.xml 600
attr Alpha2 comment Fussbodenheizung
attr Alpha2 enableXPath-Strict 1
attr Alpha2 group Fussbodenheizung
attr Alpha2 reading01Name Ist-Temperatur
attr Alpha2 reading01XPath-Strict //Devices/Device/HEATAREA/T_ACTUAL/text()
attr Alpha2 reading02Name Soll-Temperatur
attr Alpha2 reading02XPath-Strict //Devices/Device/HEATAREA/T_TARGET/text()
attr Alpha2 room Fussbodenheizung
attr Alpha2 stateFormat {sprintf("Ist-Temperatur-1: %.1f, Soll-Temperatur-1: %.1f , Ist-Temperatur-2: %.1f , Soll-Temperatur-2: %.1f , Ist-Temperatur-3: %.1f , Soll-Temperatur-3: %.1f  , Ist-Temperatur-4: %.1f , Soll-Temperatur-4: %.1f  ",  ReadingsNum($name,"Ist-Temperatur-1",0), ReadingsNum($name,"Soll-Temperatur-1",0), ReadingsNum($name,"Ist-Temperatur-2",0), ReadingsNum($name,"Soll-Temperatur-2",0),ReadingsNum($name,"Ist-Temperatur-3",0), ReadingsNum($name,"Soll-Temperatur-3",0), ReadingsNum($name,"Ist-Temperatur-4",0), ReadingsNum($name,"Soll-Temperatur-4",0))}


Damit wird der Code kürzer und übersichtlicher. In der restlichen Implementierung muss dann nur bei den Namen ein - (Minus) eingegeben werden. Alt: Ist-Temperatur1 Neu: Ist-Temperatur-1.

Soweit funktioniert es gut - Danke euch.
Raspberry PI 2/3 - CUL-433(V3) - CUL-868 (V3) - Jeelink 868 - 433 S/E Eigenbau
TX29DTH-IT - FHT80B - FHT80TF - FS20KSE
FHEMobile 3.7r803 - Fhem2Fhem - Alpha2 - OZW672 - TelegramBot

frank

Zitat von: StefanStrobel am 05 Dezember 2015, 14:40:01
Das Laden von JSON und XPath ins Modul erfolgt nur, wenn die entsprechenden Attribute verwendet werden.
perfekt.

ich vermisse noch eine möglichkeit die kommunikation zu überwachen, um auf fehler (timeout, no route to host, cannot fork, ...) entsprechend reagieren zu können. vielleicht habe ich es auch nur noch nicht gefunden bei den unendlichen möglichkeiten.

gruss frank
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

StefanStrobel

Hallo Frank,

wenn das Attribut showError gesetzt ist, bekommst Du ein Reading bzw. einen Event mit der Fehlermeldung als LAST_ERROR. Reicht das aus?

in der Read-Funktionsieht das so aus:
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))
}


Gruss
    Stefan

frank

Zitatwenn das Attribut showError gesetzt ist, bekommst Du ein Reading bzw. einen Event mit der Fehlermeldung als LAST_ERROR. Reicht das aus?

hallo stefan,
das hört sich schon sehr gut an. ich werde testen.

gruss frank
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

frank

#11
hallo stefan,

nach tausch meiner alten version mit anschliessendem reboot wird httpmod nicht mehr geladen.

# $Id: 98_HTTPMOD.pm 9127 2015-08-24 18:43:31Z ststrobel $

2015.12.06 10:27:14.238 0: Server shutdown
2015.12.06 10:29:53.643 1: Including fhem.cfg
2015.12.06 10:30:00.267 1: HMLAN_Parse: hmusb1 new condition disconnected
2015.12.06 10:30:00.370 1: HMLAN_Parse: hmusb1 new condition init
2015.12.06 10:30:00.403 1: HMLAN_Parse: hmlan1 new condition disconnected
2015.12.06 10:30:00.426 1: HMLAN_Parse: hmlan1 new condition init
2015.12.06 10:30:15.815 1: reload: Error:Modul 98_HTTPMOD deactivated:
Type of arg 1 to each must be hash or array (not private variable) at ./FHEM/98_HTTPMOD.pm line 918, near "$ref) "
Type of arg 1 to each must be hash or array (not private variable) at ./FHEM/98_HTTPMOD.pm line 922, near "$ref) "
BEGIN not safe after errors--compilation aborted at ./FHEM/98_HTTPMOD.pm line 1125, <$fh> line 1397.


Perl     : v5.12.2

perldoc sagt:
ZitatStarting with Perl 5.14, each can take a scalar EXPR, which must hold a reference to an unblessed hash or array. The argument will be dereferenced automatically. This aspect of each is considered highly experimental. The exact behaviour may change in a future version of Perl.

edit:
es sind weitere fehler vorhanden, wenn ich die beiden "each $ref" fehler folgendermassen ändere:
in z918 zu "each @{$ref}" und
in z922 zu "each %{$ref}".
abgesehen davon, ob diese änderungen überhaupt funktionell passen, wird jedenfalls erst einmal weiter kompiliert bis zu folgendem abbruch:

2015.12.07 12:49:57.020 1: reload: Error:Modul 98_HTTPMOD deactivated:
Type of arg 1 to keys must be hash or array (not hash element) at ./FHEM/98_HTTPMOD.pm line 1161, near "}) "
Type of arg 1 to push must be array (not null operation) at ./FHEM/98_HTTPMOD.pm line 1341, near "$reading) "
Type of arg 1 to keys must be hash or array (not hash element) at ./FHEM/98_HTTPMOD.pm line 1351, near "}) "
Type of arg 1 to push must be array (not null operation) at ./FHEM/98_HTTPMOD.pm line 1384, near "$reading)"


ZitatStarting with Perl 5.14, keys can take a scalar EXPR, which must contain a reference to an unblessed hash or array. The argument will be dereferenced automatically. This aspect of keys is considered highly experimental. The exact behaviour may change in a future version of Perl.
ZitatStarting with Perl 5.14, push can take a scalar EXPR, which must hold a reference to an unblessed array. The argument will be dereferenced automatically. This aspect of push is considered highly experimental. The exact behaviour may change in a future version of Perl.

edit2:
mit diesen änderungen läuft die neue version jetzt auch auf der fritzbox. mit meiner definition aus der anfangszeit von httpmod scheint alles zu funktionieren. LAST_ERROR kommt auch. die auswirkungen meiner änderungen musst du beurteilen:

zeile 918 geändert
        while( my ($key,$value) = each @{$ref}) {

zeile 922 geändert
        while( my ($key,$value) = each %{$ref}) {                                       

zeile 1161 geändert
    foreach my $reading (sort keys %{$hash->{READINGS}}) {

zeile 1341 ersetzt
if ($tried) {
if($match) {
push (@matched, $reading);
} else {
push (@unmatched, $reading);
}
}

zeile 1351 geändert
            foreach my $object (keys %{$hash->{ParserData}{JSON}}) {

zeile 1384 ersetzt
if($match) {
push (@matched, $reading);
} else {
push (@unmatched, $reading);
}


gruss frank
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

eppi

Hallo zusammen
Ich möchte gerne das neue Modul nutzen für meinen Steckdosenschalter mit Powermeter, aber ich schaffe es einfach nicht und wäre deshalb froh über einen Schups in die richtige Richtung.

Schalten kann ich das Relay mit:
http://192.168.2.123/relay?state=1

Einen Report erhalte ich mittels :
http://192.168.2.123/report

Dieser liefert mir:
{
"power": 0,
"relay": false
}


Ich habe es wie folgt probiert:
define Harasse1 HTTPMOD none 0
attr Harasse1 get01Name power
attr Harasse1 getURL http://192.168.2.123/report
attr Harasse1 getHeader1 Content-Type: application/json
attr Harasse1 getHeader2 Accept: */*
attr Harasse1 getData {"get" :["power"]}


Ich erhalte immer folgende Fehlermeldung:
2015.12.07 07:25:28 3: Harasse1: Read response to update didn't match any Reading

Besten Dank für einen Hinweis.
Viele Grüsse Dani

nesges

Funktioniert wunderbar und die Umstellung auf die neuen XPath-Attribute ist ein Kinderspiel. Danke!

Das Auflösen von mehreren Treffern auf numerierte Readings ist eine gute Lösung, allerdings benötige ich eine zusammengefasste, kommaseparierte Liste. Die daraus selbst zu bauen ist als userReading machbar:

movies { my @urv; for(my $r=1;$r>0;$r++) { my $v=ReadingsVal($name, "movies-".$r, undef); if($v) {push(@urv, $v)} else { last } } join(', ', @urv) }

aber nicht grade hübsch. Von daher wäre das von dir im anderen Thread bereits angesprochene Attribut "joinMultipleHits" sehr willkommen :-)

StefanStrobel

Hallo,

ich habe eine neue Version im ersten Post angehängt.
@nesges:
attr myDevice reading01RecombineExpr join ", ", @matchlist
bzw. ohne 01 wenn es für alle readings gelten soll oder get01RecombineExpr wenn es für ein get gelten soll.
Damit werden dann alle Ergebnisse definierbar zusammengebaut.

@frank: habe Deine Änderungen übernommen. Damit sollte es auch mit einem alten Perl wieder klappen
(ich konnte es leider nicht testen, da ich dafür erst ein neues System mit altem Perl aufsetzen müsste)

@eppi: In Deiner Konfiguration fehlt die Parse-Anweisung. Entweder mit Regexes oder JSON
(z.B. attr Harasse1 ExtractAllJSON 1)

Gruss
    Stefan