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
Empfehlung: Bau das ganze mit HTTPMOD auf. das macht es denke ich deutlich einfacher.
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
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
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
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
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
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...)
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
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)
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 ...
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
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
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
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}";
Hallo Thorsten,
Hurra!! das war's: Die runden Klammern. Nun steht im reading voltage das was ich gesucht habe.
Dir vielen vielen Dank!!!!!!!
Ich bin vielleicht eine Erklärung schuldig, warum der Groschen erst so spät gefallen ist:
Obwohl meine Hausautomatisierung mit FHEM von Alarmanlage über Kellerentfeuchtung und Heizung prima läuft, bin ich auf dem Gebiet regex wirklich blutiger Anfänger, ganz einfach, weil ich bisher ohne ausgekommen bin. Wenn man damit anfängt, stellen sich auf einmal gleichzeitig so viele Fragen, daß einem trotz eifriger Lektüre der Kopf raucht und man manchmal nicht einmal mehr sinnvolle Fragen stellen kann. Jetzt habe ich begriffen dass Dein regex zwar <voltage>xxxxx findet, aber nur das, was in den runden Klammern steht, dem reading auch zuweist.
Also nochmal Dankeschön an Dich und auch die Anderen für ihre mehr oder weniger hilfreichen Kommentare und Bemerkungen.
LG
bernd
Hallo Betateilchen,
auch Dir herzlichen Dank. Es funktioniert nun!!!.
Jetzt geht es auch mit dem ursprünglichen Ansatz und ich könnte nun beide Versionen (GetFileFromURL oder HTTPMOD) verwenden. Dank Deiner und der Hilfe von Thorsten habe ich nun eine Menge dazugelernt. Ich bin jetzt echt happy.
LG
bernd
Zitat von: berndgel am 29 März 2017, 09:37:16
Jetzt geht es auch mit dem ursprünglichen Ansatz
Du hattest ja ursprünglich schon alles richtig gemacht und das gesamte XML bereits decodiert in $ref abgelegt.
Aber ich habe bis jetzt immer noch nicht verstanden, warum Du die vorhandenen Werte dann nicht auch verwendet hattest?
Hallo Betateilchen,
ZitatDu hattest ja ursprünglich schon alles richtig gemacht und das gesamte XML bereits decodiert in $ref abgelegt.
Aber ich habe bis jetzt immer noch nicht verstanden, warum Du die vorhandenen Werte dann nicht auch verwendet hattest?
Wenig Erfahrung mit dem von mir angesprochenen Problem gepaart mit mangelhaftem Verständnis der Syntax. Man liest und sucht, probiert dieses und jenes und irgendwann raucht einem der Kopf und man weiß gar nichts mehr. Ich denke, das geht vielen so, die hier Fragen stellen. Gottseidank gibt es Leute, die einem wirklich weiterhelfen.
Danke
+
LG
bernd