Hilfe!! Ein Anfänger kommt nicht weiter: GetFileFromURL, Zuweisung der Daten

Begonnen von berndgel, 23 März 2017, 16:57:01

Vorheriges Thema - Nächstes Thema

berndgel

Hallo,
ich möchte aus dem Robonect-Server meines Mähroboters namens Erwin die Batteriespannung auslesen. Dazu habe ich in FHEM ein dummy definiert mit:

define Erwin_Stat dummy

Dann habe ich 99_myUtils.pm erweitert mit
#Stati von Erwin lesen und readings dem dummy Erwin_Stat zuweisen #####################################################
sub Update_Erwin {
my $xmltext = GetFileFromURL("http://192.168.178.4/xml?cmd=battery");
my $ref = XMLin($xmltext, KeyAttr => { }, ForceArray => [ ]);
{fhem "setreading Erwin_Stat $xmltext"};
return;
}


Nach shutdown restart liefert mir Erwin_Stat:

DeviceOverview
Erwin_Stat
?

 Erwin_Stat 

Internals
CFGFN
./FHEM/erwin_robonect.cfg
NAME
Erwin_Stat
NR
773
STATE
?
TYPE
dummy


Also ist Erwin_Stat noch jungfäulich.

Jetzt gebe ich in der Kommandozeile {Update_Erwin} ein.

Danach sieht Erwin_Stat wie folgt aus:

DeviceOverview
Erwin_Stat


Internals
CFGFN
./FHEM/erwin_robonect.cfg
NAME
Erwin_Stat
NR
773
STATE
?
TYPE
dummy
Readings

version="1.0" encoding="UTF-8" ?><robonect><successful>true</successful><battery><charge>100</charge><voltage>21192</voltage><current>6</current><temperature>81</temperature><capacity><full>1200</full><remaining>1200</remaining></capacity></battery></robonect>


Die Daten sind gelesen und dem dummy zugwiesen worden.Mir ist schon klar, dass ich mit der Zeile in 99_myUtils.pm
{fhem "setreading Erwin_Stat $xmltext"};
alles was gelesen wurde, einfach dem dummy Erwin_Stat zugewiesen habe, aber damit ist erstmal klar, dass ich überhaupt etwas lesen konnte und es auch in Erwin_Stat landet. Die Daten sind auch richtig. Ich bin also fast am Ziel. Aber nur fast.

Und hier liegt mein Problem:
Wie kann ich dem dummy Erwin_Stat die mich interessierenden Werte für <successful>,<Charge>,<voltage>,<current>,<temperature>,< capacity>,<remaining>
zuweisen, damit ich sie weiterverarbeiten kann ?


Mir würde schon helfen, wenn ich wenigstens <voltage> zuweisen könnte. Den Rest bekomme ich dann wahrscheinlich selber hin

Bitte helft mir. Ich versuche mehr als 1 Woche dieses Problem zu lösen. Die vielen Beiträge, die ich bisher gelesen habe, halfen mir nur bis hierher weiter, da es sich teilweise um sehr komplexe Fragestellungen handelt, die ich teilweise mangels Erfahrung und Wissen gar nicht nachvollziehen kann.


Danke
+
LG

bernd

Frank_Huber

Empfehlung: Bau das ganze mit HTTPMOD auf. das macht es denke ich deutlich einfacher.

berndgel

Hallo Frank,
mit HTTPMOD etc. habe ich mich die ganze Zeit gequält und das Problem nicht gelöst bekommen. Das Problem ist die Syntax, die ich offensichtlich nicht hinbekomme/verstehe. Bei meinem jetzigen Ansatz (den ich mir auch nicht selbst ausgedacht habe) fehlt mir wahrscheinlich nur ein "Einzeiler" mit dem ich wenigstens die Größe <voltage>  zuweisen kann. Dann wäre für mich das Problem gelöst.

Trotzdem Danke für Deine Einschätzung.

LG

bernd

Thorsten Pferdekaemper

Hi,
also... Das macht man in Perl mit RegEx. Wenn Du das aber hast, dann ist es viel einfacher, das mit HTTPMOD zu realisieren. Auch für alle potentiellen Helfer ist es einfacher.
Also: Versuch das nochmal mit HTTPMOD. Wenn Du nicht weiterkommst, dann hier fragen.
...außerdem: Wenn Du Informationen über Devices zeigen willst, dann am besten den Befehl "list" verwenden. Dann noch alles, was nach Coding aussieht (und das Ergebnis von "list") bitte in Code-Tags packen.
Gruß,
   Thorsten
FUIP

berndgel

Hallo,
ich habe nun nach einigem erfolglosen Rumtesten mit GetFileFromURL den Vorschlag von Thorsten bzw. Frank aufgenommen und folgendes nunmehr mit HTTPMOD gemacht


define Erwin_St HTTPMOD http://192.168.178.4/xml?cmd=battery 60
attr Erwin_St group Erwin
attr Erwin_St room Erwin

define Spannung dummy
attr Spannung rroup Erwin
attr Spannung room Erwin


Nach shutdown restart zeigt mir Erwin_ST an

DeviceOverview
Erwin_St
???
Internals
BUSY
0
CFGFN
./FHEM/erwin_robonect.cfg
CHANGED

DEF
http://192.168.178.4/xml?cmd=battery 60

Interval
60
LASTSEND
1490534929.25127
MainURL
http://192.168.178.4/xml?cmd=battery
ModuleVersion
3.3.5 - 29.9.2016
NAME
Erwin_St
NR
738
STATE
???
TRIGGERTIME
1490534989.24984
TRIGGERTIME_FMT
2017-03-26 15:29:49
TYPE
HTTPMOD
addr
http://192.168.178.4:80
buf
HTTP/1.1 200 OK Content-Type: text/xml Server: FHDR Connection: close Cache-Control: no-cache Content-Type: application/x-www-form-urlencoded <?xml version="1.0" encoding="UTF-8" ?><robonect><successful>true</successful><battery><charge>62</charge><voltage>19321</voltage><current>-456</current><temperature>186</temperature><capacity><full>1200</full><remaining>755</remaining></capacity></battery></robonect>
code
200
conn

data

displayurl
http://192.168.178.4/xml?cmd=battery
header

host
192.168.178.4
httpheader
HTTP/1.1 200 OK Content-Type: text/xml Server: FHDR Connection: close Cache-Control: no-cache Content-Type: application/x-www-form-urlencoded
httpversion
1.0
hu_blocking
0
hu_filecount
8
hu_portSfx

ignoreredirects
0
loglevel
4
path
/xml?cmd=battery
protocol
http
redirects
0
timeout
2
url
http://192.168.178.4/xml?cmd=battery
value
0


buf enthält unter anderem Folgendes :<voltage>19321</voltage>

Die Zahl 19321 ist die aktuelle Batteriespannung in mv . Diese Zahl will ich dem dummy Spannung zuweisen. Und genau hier komme ich nicht weiter. Kann mir da bitte jemand auf die Sprünge helfen?

Danke
+
LG
bernd

Thorsten Pferdekaemper

Hi,
versuch mal folgendes:

attr Erwin_St readingsName1 voltage
attr Erwin_St readingsRegex1 <voltage>[\x20 ]([-\d]+)

...und dann eine Minute warten.
Dann müsste das Device Erwin_St ein Reading "voltage" haben.
Warum Du das in einem Dummy haben willst ist mir nicht ganz klar. Das müsstest Du dann halt irgendwie mit notify machen. Das fände ich aber ungeschickt, da Du ja alles direkt in Erwin_St haben kannst.
Gruß,
   Thorsten 
FUIP

berndgel

Hallo Thorsten,
erstmal vielen Dank für Deine Geduld.
Ich habe jetzt Deinen Vorschlag so realisiert:

1. Meine cfg
define Erwin_St HTTPMOD http://192.168.178.4/xml?cmd=battery 60
attr Erwin_St group Erwin
attr Erwin_St room Erwin
attr Erwin_St reading01Name voltage
attr Erwin_St reading01Regex <voltage>[-\d]+


2. Device ausgelesen:

DeviceOverview
Erwin_St
???
Internals
BUSY
0
CFGFN
./FHEM/erwin_robonect.cfg
DEF
http://192.168.178.4/xml?cmd=battery 60

Interval
60
LASTSEND
1490699000.11174
MainURL
http://192.168.178.4/xml?cmd=battery
ModuleVersion
3.3.5 - 29.9.2016
NAME
Erwin_St
NR
744
STATE
???
TRIGGERTIME
1490699060.10977
TRIGGERTIME_FMT
2017-03-28 13:04:20
TYPE
HTTPMOD
addr
http://192.168.178.4:80
buf
HTTP/1.1 200 OK Content-Type: text/xml Server: FHDR Connection: close Cache-Control: no-cache Content-Type: application/x-www-form-urlencoded <?xml version="1.0" encoding="UTF-8" ?><robonect><successful>true</successful><battery><charge>71</charge><voltage>19688</voltage><current>-720</current><temperature>184</temperature><capacity><full>1200</full><remaining>852</remaining></capacity></battery></robonect>
code
200
conn

data

displayurl
http://192.168.178.4/xml?cmd=battery
header

host
192.168.178.4
httpheader
HTTP/1.1 200 OK Content-Type: text/xml Server: FHDR Connection: close Cache-Control: no-cache Content-Type: application/x-www-form-urlencoded
httpversion
1.0
hu_blocking
0
hu_filecount
23
hu_portSfx

ignoreredirects
0
loglevel
4
path
/xml?cmd=battery
protocol
http
redirects
0
timeout
2
url
http://192.168.178.4/xml?cmd=battery
value
0
Readings
voltage
1
2017-03-28 13:03:20

 Erwin_St 

Attributes
group
Erwin
deleteattr
reading01Name
voltage
deleteattr
reading01Regex
<voltage>[-\d]+
deleteattr
room
Erwin
deleteattr
userattr
reading01Name reading01Regex


buf enthält offensichtlich den empfangenen String in dem sich auch voltage befindet.
Gesendet wurde u.a. <voltage>19688</voltage>
Jetzt existiert ein reading mit dem Namen voltage, das offensichtlich den Wert 1 hat. Interpretiere ich da etwas falsch?

3. Ergebnis von list Erwin_Sta
Internals:
   BUSY       0
   CFGFN      ./FHEM/erwin_robonect.cfg
   DEF        http://192.168.178.4/xml?cmd=battery 60
   Interval   60
   LASTSEND   1490699060.11789
   MainURL    http://192.168.178.4/xml?cmd=battery
   ModuleVersion 3.3.5 - 29.9.2016
   NAME       Erwin_St
   NR         744
   STATE      ???
   TRIGGERTIME 1490699120.11511
   TRIGGERTIME_FMT 2017-03-28 13:05:20
   TYPE       HTTPMOD
   addr       http://192.168.178.4:80
   buf        HTTP/1.1 200 OK
Content-Type: text/xml
Server: FHDR
Connection: close
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded

<?xml version="1.0" encoding="UTF-8" ?><robonect><successful>true</successful><battery><charge>70</charge><voltage>19659</voltage><current>-864</current><temperature>186</temperature><capacity><full>1200</full><remaining>841</remaining></capacity></battery></robonect>
   code       200
   conn
   data
   displayurl http://192.168.178.4/xml?cmd=battery
   header
   host       192.168.178.4
   httpheader HTTP/1.1 200 OK
Content-Type: text/xml
Server: FHDR
Connection: close
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
   httpversion 1.0
   hu_blocking 0
   hu_filecount 24
   hu_portSfx
   ignoreredirects 0
   loglevel   4
   path       /xml?cmd=battery
   protocol   http
   redirects  0
   timeout    2
   url        http://192.168.178.4/xml?cmd=battery
   value      0
   QUEUE:
   Readings:
     2017-03-28 13:04:20   voltage         1
   Request:
     data
     header
     ignoreredirects 0
     retryCount 0
     type       update
     url        http://192.168.178.4/xml?cmd=battery
     value      0
   Defptr:
     Readingbase:
       voltage    reading
     Readingnum:
       voltage    01
     Readingoutdated:
     Requestreadings:
       Update:
         voltage    reading 01
   Sslargs:
Attributes:
   group      Erwin
   reading01Name voltage
   reading01Regex <voltage>[-\d]+
   room       Erwin
   userattr   reading01Name reading01Regex

Jetzt hat sich der Wert für voltage im empfangenen String natürlich schon geändert, da das "list Erwin_Sta" etwas später ausgeführt wurde  : <voltage>19659</voltage>

Wenn ich die o.a. Ausgaben richtig interpretiere, ist jedoch das reading voltage mit 1 besetzt, oder interpretiere ich das falsch. Also weiterhin ratlos!!

Überigens ich muss den Wert für voltage nicht einem dummy übergeben sondern kann natürlich auch direkt mit doif usw. den Wert weiterverarbeiten.

z.B. define d_Erwin_ST doif (xxxxxx lt 1500) (set Schalter off)  doelse  (set Schalter  on)

Aber da muss ich erstmal hinkommen weil ich nicht weiß was genau in xxxxxx stehen muss, was ja wieder zum eigentlichen Problem (s.o.) führt.

Danke
+
LG

bernd

betateilchen

So ein Quatsch. Sorry.

Wenn man schon mit einer Funktion in der 99_myUtils.pm arbeitet und XML als Input hat,
sollte man einfach die in perl vorhandenen Möglichkeiten zum parsen von XML verwenden.

Dazu braucht es kein HTTPMOD.

(Aber es soll ja auch Leute geben, die sich aus Excel eine Textverarbeitung basteln...)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Wuppi68

Zitat von: betateilchen am 28 März 2017, 14:12:25

(Aber es soll ja auch Leute geben, die sich aus Excel eine Textverarbeitung basteln...)

<off tpoic>
und Leute die die Configdb in der SAP ...
</off Topic>

ansonsten schaue mal ins Wiki nach https://wiki.fhem.de/wiki/HTTPMOD#Parsing_JSON hier

FHEM unter Proxmox als VM

betateilchen

Zitat von: Wuppi68 am 28 März 2017, 14:32:18
<off tpoic>
und Leute die die Configdb in der SAP ...
</off Topic>

ja... und DynamoDB als NonSQL geht inzwischen auch :)

Aber XML mit JSON zu parsen, stelle ich mir noch aufwändiger vor als mit HTTPMOD regexp  8)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Wuppi68

Zitat von: betateilchen am 28 März 2017, 14:36:58
Aber XML mit JSON zu parsen, stelle ich mir noch aufwändiger vor als mit HTTPMOD regexp  8)

der XML Part kommt direkt darunter ...
FHEM unter Proxmox als VM

Thorsten Pferdekaemper

Zitat von: berndgel am 28 März 2017, 13:44:10Ich habe jetzt Deinen Vorschlag so realisiert:

1. Meine cfg
attr Erwin_St reading01Regex <voltage>[-\d]+

Das muss zumindest mal so heißen:
attr Erwin_St reading01Regex <voltage>([-\d]+)

Die Klammern sind wesentlich, denke ich.
Gruß,
   Thorsten
FUIP

berndgel

Hallo Thorsten
ich habe jetzt mal mit einem regex-Tool (regexr.com) gespielt und diesem die Daten aus bus, also dem empfangenen String zum Fraß vorgeworfen:

<voltage>[\x20 ]([-\d]+)              findet nichts

<voltage>[-\d]+                          findet:  <voltage>19688

<voltage>([-\d]+)                        findet: <voltage>19688


Ich brauche im reading voltage aber nur die Zahl 19688 ohne <voltage> davor, aber wie?

LG

bernd

Thorsten Pferdekaemper

Zitat von: berndgel am 28 März 2017, 19:05:05ich habe jetzt mal mit einem regex-Tool (regexr.com) gespielt und diesem die Daten aus bus, also dem empfangenen String zum Fraß vorgeworfen:
Warum?

Zitat
Ich brauche im reading voltage aber nur die Zahl 19688 ohne <voltage> davor, aber wie?
Mach doch mal das, was ich Dir gesagt habe.
Gruß,
   Thorsten
FUIP

betateilchen

nochmal... macht Euch doch bitte das Leben nicht unnötig schwer.

Wenn man - wie im Eingangsbeitrag - in der 99_myUtils schon mit XML arbeitet, ist doch alles schon fertig.

@berndgel: teste mal bitte Deine Funktion "Update_Erwin" so:


sub Update_Erwin {
my $xmltext = GetFileFromURL("http://192.168.178.4/xml?cmd=battery");
my $ref = XMLin($xmltext, KeyAttr => { }, ForceArray => [ ]);
return $ref->{battery}->{voltage};
}


Dann bekommst Du den aus XML extrahierten Wert "voltage" zurück, wenn Du die Funktion im Frontend aufrufst.

{Update_Erwin}

$ref->{battery}->{voltage} kannst Du natürlich auch direkt als Wert verwenden, um ihn in ein reading zu schreiben.


fhem "setreading Erwin_St voltage $ref->{battery}->{voltage}";
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!