Ankündigung

Einklappen
Keine Ankündigung bisher.

Problem Logikeditor Livewerte

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Problem Logikeditor Livewerte

    Hallo,

    ich habe hier grad ein Problem mit einem eigenen LBS. Ich kann mir im Logikeditor keine Livewerte mehr anzeigen lassen sobald der LSB auf der Seite ist und mit einer Ausgangsbox verbunden wurde. Wenn ich auf "Aktualisieren" klicke taucht nur kurz der gruene Kreis auf und das wars dann, sonst nix.Tausche ich den LBS gegen (zB) ein 2fach Oder aus, funktioniert alles wieder wie gewohnt.
    Kann das tatsaechlich an dem LBS liegen oder hat das wohl andere Gruende?

    gruesse :: Michael

    #2
    Poste mal den LBS. So kann man schwer etwas sagen.

    Kommentar


      #3
      Gerne - ist noch schwer mit debug Kram aus der Console geflutet und nicht fertig, aber er laeuft zumindest. Ich poste den Code hier aber trotzdem mal unveraendert

      Code:
      ###[DEF]###
      [name        = Squeeze Server    ]
      
      [v#1        = 0    ]
      [v#2        = 0    ]
      [v#3        = 0    ]
      
      [e#1        = Trigger #init=1 ]
      [e#2        = IP ]
      [e#3        = Port #init=9090 ]
      [e#4        = coverURL ]
      [e#5        = subscription #init='subscribe:0 tags:aCdDefgiIjJKlOqrstTuxy' ]
      [e#6        = unused1 ]
      [e#7        = unused2 ]
      [e#8        = unused3 ]
      [e#9        = unused4 ]
      [e#10        = command ]
      
      [a#1        = Result ]
      [a#2        = Fehler ]
      
      ###[/DEF]###
      
      
      ###[HELP]###
      Vorlage: LBS-Dämon
      
      Der Baustein wird automatisch gestartet, sobald EDOMI gestartet wird (E1 hat den Initialwert 1).
      Das EXEC-Script wird dann einmalig(!) gestartet und läuft in einer Schleife solange, bis EDOMI beendet oder neugestartet wird.
      
      Der Baustein erhält nicht(!) den Status 1 (LBS "läuft"), um Ressourcen zu sparen: Der [LBS]-Abschnitt dient nur dazu, das EXEC-Script einmalig(!) zu starten.
      ###[/HELP]###
      
      
      ###[LBS]###
      <?
      function LB_LBSID($id) {
          if ($E=getLogicEingangDataAll($id)) {
          
              if ($E[1]['value']!=0 && $E[1]['refresh']==1) {
                  
                  if (getLogicElementVar($id,1)!=1) {    //dieses Konstrukt stellt sicher, dass das EXEC-Script nur einmal gestartet wird
                      setLogicElementVar($id,1,1);
                      callLogicFunctionExec(LBSID,$id);
                  }
                  
              }
              if ($E[10]['refresh']) {
                  setLogicElementVar($id,2,$E[10]{'value'});
              }
          }
      }
      ?>
      ###[/LBS]###
      
      
      ###[EXEC]###
      <?
      require(dirname(__FILE__)."/../../../../main/include/php/incl_lbsexec.php");
      set_time_limit(0);
      sql_connect();
      
      writeToTraceLog(0,true,'Squeeze Server EXEC-Script gestartet');
      
      //-------------------------------
      //Dämon wurde gestartet
      //-------------------------------
      //eigener Code...
      if ($E=getLogicEingangDataAll($id)) {
          while(getSysInfo(1)>=1) {    //Hauptschleife (wird beim Beenden oder Neustart von EDOMI verlassen)
              $host=$E[2]['value'];
              $port=$E[3]['value'];
              $addr = gethostbyname($host);
              $cmdTimeout=1000000 * 5; # 5s
              $connectTimeout=1000000 * 10; # 10s
              $quant=500000;
              //$subscription="subscribe:0 tags:aCdejJKlstTxyuOrqDiIgf";
              $subscription=$E[5]['value'];
      
      
              $player["_server"]=array("_ip"=>$host,"_port"=>$port,"_timeout"=>$connectTimeout,"_cmdtimeout"=>$cmdTimeout,"_subscription"=>$subscription);
      
              $lmsc="";
              connect($player);
      
              $resp='';
              $c=0;
              $oldCMD=getLogicElementVar($id,2);
              while ($lmsc and !feof($lmsc)) {
                  $E=getLogicEingangDataAll($id);
                  if (getLogicElementVar($id,2)) {
                      $oldCMD=getLogicElementVar($id,2);
                      setLogicElementVar($id,2,NULL);
                      writeToTraceLog(0,true,"Sending: $oldCMD"); 
                      send($oldCMD);
                  }
                  #$i=fgets(STDIN);
                  #fwrite($lmsc,$i);
                  #if ($line=stream_get_contents($lmsc)) { echo $line; }
                  if ($resp=stream_get_contents($lmsc)) {
                      #print rawurldecode("\nRESP: $resp\n");
                      parseResponse($resp);
                  }
                  usleep($quant);
      //            echo ".";
      #            $c++;
      #            if ($c>6) {
      #                $c=0;
      #            }
                  while(feof($lmsc)) { connect($player); usleep($player["_server"]["_timeout"]); }
                  if ($E[1]['value']==0) { finish(); }
              }
          }
      }
      finish();
      
      //-------------------------------
      //Dämon wurde beendet (EDOMI wurde beendet oder neugestartet)
      //Achtung: Nach ca. 3 Sekunden wird der Prozess vom Betriebssystem hart beendet!
      //-------------------------------
      //eigener Code, z.B. Aufräumen, Verbindungen trennen, etc.
      function finish() {
          global $lmsc,$id;
          setLogicElementVar($id,1,0);
          writeToTraceLog(0,true,'Squeeze Server EXEC-Script stoppt');
          $lmsc->disconnect();
          sql_disconnect();
          exit();
      }
      
      function connect($player) {
          global $lmsc;
          $lmsc=stream_socket_client("tcp://".$player["_server"]["_ip"].":".$player["_server"]["_port"], $errNo, $errMsg);
          stream_set_blocking($lmsc, false);
          if ($lmsc === false) {
              throw new UnexpectedValueException("Failed to connect: $errorMessage");
          }
          # send init commands
          parseResponse(send("listen 1"));
          parseResponse(send("players"));
      }
      
      function parseResponse($response) {
          global $player;
          $r=explode("\n",$response);
          foreach ($r as $line) { # parse each line (if not empty)
              $ln=0; # number of currently parsed line
              if ($line) {
                  $result=preg_split("/\s+/",$line); # split recieved line into single atoms
                  $c=0;
                  if (preg_match('/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/',rawurldecode($result[0]))) {
                      # first atom is a MAC address - resp. playerID
                      $playerID=rawurldecode($result[0]);
                      #print "Found playerID: $playerID\n";
                      $player[$playerID]["player_id"]=$playerID;
                      if (isset($result[1]) && isset($result[2]) && isset($result[3]) && rawurldecode($result[1].$result[2].$result[3])=="status-1") {
                          # found a status response, parse result
                          foreach ($result as $atom) {
                              if (preg_match('/^([^:]+):(.*)$/',rawurldecode($atom),$matches)) {
                                  # cycle through the interesting properties
                                  foreach (array(
                                      'subscribe','tags',
                                      'player_name','player_connected','player_ip','power','signalstrength',
                                      'mode','time','rate','duration','can_seek','mixer volume','playlist repeat',
                                      'playlist shuffle','playlist mode','seq_no','playlist_cur_index',
                                      'playlist_timestamp','playlist_tracks','digital_colume_control','playlist index',
                                      'id','title','artist','compilation','duration','album_id','coverart',
                                      'artwork_track_id','album','artist_id','tracknum','remote','year',
                                      'url','artwork_url','disc','samplesize','genre','filesize',
                                      'samplerate','playcount','bitrate','disccount','addedTime','artwork_url'
                                  ) as $prop) {
                                      # set properties and leave loop after match was found
                                      if ($matches[1]==$prop) { $player[$playerID][$prop]=rawurldecode($matches[2]); break; }
                                  }
                                  # add additional properties
                                  # add a percentage of the current playing position
                                  if (isset($player[$playerID]['time']) && isset($player[$playerID]['duration'])) {
                                      $player[$playerID]['_position']=calcPosition($player[$playerID]['time'],$player[$playerID]['duration']);
                                  } else {
                                      $player[$playerID]['_position']=0;
                                  }
                              }
                          }
                          #print "\nXML: ".toXML($player)."\n";
                          #print "\nSER: ".serialize($player[$playerID])."\n";
                          #print "LINE: ".rawurldecode($line)."\n";
                          output($player[$playerID]);
                      } else if ($result[1]=="playlist" && $result[2]=="newsong") {
                          # player is starting a new song
                      } else if ($result[1]=="connected") {
                          $player[$playerID]['player_connected']=rawurldecode($result[2]);
                          #print "\nXML: ".toXML($player)."\n";
                          output($player[$playerID]);
                      } else if ($result[1]=="time") {
                          $player[$playerID]['time']=rawurldecode($result[2]);
                          if (isset($player[$playerID]['duration'])) {
                              $player[$playerID]['_position']=calcPosition($player[$playerID]['time'],$player[$playerID]['duration']);
                          } else {
                              $player[$playerID]['_position']=0;
                          }
                          #print "\nXML: ".toXML($player)."\n";
                          output($player[$playerID]);
                      } else if ($result[1]=="duration") {
                          $player[$playerID]['duration']=rawurldecode($result[2]);
                          #if (isset($player[$playerID]['time'])) {
                      #        $player[$playerID]['_position']=calcPosition($player[$playerID]['time'],$player[$playerID]['duration']);
                      #    } else {
                      #        $player[$playerID]['_position']=0;
                      #    }
                      #    print "\nXML: ".toXML($player)."\n";
                      } else if ($result[1]=="mode") {
                          $player[$playerID]['mode']=rawurldecode($result[2]);
                          #print "\nXML: ".toXML($player)."\n";
                          output($player[$playerID]);
                      } else if ($result[1]=="newmetadata") {
                          # ignore
                      } else if ($result[1]=="prefset") {
                          # ignore
                      } else if ($result[1]=="playlist") {
                          # ignore
                      } else if ($result[1]=="mixer") {
                          # ignore
                      } else if ($result[1]=="alarm") {
                          # ignore
                      } else if ($result[1]=="pause") {
                          # ignore
                      } else if ($result[1]=="power") {
                          # ignore
                      } else if ($result[1]=="button") {
                          # ignore
                      } else if ($result[1]=="menustatus") {
                          # ignore
                      } else if ($result[1]=="client") {
                          if ($result[2]=="disconnect") { debug("client ".$playerID." disconnected"); }
                          if ($result[2]=="reconnect") { debug("client ".$playerID." reconnected"); }
                          if ($result[2]=="new") { debug("client ".$playerID." connected"); }
                      } else if ($result[1]=="displaynotify") {
                          # ignore
                      } else {
                          //print "\nUNKNOWN RESPONSE\n$line\n\n";
                          writeToTraceLog(0,true,'Squeeze Server DEBUG (UNKNOWN RESPONSE): $line');
                      }
                  } else {
                      # first atom not a MAC address, must be a server response
                      if (preg_match("/^listen/",rawurldecode($line))) {
                          # listen command, ignore
                      } else if (preg_match("/^players\s+count:(\d+)$/",rawurldecode($line),$count)) {
                          # received player count
                          # collect player information
                          for ($i=1;$i<=$count[1];$i++) {
                              parseResponse(send("players ".($i-1)." ".$i));
                          }
                      } else if (preg_match("/^players\s+\d+\s+\d+\s+(.*)$/",rawurldecode($line),$server_response)) {
                          $atoms=preg_split("/\s+/",$server_response[1]);
                          #print_r($atoms);
                          foreach ($atoms as $atom) {
                              if (preg_match('/^([^:]+):(.*)$/',rawurldecode($atom),$matches)) {
                                  # cycle through the interesting properties
                                  if ($matches[1]=="playerid") {
                                      $playerID=$matches[2];
                                      $player[$playerID]["player_id"]=$playerID;
                                      parseResponse(send($playerID." status - 1 ".$player["_server"]["_subscription"]));
                                  }
                                  if (isset($playerID)) {
                                      if ($matches[1]=="uuid") { $player[$playerID]["player_uuid"]=$matches[2]; }
                                      else if ($matches[1]=="ip") { $player[$playerID]["player_ip"]=$matches[2]; }
                                      else if ($matches[1]=="name") { $player[$playerID]["player_name"]=$matches[2]; }
                                      else if ($matches[1]=="model") { $player[$playerID]["player_model"]=$matches[2]; }
                                      else if ($matches[1]=="isplayer") { $player[$playerID]["player_isplayer"]=$matches[2]; }
                                      else if ($matches[1]=="displaytype") { $player[$playerID]["player_displaytype"]=$matches[2]; }
                                      else if ($matches[1]=="canpoweroff") { $player[$playerID]["player_canpoweroff"]=$matches[2]; }
                                      else if ($matches[1]=="connected") { $player[$playerID]["player_connected"]=$matches[2]; }
                                  }
                              }
                              #print "\nATOM: ".$atom."\n";
                          }
                      } else {
                          writeToTraceLog(0,true,'Squeeze Server DEBUG (UNKNOWN SERVER): $line');
                          //print "\nUNKNOWN SERVER:\n$line\n\n";
                      }
                  }
                  #print_r($player);
                  #print "\nLINE: ".rawurldecode($line)."\n\n";
      
                  #foreach ($result as $atom) {
                  #    print $c++." :: ".rawurldecode($atom)."\n\n\n";
                  #}
                  //print "-";
              } else {
                  #print "EMPTY LINE...\n";
              }
          }
      }
      
      function calcPosition($time,$dur) {
          # calculates position percentage
          if ($dur) {
              return(round($time*100/$dur));
          } else {
              return 0;
          }
      }
      
      function send($cmd) {
          global $lmsc, $errNo, $errMsg, $timeout, $cmdTimeout;
          if (!fwrite($lmsc,$cmd."\n")) {
              conError("255","Could not send to server");
              return;
          } else {
              $starttime=microtime(true);
              $resp="";
              while ((!feof($lmsc)) && ($resp=="") && (microtime(true)-$starttime < $cmdTimeout)) {
                  $resp.=stream_get_contents($lmsc);
                  usleep(500);
              }
              #return rawurldecode($resp);
              return $resp;
          }
      }
      
      function conError($en,$et) {
          
      }
      
      function output($a) {
          global $id;
          #print "\n".serialize($a)."\n\n";
          #print "\n"; print_r($a); print "\n";
          #print "*";
          //$a=print_r($a,true);
          setLogicLinkAusgang($id,1,serialize($a));
      }
      
      function debug($a) {
          //print "\nDEBUG: $a\n";
          writeToTraceLog(0,true,'Squeeze Server DEBUG: $a');
      }
      
      ?>
      ###[/EXEC]###

      Kommentar


        #4
        # 5s ??? Kommentare leitet man mit // ein => "Syntax-Fehler", d.h. das EXEC-Script läuft vermutlich garnicht...
        EDOMI - Intelligente Steuerung und Visualisierung KNX-basierter Elektro-Installationen (http://www.edomi.de)

        Kommentar


          #5
          Zitat von gaert Beitrag anzeigen
          # 5s ??? Kommentare leitet man mit // ein => "Syntax-Fehler", d.h. das EXEC-Script läuft vermutlich garnicht...
          Tut mir leid, aber das ist falsch: http://php.net/manual/de/language.ba...x.comments.php

          Und der EXEC Teil laeuft - er schreibt auch ins Trace-Log. Und wenn ich die Ausgangsbox nicht in die Logik-Seite packe und mit dem LBS verbinde, dann funktionieren auch die Live-Werte wieder... o\

          Kommentar


            #6
            Aha, ok... Das wußte ich noch nicht Hab' ich allerdings auch noch nie in irgendwelchen PHP-Sources gesehen...

            Zu Deinem Problem: Ohne jetzt den ganzen Quelltext studiert zu haben: Vermutlich setzt Du irgendwelche Sonderzeichen an einen Ausgang - und die bringen den HTML-Code im Logikeditor aus dem Tritt... Nicht erlaubt sind z.B. Zeichen wie " oder '
            EDOMI - Intelligente Steuerung und Visualisierung KNX-basierter Elektro-Installationen (http://www.edomi.de)

            Kommentar


              #7
              Zitat von gaert Beitrag anzeigen
              Vermutlich setzt Du irgendwelche Sonderzeichen an einen Ausgang - und die bringen den HTML-Code im Logikeditor aus dem Tritt... Nicht erlaubt sind z.B. Zeichen wie " oder '
              Um Dich zu zitieren: "Aha, ok..."
              Das Ergebnis enthaelt vermutlich derartige Sonderzeichen, denn das ist momentan ein serialisiertes, assoziatives Array (welches dann spaeter von nem anderen Baustein geparsed werden soll), da sind dann mal mindestens Hochkommata drin...
              Abgesehen von der nicht funktionierenden Anzeige im Logikeditor bringt das dann aber keine weiteren technischen Probleme mit sich, oder?

              gruesse :: Michael

              Kommentar


                #8
                Oh doch! KOs (und auch Ausgänge - sind intern auch KOs) dürfen nur bestimmte Sonderzeichen enthalten. Gedacht sind KOs/Ausgänge prinzipiell für "normale" Strings und Zahlen. Zeichen wie ASCII(13) etc. oder gar "Bytes" in Stringform sind nicht erlaubt.

                By the way: Das Filtern der KOs ist schon in der Schublade, damit es nicht zu Problemen kommen kann, falls mal ein Sonderzeichen dabei ist...
                EDOMI - Intelligente Steuerung und Visualisierung KNX-basierter Elektro-Installationen (http://www.edomi.de)

                Kommentar


                  #9
                  Das was da transportiert wird ist quasi quoted-printable, also ohne irgendwelche Binaerdaten, Bimmeln, Tabs, Newline usw usf. Aber es sind halt verschiedenste Klammerformen drin, sowie mitunter " und !.
                  Im Prinzip sieht das Ergebnis so aus, wobei die Arraywerte alle "normale" Strings und Zahlen sind:

                  PHP-Code:
                  [root@edomi ~]# cat test.php ; php test.php
                  <?
                  $array = array();
                  $array[] = 1;
                  $array[] = 2;
                  $array[] = 3;
                  $array[] = "hallo:{}'";

                  echo serialize($array)."\n";
                  ?>
                  a:4:{i:0;i:1;i:1;i:2;i:2;i:3;i:3;s:9:"hallo:{}'";}
                  Oder sollte ich das besser zur Not nochmal durch die base64 Muehle drehen?

                  Kommentar


                    #10
                    Das ' ist das Problem - wird zur Zeit noch ungefiltert in die DB geschrieben, bzw. es wird versucht SQL-Injection quasi... Im nächsten Update werden diverse Zeichen rausgefiltert oder escaped - ich werde berichten.
                    EDOMI - Intelligente Steuerung und Visualisierung KNX-basierter Elektro-Installationen (http://www.edomi.de)

                    Kommentar


                      #11
                      Ich denke, ich werds trotzdem durch base64 ziehen - die Werte die da im Array stehen koennen hab ich selber nicht unter Kontrolle, die kommen fast allesamt vom LMS und da kann weiss-gott-was drinstehen. Also jetzt mal unabhaengig von der Web-Darstellung ist das wahrscheinlich der sicherste Weg - und kosten tut das auch nicht viel mehr...

                      Danke fuer die schnelle Antwort!

                      Kommentar


                        #12
                        Das wäre eine Option. Wie an anderer Stelle schon gesagt: Sonderzeichen sind ein Problem in EDOMI - nicht zuletzt weil's eine Webapplikation ist. Da gibt es eine Menge "Fallen" hier und da - ich arbeite daran...
                        EDOMI - Intelligente Steuerung und Visualisierung KNX-basierter Elektro-Installationen (http://www.edomi.de)

                        Kommentar


                          #13
                          Zitat von gaert Beitrag anzeigen
                          Das wäre eine Option.
                          Ja, wenns b64 kodiert ist, laeuft auch der Logik-Editor wieder sauber. Grad probiert.
                          Dumm nur, dass ich jetzt mit der Ausgabe nicht mehr wirklich viel anfangen kann - Katze, Schwanz, beissen, und so
                          mit htmlentities oder urlencodes kann ich leider nicht arbeiten, weil ich das im Zweifelsfall nicht mehr korrekt zurueck gewandelt bekomme. Vllt sollte ich neben der eigentlichen Ausgabe zum Datenaustausch einen debug Ausgang dafuer vorsehen, ist vermutlich das einfachste o\

                          BTW: das Problem tritt auch (was Dich vermutlich nicht sehr verstoeren wird) in aehnlicher Form im KNX-Monitor auf wenn man dort Werte abfragen moechte.

                          Kommentar


                            #14
                            Ich weiß Ab dem nächsten Update sind ohnehin nur noch diese Zeichen für KOs und Ausgänge erlaubt:

                            A..Z a..z 0..9 äöü ÄÖÜ ß <space> []_$#+*%.()?!,;-:/&=@{}

                            Was macht Dein LBS denn genau? Sofern er einen HTTP-Request oder ähnliches absetzt, kannst Du dies ja einfach direkt im LBS erledigen - dann ist der Ausgang quasi überflüssig.

                            PS: Bei dem #init='...' sind die ' ebenfalls "verboten" und werden entfernt..
                            EDOMI - Intelligente Steuerung und Visualisierung KNX-basierter Elektro-Installationen (http://www.edomi.de)

                            Kommentar


                              #15
                              Zitat von gaert Beitrag anzeigen
                              A..Z a..z 0..9 äöü ÄÖÜ ß <space> []_$#+*%.()?!,;-:/&=@{}
                              Ui, da muss man aber aufpassen dann

                              Was macht Dein LBS denn genau? Sofern er einen HTTP-Request oder ähnliches absetzt, kannst Du dies ja einfach direkt im LBS erledigen - dann ist der Ausgang quasi überflüssig.
                              Logitech Squeezeboxen (bzw Nachbauten) ansteuern, also im wesentlichen Multiroom-Audio. Das sollte ein zweistufiges Konzept sein, wobei ein zentraler Baustein (der obige) als Daemon eine bidirektionale telnet Verbindung zum Server aufrecht erhaelt ueber die sowohl Befehle abgesetzt werden, als auch zentral der Status aller Player abgefragt wird (inkl. der ID-Tags aus den mp3 Files, worueber ich dann nicht so direkt die Kontrolle haette).
                              Fuer jeden Client (also jeden Player) gibts dann einen eigenen Baustein, der die gesammelten Ausgaben des Daemons empfaengt, die fuer ihn relevanten Teile aus dem Array rauspflueckt und als KOs bereitstellt. Weiterhin koennen ueber den Client-LBS dann auch Befehle an den Daemon uebergeben werden, die er dann entsprechend aufbereitet und schlussendlich zum Server schickt.
                              Alternativ muesste ich fuer jeden Client eine telnet-Verbindung aufrecht erhalten, das ergibt insgesamt IMHO aber zuviel Overhead. Um den Datenaustausch zwischen den Bausteinen komme ich also nicht drumrum, das sollte dann eben ueber interne KOs erledigt werden.

                              PS: Bei dem #init='...' sind die ' ebenfalls "verboten" und werden entfernt..
                              Auch gut zu wissen... wenn dann aber, wie in meinem Beispiel, der init-Wert Leerzeichen enthaelt: wie ist dann die korrekte Syntax? (Momentan wird wegen der ' im init nicht genoergelt und der Wert kommt auch korrekt im Baustein an.)

                              Tante Edith sagt ich sollte besser noch fragen ob es Laengenbeschraenkung fuer interne KOs gibt

                              Kommentar

                              Lädt...
                              X