HMLAN Disconnect

Begonnen von oniT, 13 Mai 2013, 22:19:58

Vorheriges Thema - Nächstes Thema

oniT

Hi Martin,

ich habe ebenfalls diese Disconnects. Diese kommen fast jede Minute.


2013.05.13 15:25:05 1: 192.168.1.170:1000 reappeared (01_LANInterface)
2013.05.13 15:25:00 1: 192.168.1.170:1000 disconnected, waiting to reappear
2013.05.13 15:23:07 1: 192.168.1.170:1000 reappeared (01_LANInterface)
2013.05.13 15:23:02 1: 192.168.1.170:1000 disconnected, waiting to reappear
2013.05.13 15:22:05 1: 192.168.1.170:1000 reappeared (01_LANInterface)
2013.05.13 15:22:00 1: 192.168.1.170:1000 disconnected, waiting to reappear
2013.05.13 15:21:05 1: 192.168.1.170:1000 reappeared (01_LANInterface)
2013.05.13 15:21:00 1: 192.168.1.170:1000 disconnected, waiting to reappear
2013.05.13 15:19:35 1: 192.168.1.170:1000 reappeared (01_LANInterface)
2013.05.13 15:19:30 1: 192.168.1.170:1000 disconnected, waiting to reappear
2013.05.13 15:18:09 1: 192.168.1.170:1000 reappeared (01_LANInterface)
2013.05.13 15:18:04 1: 192.168.1.170:1000 disconnected, waiting to reappear


Ich habe auch bereits herausgefunden an was es liegt. Und zwar habe ich mit Hilfe von UliM diese Abfrage von Werten aus einer XML eingebaut. Hiermit wird zum Beispiel minütlich die Aussentemperatur abgefragt:


define html_aufruf_at at +*00:01:00 {\
 my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi");;\
  foreach (@werte) {\
    if( $_ =~ m"<VALUE>(.*)<\/VALUE>") {\
      my $wert = $1;;\
  fhem("set AT $wert");;\
  }\
 }\
}

define AT dummy
attr AT alias Aussentemperatur


Diesen ganzen Code gibt es natürlich nicht nur einmal sondern mehrmals für unterschiedliche Werte (Vorlauftemperatur, Rücklauftemperatur, usw. usf.). Kommentiere ich diese aus, sind die Disconnects weg.

Jetzt weiß ich nicht so recht weiter und vermute das Netzwerk ist dann überlastet oder was auch immer. Wobei ich nicht ganz verstehen kann was das eine hier mit dem anderen zu tun hat. Benötigst Du für eine genaue Analyse noch mehr Infos? Wenn ja, welche? Oder liegt es nur an dem Code oben? Müsste man da etwas ändern?

Danke

Gruß
TinoB
BBB - debian weezy - FHEM 5.7
HMLAN - HM-LC-Bl1-FM, HM-ES-PMSw1-PI, HM-LC-Sw1-FM, HM-TC-IT-WM-W-EU, HM-WDS40-TH-I, HM-Sen-Wa-Od, HM-Sec-RHS
Dimplex Wärmepumpe / Dimplex ZL 300 - Modbus TCP
SDM630M - Modbus TCP
SolarLog 200 / SMA SonnyBoy 1.5/2.5 - Modbus TCP

martinp876

Hallo TinoB,

evtl ist nicht das Netzwerk tot sondern der FHEM prozess.
Man koennte ausmessen, wie lange einer deiner Aufrufe dauert. Wenn es mehrere sind muss man die Addieren. Dann hat man die Zeit, die dieser Vorgang benötigt und somit alles andere in FHEM blockiert.

Was kommt den so alles aus deinem CGI zurück? Ist es sinnvoll, das file mit match zu durchsuchen oder kann man das schneller? mit grep evtl?
Da steht doch nur ein wert drin - du kannst in jeden Fall mit "last" nach dem finden abbrechen.

Evtl kannst du auch alle Abfragen - du hast mehrere Fühler - in ein at zusammenfassen.

Kurzum - erst performance analyse, dann tuning.
Wenn es daran liegt wie lange dein device zum Antworten braucht sollte man den Prozess auslagern. Das ist auf User-level etwas komplexer (jedenfalls habe ich noch nicht nachgedacht darüber).

Fange einmal an mit "gettimeofday()" die Zeiten zu messen
my $start = gettimeofday();
aktionen
my $duration = gettimeofday()-$start;

Gruss
Martin

oniT

Hallo Martin,

ok, dies habe ich eingefügt:


define html_aufruf_at at +*00:01:00 {\
my $start = gettimeofday();;\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|20");;\
  foreach (@werte) {\
    if( $_ =~ m"<VALUE>(.*)<\/VALUE>") {\
      my $wert = $1;;\
  fhem("set AT $wert");;\
  }\
 }\
my $duration = gettimeofday()-$start;;\
fhem("set 1_Time_at $duration");;\
}


Herausgekommen sind da Zeiten von ca. 0,7 Sekunden. Das ganze natürlich mal 11 Werte. Auch wenn die Abfragen alle nicht immer zeitgleich stattfinden ist das schon eine Menge oder? Ich habe da nicht so die Erfahrung.

Zum Test habe ich nun die Abfragezeiten in dem at zeitversetzt von 5 Sekunden. Also zum Beispiel Wert 1 mit 25 Sekunden, Wert 2 auf 30 Sekunden usw. usf. Und siehe da, es wurde kein Disconnect gemeldet.

Jetzt könnte ich daraus Schlußfolgern, dass ich die Abfrage optimieren könnte. Sehe ich das richtig?

ZitatEvtl kannst du auch alle Abfragen - du hast mehrere Fühler - in ein at zusammenfassen.

Genau dies könnte des Rätsels Lösung sein.

Es kann die Abfrage aller Werte über die CGI erfolgen. Als Ergebnis würde ich dann zum Beispiel folgende XML erhalten:


</WEB>
 </PCO>
  </ANALOG>
   </VARIABLE>
...........
   <VARIABLE>
   </VARIABLE>
    <VALUE>-999.9</VALUE>
    <INDEX>4</INDEX>
   <VARIABLE>
   </VARIABLE>
    <VALUE>37.8</VALUE>
    <INDEX>3</INDEX>
   <VARIABLE>
   </VARIABLE>
    <VALUE>22.2</VALUE>
    <INDEX>2</INDEX>
   <VARIABLE>
   </VARIABLE>
    <VALUE>17.5</VALUE>
    <INDEX>1</INDEX>
   <VARIABLE>
  <ANALOG>
 <PCO>
<WEB>


Bisher wird ja nur jeweils 1 Index abgefragt. Somit müsste die Schleife erweitert werden und der Index + den jeweiligen Value abgefragt und in die Logdatei geschrieben werden.

Allerdings bekomme ich das nicht selbst hin. Hast Du hier eine Idee, was in der Schleife geändert werden muss?

Danke
TinoB
BBB - debian weezy - FHEM 5.7
HMLAN - HM-LC-Bl1-FM, HM-ES-PMSw1-PI, HM-LC-Sw1-FM, HM-TC-IT-WM-W-EU, HM-WDS40-TH-I, HM-Sen-Wa-Od, HM-Sec-RHS
Dimplex Wärmepumpe / Dimplex ZL 300 - Modbus TCP
SDM630M - Modbus TCP
SolarLog 200 / SMA SonnyBoy 1.5/2.5 - Modbus TCP

martinp876

Hallo TinoB,

0.7sec ist schon etwas - wenn es nicht koordiniert ist und mal 11 sind dies 7,7sec delay. Fuer mich ist dies nicht tragbar - wir wollen doch unser licht in Echtzeit anschalten. HMLAN kann bei einer Verzoegerung von 5 sec disconnected.

Es gibt 2 vorgehensweisen
a) optimieren
b) entkoppeln

Vorerst einmal optimieren - entkoppeln ist besser aber deutlich komplexer.

Wenn ich mir den input ansehe kommen die passenden Werte "<VALUE>(.*)<\/VALUE>" mehrfach mit verschiedenen indizes - und alle werden nach AT geschrieben. Macht dass sinn? Oder willst du nur einen schreiben? Stehen bleibt der Letzte, also index 1.

Frage a) wer verzoegert: GetHttpFile oder die Suche und das Setzen?
 schreiben einmal
my $start = gettimeofday();;\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|20");;\
my $duration = gettimeofday()-$start;;\
  foreach (@werte) {\
.......
falls die Verzoegerung durch das get kommt ist es nicht notwendig (aber schoener...) die Auswertung zu tunen.

Du koenntest einen timer starten und alle 5 sec einen anderen Fuehler auslesen. Dann hast du immer noch 0.7sec delay alle 5 sec, aber keinen Burst mehr - alles kontrolliert eben.

Das ganze zu forken gibt es noch nicht mit User-Interface Unterstuetzung - dann waeren die Delays aber egal.

Gruss Martin












oniT

Hallo Martin,

ok ich muss zugeben ich verstehe teilweise nur Bahnhof ;-) aber das macht ja nix, ich will es lernen und verstehen.

Ich meine ich habe etwas falsch beschrieben. Diese 0,7 Sekunden kommen bei jeder Abfrage, egal wie viele Werte abgefragt werden. Mit dieser hier habe ich begonnen um die Aussentemperatur abzufragen:


define html_aufruf_at at +*00:00:30 {\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|1");;\
  foreach (@werte) {\
    if( $_ =~ m"<VALUE>(.*)<\/VALUE>") {\
      my $wert = $1;;\
  fhem("set AT $wert");;\
  }\
 }\
}


Von diesen Abfragen habe ich im Moment 11 am LaufenDabei werden immer nur die Abfrageindizes geändert. Hier zum Beispiel Index 2:


my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|2|2");;\


oder Index 3:


my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|3|3");;\


Dabei dauert jede Abfrage ca. 0,7 Sekunden und wie Du schreibst können dies dann ganz schnell mal 7,7 Sekunden werden.
Jetzt kann man aber auch mit dieser Abfrage mehrere Werte miteinmal erhalten.

Zum Beispiel mit Index 1-10:


my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|10");;\


Das heißt, es werden die Analogindizes 1 bis 10 abgefragt. Ich habe auch hier die Zeit aufgenommen wie von Dir vorgeschlagen. Und dabei spielt es keine Rolle ob die Indizes 1-10 oder 1-100 abgefragt werden. Es dauert immer ca. 0,7 Sekunden. Die Schlußfolgerung wäre, genau das was Du schreibst, das Tuning. Ich gehe davon aus, dass wenn die Werte immer einmal komplett abgefragt werden das Problem damit gelöst ist.

Nur, und das ist jetzt die Frage, wie mach ich das?

Man erhält mit der oben genannten Abfrage von Wert 1 bis XX diese XML zurück.


</WEB>
 </PCO>
  </ANALOG>
   </VARIABLE>
   ....
   ....
   <VARIABLE>
   </VARIABLE>
    <VALUE>-999.9</VALUE>
    <INDEX>4</INDEX>
   <VARIABLE>
   </VARIABLE>
    <VALUE>37.8</VALUE>
    <INDEX>3</INDEX>
   <VARIABLE>
   </VARIABLE>
    <VALUE>22.2</VALUE>
    <INDEX>2</INDEX>
   <VARIABLE>
   </VARIABLE>
    <VALUE>17.5</VALUE>
    <INDEX>1</INDEX>
   <VARIABLE>
  <ANALOG>
 <PCO>
<WEB>


Und es sollen nur bestimmte Indizes genutzt werden. Also z.B. in eine Logdatei geschrieben werden oder oder oder ..

Wie muss ich den bisherigen Code


define html_aufruf_at at +*00:00:30 {\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|10");;\
  foreach (@werte) {\
    if( $_ =~ m"<VALUE>(.*)<\/VALUE>") {\
      my $wert = $1;;\
  fhem("set AT $wert");;\
  }\
 }\
}



ergänzen/anpassen, damit aus der Abfrage von 1 bis 10 nur die Werte von bestimmten Indizes geloggt werden?

Danke

Gruß
TinoB
BBB - debian weezy - FHEM 5.7
HMLAN - HM-LC-Bl1-FM, HM-ES-PMSw1-PI, HM-LC-Sw1-FM, HM-TC-IT-WM-W-EU, HM-WDS40-TH-I, HM-Sen-Wa-Od, HM-Sec-RHS
Dimplex Wärmepumpe / Dimplex ZL 300 - Modbus TCP
SDM630M - Modbus TCP
SolarLog 200 / SMA SonnyBoy 1.5/2.5 - Modbus TCP

martinp876

Hi ToniB,
Zitatich verstehe teilweise nur Bahnhof
werde mich bemühen.

Jeden Wert einzeln abfragen sollte man in jeden Fall vermeiden - der Overhead ist, wie man sieht, erheblich im Internet, gerade bei nur einem Wert.

Wenn du nun alle 10 (oder 100) Werte in einem Zug holst kann man die auswerten. Nur weiss ich nicht, was sie Bedeuten oder was du damit machen willst. Voraussichtich haben die 10 jeder eine andere Bedeutung und sollen in eine andere Variable.
Die ausgabe deines web-device sendet erst den Wert und dann den Index - also muessen wir uns den Wert merken und auf den index warten. Wenn der Index kommt koennen wir ausgeben.


Hier etwas zum Spielen:
my $val;
foreach (@werte){
   if($_ =~m"<INDEX>(.*)</INDEX>"){
      Log 1, "found Idx:$1 Val:$val";
      fhem("set AT$1 $val");
   }
   $val=$1 if($_ =~m"<VALUE>(.*)</VALUE>");
}


wir speichern den Wert in $val - sobald wir einen finden. Immer wenn ein "Index" kommt geben wir dann $val aus. Im Beispiel passiert es 2 mal: einmal als log und einmal als set in eine Dummy Variable. Du musst also vorher die AT definiert haben
define AT1 dummy
define AT2 dummy
.....
Alternativ - falls die Werte eine Bedeutung haben (wahrscheinlich) kannst du auch

define html_aufruf_at at +*00:00:30 {\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|10");;\
my $val;\
foreach (@werte){\
   if($_ =~m"<INDEX>(.*)</INDEX>"){\
      if ($1 == 1){\
        fhem("set aussenwert $val");\
      }elsif ($1 == 2){\
        fhem("set feuchte $val");\
      }elsif ($1 == 3){\
        fhem("set ATgestern $val");\
      }elsif ($1 == 7){\
        fhem("set rain $val");\
      }\
   }\
   $val=$1 if($_ =~m"<VALUE>(.*)</VALUE>");\
}


Ich hoffe, das Prinzip ist zu erkennen. Wo die Werte hin muessen ist mir komplett unklar, daher kann ich nicht weiter helfen.
0.7sec alle 30sec ist immer noch ein hoher Wert, aber du weisst jetzt was es bedeuted und kannst es im Auge behalten.
Gruss, Martin

oniT

Hallo Martin,

jetzt habe ich noch einen Fehler beim kopieren gemacht. Mein LogFile zeigt oben immer den neuesten Eintrag an. Das heißt Wirklichkeit steht erst der Index und dann der Value. Was bedeutet, dass der Wert nicht zwischengespeichert werden. Auch richtig ist, dass jeder Wert eine Bedeutung hat.


</WEB>
 <PCO>
  <ANALOG>
   <VARIABLE>
    <INDEX>1</INDEX>
    <VALUE>-999.9</VALUE>
   </VARIABLE>
   <VARIABLE>
    <INDEX>2</INDEX>
    <VALUE>37.8</VALUE>
   </VARIABLE>
   <VARIABLE>
    <INDEX>3</INDEX>
    <VALUE>22.2</VALUE>
   </VARIABLE>
   <VARIABLE>
    <INDEX>4</INDEX>
    <VALUE>17.5</VALUE>
   </VARIABLE>
   <VARIABLE>
   ....
   ....
   </VARIABLE>
  </ANALOG>
 </PCO>
</WEB>


Jetzt habe ich dies so versucht abzufragen:


define html_aufruf_at at +*00:00:30 {\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|10");;\
my $val;;\
 foreach (@werte){\
   if($_ =~m"<INDEX>(.*)</INDEX>"){\
     if ($1 == 1){\
 fhem("set aussenwert $val");;\
 }elsif ($1 == 2){\
 fhem("set feuchte $val");;\
 }elsif ($1 == 3){\
 fhem("set ATgestern $val");;\
 }elsif ($1 == 7){\
 fhem("set rain $val");;\
 }\
}\
   $val=$1 if($_ =~m"<VALUE>(.*)</VALUE>");;\
  }\
}


Wenn ich das richtig verstehe, fragt doch die Schleife den Index ab und gibt bei entsprechend gefunden Index den dazugehörigen Value aus. Allerdings tut es das nicht. Liegt es daran, dass doch der Index vor dem Value kommt? Wie muss dann der Code angepasst werden?

Danke

Gruß
TinoB
BBB - debian weezy - FHEM 5.7
HMLAN - HM-LC-Bl1-FM, HM-ES-PMSw1-PI, HM-LC-Sw1-FM, HM-TC-IT-WM-W-EU, HM-WDS40-TH-I, HM-Sen-Wa-Od, HM-Sec-RHS
Dimplex Wärmepumpe / Dimplex ZL 300 - Modbus TCP
SDM630M - Modbus TCP
SolarLog 200 / SMA SonnyBoy 1.5/2.5 - Modbus TCP

martinp876

Hi TinoB

ja, die Reihenfolge ist wichtig. Beim Parsen habe ich gespart - und ich dachten es kommt immer erst die Variable, dann der Index.
Du musst dir immer den ersten Wert merken und wenn der 2. da ist schreiben.
Sollte sich die Reihenfolge drehen muss man den (korrekten) weg gehen und alles merken, dann schreiben.

Nachfolgend sollte die Reihenfolge egal sein.

define html_aufruf_at at +*00:00:30 {\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|10");;\
my $val;;\
my $idx;;\
 foreach (@werte){\
   if($_ =~m"</VARIABLE>"){\
     if ($idx && $val){\
       if ($idx == 1)    {fhem("set aussenwert $val");;\
       }elsif ($idx == 2){fhem("set feuchte $val");;\
       }elsif ($idx == 3){fhem("set ATgestern $val");;\
       }elsif ($idx == 7){fhem("set rain $val");;\
       }\
     }\
   }elsif($_ =~m"<VARIABLE>"){\
     $val = $idx = 0;;\
   }elsif($_ =~m"<INDEX>(.*)</INDEX>"){\
     $idx = $1;;\
   }if($_ =~m"<VALUE>(.*)</VALUE>"){\
     $val = $1;;\
   }\
 }

oniT

Hallo Martin,

Danke für die bisherigen Infos. Nun möchte ich jetzt nicht das Homematic Thema zerschnipseln da die Ursache der Disconnects ja gelöst ist. Allerdings komme ich als noch nicht so großer Perl Spezialist mit dem Code klar.

Bei dem von Dir vorgeschlagenen wird nach der Ausführung weder im Logfile noch im Event Monitor ein Wert ausgegeben.


define html_aufruf_at at +*00:00:30 {\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|10");;\
my $val;;\
my $idx;;\
foreach (@werte){\
 if($_ =~m"</VARIABLE>"){\
  if ($idx && $val){\
   if ($idx == 1) {fhem("set aussenwert $val");;\
   }elsif ($idx == 2){fhem("set feuchte $val");;\
   }elsif ($idx == 3){fhem("set ATgestern $val");;\
   }elsif ($idx == 7){fhem("set rain $val");;\
   }\
  }\
  }elsif($_ =~m"<VARIABLE>"){\
  $val = $idx = 0;;\
  }elsif($_ =~m"<INDEX>(.*)</INDEX>"){\
  $idx = $1;;\
  }if($_ =~m"<VALUE>(.*)</VALUE>"){\
  $val = $1;;\
  }\
 }\
}


Würdest Du hier bitte nochmals drüber sehen.

Und was passiert eigentlich an dieser Stelle if($_ =~m"</VARIABLE>")? Da geht es doch um die Bedingung welche erfüllt sein muss? Das heißt doch, es wird nach dem Ende des Eintrag </VARIABLE> gesucht? Sehe ich das richtig?

Anschließend kommt die Anweisung if ($idx && $val). Was passiert hier? Bis dahin wurde doch weder ein Index noch Value abgefragt/ermittelt. Und Anschließend kommt doch schon if ($idx == 1) {fhem("set aussenwert $val"), wenn Index 1 dann schreibe Wert.

Danke

Gruß
TinoB
BBB - debian weezy - FHEM 5.7
HMLAN - HM-LC-Bl1-FM, HM-ES-PMSw1-PI, HM-LC-Sw1-FM, HM-TC-IT-WM-W-EU, HM-WDS40-TH-I, HM-Sen-Wa-Od, HM-Sec-RHS
Dimplex Wärmepumpe / Dimplex ZL 300 - Modbus TCP
SDM630M - Modbus TCP
SolarLog 200 / SMA SonnyBoy 1.5/2.5 - Modbus TCP

martinp876

Das vorgehen ist
wenn </VARIABLE> ist der Datensatze beendet. Falls jetzt $idx UND $val gesetzt wurden geben wir es aus
wenn <VARIABLE> beginnt ein neuer Datensatz - wir löschen $idx und $val
wenn "<INDEX>(.*)</INDEX>" setzen wir $idx
wenn "<VALUE>(.*)</VALUE>" setzen wir $val

Diese IFs stehe auf der gleichen Ebene, also wenn das eine

Falsch war
 }if($_ =~m"<VALUE>(.*)</VALUE>"){\
 
sollte sein:
 }elsif($_ =~m"<VALUE>(.*)</VALUE>"){\

ZitatUnd was passiert eigentlich an dieser Stelle if($_ =~m"</VARIABLE>")? Da geht es doch um die Bedingung welche erfüllt sein muss? Das heißt doch, es wird nach dem Ende des Eintrag </VARIABLE> gesucht? Sehe ich das richtig?
korrekt: ein Eintrag der </VARIABLE> beinhaltet
Zitatif ($idx && $val). Was passiert hier?
$idx und $val müssen einen Wert haben, also irgendwann einmal gesetzt worden sein.

ZitatBis dahin wurde doch weder ein Index noch Value abgefragt/ermittelt
ja, im ersten Durchgang nicht. Wir arbeiten aber eine Schleife ab. Es wird Zeile für Zeile durchgegangen. Wenn irgendwann /VARIABLE kommt kamen vorher schon INDEX und VALUE. In welcher Reihenfolge wir die IFs stellen ist nicht wichtig. $val und $idx sind ausserhalb der Schleife definiert und behalten ihren Wert auch im nächsten Durchlauf der Schleife.

ZitatUnd Anschließend kommt doch schon if ($idx == 1) {fhem("set aussenwert $val"), wenn Index 1 dann schreibe Wert.
Die IFs sind geschachtelt. Du musst beachten, was innerhalb weches IFs kommt.
Wenn $idx = 1 dann setze "aussenwert", wenn es 2 ist, dann "feuchte"

zum debuggen kannst du einfach einmal probieren:

define html_aufruf_at at +*00:00:30 {\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|10");;\
my $val;;\
my $idx;;\
foreach (@werte){\
 if($_ =~m"</VARIABLE>"){\
   fhem("set aussenwert varend");;\
 }elsif($_ =~m"<VARIABLE>"){\
   fhem("set aussenwert varbegin");;\
 }elsif($_ =~m"<INDEX>(.*)</INDEX>"){\
   fhem("set aussenwert index_$1");;\
 }elsif($_ =~m"<VALUE>(.*)</VALUE>"){\
   fhem("set aussenwert value_$1");;\
 }\
 }\
}


oniT

Ah Martin spitze, das habe ich verstanden.

könnte es dann sein, dass die Schleife nie abgearbeitet wird, weil die erste Bedingung ein WAHR liefert? Ich hab nun den Code von Dir eingefügt:


define html_aufruf_at at +*00:00:30 {\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|10");;\
my $val;;\
my $idx;;\
foreach (@werte){\
 if($_ =~m"</VARIABLE>"){\
   fhem("set aussenwert varend");;\
 }elsif($_ =~m"<VARIABLE>"){\
   fhem("set aussenwert varbegin");;\
 }elsif($_ =~m"<INDEX>(.*)</INDEX>"){\
   fhem("set aussenwert index_$1");;\
 }elsif($_ =~m"<VALUE>(.*)</VALUE>"){\
   fhem("set aussenwert value_$1");;\
 }\
 }\
}


und es wird immer nur der erste Wert (varend) ausgegeben. Zum Testen habe ich diesen dann geändert in:


define html_aufruf_at at +*00:00:30 {\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|10");;\
my $val;;\
my $idx;;\
foreach (@werte){\
 if($_ =~m"<VARIABLE>"){\
   fhem("set aussenwert varbegin");;\
 }elsif($_ =~m"</VARIABLE>"){\
   fhem("set aussenwert varende");;\
 }elsif($_ =~m"<INDEX>(.*)</INDEX>"){\
   fhem("set aussenwert index_$1");;\
 }elsif($_ =~m"<VALUE>(.*)</VALUE>"){\
   fhem("set aussenwert value_$1");;\
 }\
 }\
}


und es wird "varbegin" ausgegeben. Dann zum Testen:


define html_aufruf_at at +*00:00:30 {\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|10");;\
my $val;;\
my $idx;;\
foreach (@werte){\
 if($_ =~m"<VALUE>(.*)</VALUE>"){\
   fhem("set aussenwert value_$1");;\
 }elsif($_ =~m"</VARIABLE>"){\
   fhem("set aussenwert varende");;\
 }elsif($_ =~m"<INDEX>(.*)</INDEX>"){\
   fhem("set aussenwert index_$1");;\
 }elsif($_ =~m"<VARIABLE>"){\
   fhem("set aussenwert varbegin");;\
 }\
 }\
}


dann wird eben "value_16.7" also wieder der erste ermittelte Wert. Das würde doch eben genau dies bedeuten, die Schleife wird bis zum ersten WAHR abgearbeitet und dann beendet.

Gruß
TinoB

 
BBB - debian weezy - FHEM 5.7
HMLAN - HM-LC-Bl1-FM, HM-ES-PMSw1-PI, HM-LC-Sw1-FM, HM-TC-IT-WM-W-EU, HM-WDS40-TH-I, HM-Sen-Wa-Od, HM-Sec-RHS
Dimplex Wärmepumpe / Dimplex ZL 300 - Modbus TCP
SDM630M - Modbus TCP
SolarLog 200 / SMA SonnyBoy 1.5/2.5 - Modbus TCP

martinp876

hm - dann wird elsif nicht korrekt verarbeitet.
ersetze doch alle elsif gegen if.
elsif ist "sparsamer", da die Verarbeitung beendet wird. Bei if wird immer noch alles durchgesehen. Aber zum Testen ist es ok.

oder der Kontext geht verloren. dann probieren einmal
define html_aufruf_at at +*00:00:30 {\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|10");;\
my $val;;\
my $idx;;\
foreach my $line (@werte){\
 if($line =~m"</VARIABLE>"){\
   fhem("set aussenwert varend");;\
 }elsif($line =~m"<VARIABLE>"){\
   fhem("set aussenwert varbegin");;\
 }elsif($line =~m"<INDEX>(.*)</INDEX>"){\
   fhem("set aussenwert index_$1");;\
 }elsif($line =~m"<VALUE>(.*)</VALUE>"){\
   fhem("set aussenwert value_$1");;\
 }\
 }\
}

oniT

Wenn elsif durch if ersetzt wird läuft die Schleife durch.

Auch bei dem Test:


define html_aufruf_at at +*00:00:30 {\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|10");;\
my $val;;\
my $idx;;\
foreach my $line (@werte){\
 if($line =~m"</VARIABLE>"){\
   fhem("set aussenwert varend");;\
 }if($line =~m"<VARIABLE>"){\
   fhem("set aussenwert varbegin");;\
 }if($line =~m"<INDEX>(.*)</INDEX>"){\
   fhem("set aussenwert index_$1");;\
 }if($line =~m"<VALUE>(.*)</VALUE>"){\
   fhem("set aussenwert value_$1");;\
 }\
 }\
}


muss elsif durch if ersetzt werden. Ansonsten wird auch hier nur der erste Wert übergeben.

Jetzt dachte ich versuche es ganz einfach mal so. Es wird nach dem Eintrag INDEX gesucht. Dieser wird in $idx geschrieben und je nach gefundenen $idx wird der VALUE übergeben.


define html_aufruf_at at +*00:00:30 {\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|10");;\
my $val;;\
my $idx;;\
foreach (@werte){\
 if($_ =~m"<INDEX>(.*)</INDEX>");;\
  $idx = $1{\
   if($idx == 1){\
    if($_ =~m"<VALUE>(.*)</VALUE>"){\
     fhem("set aussenwert $1");;\
    }\
   }\
   if($idx == 2){\
    if($_ =~m"<VALUE>(.*)</VALUE>"){\
     fhem("set feuchte $1");;\
   }\
  }\
 }\
}\
}


Das war dann doch etwas zu einfach ;-) da es so nicht geht :-(

Gruß
TinoB
BBB - debian weezy - FHEM 5.7
HMLAN - HM-LC-Bl1-FM, HM-ES-PMSw1-PI, HM-LC-Sw1-FM, HM-TC-IT-WM-W-EU, HM-WDS40-TH-I, HM-Sen-Wa-Od, HM-Sec-RHS
Dimplex Wärmepumpe / Dimplex ZL 300 - Modbus TCP
SDM630M - Modbus TCP
SolarLog 200 / SMA SonnyBoy 1.5/2.5 - Modbus TCP

martinp876

schade und seltsam dass elsif nicht funktioniert.

Du musst auf die Klammern achten. {} ist immer ein Block. Dein einruecken passt nicht

Du fragst:
foreach (@werte){# fuer jede Zeile
 if($_ =~m"<INDEX>(.*)</INDEX>");;\ # ;; ist ende Solle { sein
  $idx = $1{\#setze den Index
   if($idx == 1){\#falls Index = 1
    if($_ =~m"<VALUE>(.*)</VALUE>"){\#und eine value Zeile
...

Probieren einmal:
fuer jede Zeile
--wenn Variable Ende "/VARIABLE"
----Wenn idx und val gesetzt sind (nur dann sollten wir schreiben)
------wenn idx = 1 setze aussenwert
------wenn idx = 2 setze feuchte
----loesche idx und val wenn sie geschrieben wurden
--setze idx falls es eine INDEX Zeile ist
--setze val falls es eine VALUE Zeile ist


define html_aufruf_at at +*00:00:30 {\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|10");;\
my $val=0;;\
my $idx=0;;\
foreach (@werte){\
 if($_ =~m"</VARIABLE>"){\
   if ($idx && $val){\
     if ($idx == 1) {fhem("set aussenwert $val");;}\
     if ($idx == 2) {fhem("set feuchte $val");;}\
     if ($idx == 3) {fhem("set ATgestern $val");;}\
     if ($idx == 7) {fhem("set rain $val");;}\    
   }\
   $idx=0;;\
   $val=0;;\
 }\
 if($_ =~m"<INDEX>(.*)</INDEX>"){\
   $idx = $1;;\
 }\
 if($_ =~m"<VALUE>(.*)</VALUE>"){\
   $val = $1;;\
 }\
}\
}

Probleme koennte es geben, wenn der Wert (val) = 0 ist (kein Regen?). Dann wuerde nicht geschrieben. Du kannst daher auch
define html_aufruf_at at +*00:00:30 {\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|10");;\
my $val=0;;\
my $idx=0;;\
foreach (@werte){\
 if($_ =~m"</VARIABLE>"){\
   if ($idx == 1) {fhem("set aussenwert $val");;}\
   if ($idx == 2) {fhem("set feuchte $val");;}\
   if ($idx == 3) {fhem("set ATgestern $val");;}\
   if ($idx == 7) {fhem("set rain $val");;}\    
   $idx=0;;\
   $val=0;;\
 }\
 if($_ =~m"<INDEX>(.*)</INDEX>"){\
   $idx = $1;;\
 }\
 if($_ =~m"<VALUE>(.*)</VALUE>"){\
   $val = $1;;\
 }\
}\
}

Gruss Martin

oniT

Hallo Martin,

hm, ich versteh das nicht. Es wird weder eine Fehlermeldung noch ein Wert in das LogFile oder auch in den Event Monitor geschrieben. Jetzt habe ich folgenden Test durchgeführt und Log Testidx und Testval eingefügt:


define html_aufruf_test at +*00:00:30 {\
my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|1|10");;\
my $val=0;;\
my $idx=0;;\
foreach (@werte){\
 if($_ =~m"</VARIABLE>"){\
   if ($idx && $val){\
     if ($idx == 1) {fhem("set aussenwert $val");;}\
     if ($idx == 2) {fhem("set feuchte $val");;}\
     if ($idx == 3) {fhem("set ATgestern $val");;}\
     if ($idx == 7) {fhem("set rain $val");;}\    
   }\
   $idx=0;;\
   $val=0;;\
 }\
 if($_ =~m"<INDEX>(.*)</INDEX>"){\
   $idx = $1;;\
   Log 1, "Testidx $idx";;\
 }\
 if($_ =~m"<VALUE>(.*)</VALUE>"){\
   $val = $1;;\
   Log 1, "Testval $val";;\
 }\
}\
}


Dabei wird ins LogFile der Index 1 und entsprechende Wert dazu ausgegeben. Was ja sicherlich richtig ist, weil ja dieser als erstes gefunden wird. Ich habe irgendwie das gefühl die Schleife läuft einmal durch und dann nicht mehr. Sonst müsste es doch von vorn wieder losgehen und die entsprechenden Werte zum gesuchten Index gesetzt werden, oder?

Zum Testen wird erst ab Index 2 aufgerufen:


my @werte=GetHttpFile("192.168.1.150", "/usr-cgi/xml.cgi?|A|2|10");;\


Und auch hier wird der Index 2 und dazugehörige Wert ausgegeben.

Gruß
TinoB
BBB - debian weezy - FHEM 5.7
HMLAN - HM-LC-Bl1-FM, HM-ES-PMSw1-PI, HM-LC-Sw1-FM, HM-TC-IT-WM-W-EU, HM-WDS40-TH-I, HM-Sen-Wa-Od, HM-Sec-RHS
Dimplex Wärmepumpe / Dimplex ZL 300 - Modbus TCP
SDM630M - Modbus TCP
SolarLog 200 / SMA SonnyBoy 1.5/2.5 - Modbus TCP