Homeline is Online

Hallo zusammen,

nach langem versuchen und viel Unterstützung von euch ist es nun gelungen, das Protokoll auszuwerten und das Homeline-System von Rademacher in Betrieb zu nehmen. Da das Script zum Auswerten der Daten noch nicht besonders elegant aussieht, habe ich hierzu nochmal eine Frage.

Beim Auslesen der Daten und filtern der Adressen durchläuft das Script unzählige IF-Anweisungen. Kann man das irgenwie abkürzen oder gibt es in PHP Sprungfunktionen innerhalb des Scripts um nicht das komplette Script durchlaufen zu müssen? Habe im Online-Manual leider nichts gefunden, weiss auch nicht genau, wonach ich da suchen muss.
Da die Adresse am Anfang des Scripts ja schon bekannt ist, müsste man doch die Auswertung direkt anspringen können, oder kann man das anders lösen?

Hier mal ein Beispiel dazu:


 //Signalstation 18 (Fenster WiGa) auswerten
if (($Adresse == 18) and ($Sensor == 5)) {
    $Daten=(Float)$Daten;
    SetValueFloat("Temperatur_Garten",($Daten)/10);
  }

//Signalstation 36 (WiGa Luefter) auswerten
if (($Adresse == 36) and ($Sensor == 5)) {
    SetValueInteger("Helligkeitssensor",$Daten);
  }

//Signalstation 37 (Flur OG) auswerten
if (($Adresse == 37) and ($Sensor == 5)) {
    $Daten=(Float)$Daten;
    SetValueFloat("Temperatur_Wasserspeicher",($Daten)/10);
  }
if (($Adresse == 37) and ($Sensor == 6)) {
    SetValueInteger("Multitaster_Flur_OG",$Daten);
  }

Viele Grüße und danke für eure Hilfe,

Thomas

benutze if/elseif: http://de3.php.net/manual/de/control-structures.elseif.php

Hallo Olli,

hatte ich auch dran gedacht, allerdings wollte ich NICHT alle if-anweisungen durchlaufen, sondern direkt an die einzelnen Auswertungen springen, um die Verarbeitungszeit so kurz wie möglich zu halten.
Es sind hier mehr als 50 IF-Anweisungen um alle Adresse abzudecken.
Gibt es keine Sprungfunktionen innerhalb des Scripts wie z.B. Basic oder so?

Gruß,

Thomas

nein, kein goto. php ist aber auch bei 50 conditions oder weiterem quellcode schnell genug :slight_smile:

ich include bei fast allen ips-scripten ca. 15-20 KB an zusätzlichem code und es läuft ohne irgendwelche geschwindigkeitsprobleme. ansonsten kannst du ja einfach mal die scriptlaufzeit messen lassen…

Hallo Thomas,

es wuerde auch anders gehen. Erstelle ein Array, in welchen die Zuordnung der Adressen, Sensoren etc. drin sind. Dann suchst Du nur mit einer Anweisung im Array und hast sofort fuer die weiteren notwendigen Befehle die Parameter im Arrayeintrag.

Gruss Torro

Torro, es geht auch ohne Array :wink:

 
<?
/*
*******************************
 IP-SYMCON Event Scripting
*******************************
File     : func_test.ips.php
Trigger  : 
Interval : 
*/
 
$Adresse = 18;
$Sensor  = 6;
$Daten   = 7600;
call_user_func("Process_".strzero($Adresse,3).strzero($Sensor,3), $Daten);
return;  // that's all - no more if's ;-)
 
//-------------------------------------------------------------------------
// helper functions...
function strzero( $v, $len)
{
   return( str_pad( strval(intval($v)), $len, "0", STR_PAD_LEFT));
}
 
//-------------------------------------------------------------------------
// data-handler functions...
 
function Process_018005( $Daten )
{
  echo "executing Process_018005 with Daten=$Daten";
}
 
function Process_018006( $Daten )
{
  echo "executing Process_018006 with Daten=$Daten";
}
?>


Hallo Torro u, Olli,

werde ich mal testen, auch wenn ich noch nicht genau weiss, wie ich das umsetzten soll.

@Olli

Das Script wird durch die COM getriggert, und da ist ganz schön was los. Deshalb wollte ist das Script so schlank wie möglich halten, um die CPU zu entlasten. Aber vielleicht sind die 50 IF’s auch gar nicht so wild.
Wie kann ich denn die Scriptlaufzeit messen?

Thomas

Hallo Thomas,

da schaust Du hier.

Gruss Torro

Hast Du dafür evtl. auch ein Beispiel o. Link parat?

Gruß,

Thomas

Hallo Thomas,

nicht auf die schnelle…

Gruss Torro

Mach dir um die Laufzeit keine Sorgen. Solange das nur IF’s sind und keine Rekursiven Funktionen sind das Laufzeiten im Millisekunden Bereicht. Mit der neuen Beta gibts auch Multithreading. Da kommt es dann auf +/- paar Millisekunden nicht an. Du kannst im Kernel->Debug gucken, wie lange dein Script gebraucht hat. Seit der BETA#2 werden dort auch die Millisekunden angezeigt.

Übrigens ist die Idee von Olli recht elegant. Dadurch ist die Sache sehr einfach und für andere User erweiterbar :slight_smile:

Grüße, paresy

… nur leider habe ich noch nicht durchgeblickt, was er da gemacht hat. :confused:
Ist vielleicht am Anfang noch ein bischen zu viel.

Gruß,

Thomas

ganz grob:

a) ich erzeuge einen string, der einen Funktionsnamen darstellt
-> „Process_“.strzero($Adresse,3).strzero($Sensor,3)

b) ich rufe den String als Funktion auf
-> call_user_func(„Process_“.strzero($Adresse,3).strzero($Sensor,3), $Daten);
(siehe die Doku zu call_user_func bei www.php.net)

c) für jede reale Adresse/Sensor-Kombination muss eine Funktion geschreiben werden die den Code ausführt, der bei dir innerhalb deine if-Anweisungen ist
wobei z.B. die Funktion „Process_018005()“ die Adresse=18 und den Sensor=5 abarbeitet

Hallo Olli,

ich lese schon den ganzen Nachmittag. So in Teilen ist das auch klar, obwohl ich mit Funktionen noch nicht gearbeitet habe. Aber ich verstehe nicht, warum $Daten schon in der Function drinsteht.
Auch weiss ich nicht genau, was das genau bringen soll. Ob ich jede IF Anweisung abfragen muss oder jede Funktion, oder wird nur die betreffende Funktion „angefahren“?

Gruß,

Thomas

ok, du schreibst deinen Code:

 
//Signalstation 18 (Fenster WiGa) auswerten 
if (($Adresse == 18) and ($Sensor == 5)) { 
    $Daten=(Float)$Daten; 
    SetValueFloat("Temperatur_Garten",($Daten)/10); 
  } 
//Signalstation 36 (WiGa Luefter) auswerten 
if (($Adresse == 36) and ($Sensor == 5)) { 
    SetValueInteger("Helligkeitssensor",$Daten); 
  } 
//Signalstation 37 (Flur OG) auswerten 
if (($Adresse == 37) and ($Sensor == 5)) { 
    $Daten=(Float)$Daten; 
    SetValueFloat("Temperatur_Wasserspeicher",($Daten)/10); 
  } 
if (($Adresse == 37) and ($Sensor == 6)) { 
    SetValueInteger("Multitaster_Flur_OG",$Daten); 
  }  
 

so um:

 
call_user_func("Process_".strzero($Adresse,3).strzero($Sensor,3), $Daten);
return;  // that's all - no more if's ;-)
 
//-------------------------------------------------------------------------
// helper functions...
function strzero( $v, $len)
{
   return( str_pad( strval(intval($v)), $len, "0", STR_PAD_LEFT));
}
//-------------------------------------------------------------------------
// data-handler functions...
function Process_018005( $Daten )
{
 $Daten=(Float)$Daten; 
    SetValueFloat("Temperatur_Garten",($Daten)/10); 
}
function Process_036005( $Daten )
{
    SetValueInteger("Helligkeitssensor",$Daten); 
}
function Process_037005( $Daten )
{
    $Daten=(Float)$Daten; 
    SetValueFloat("Temperatur_Wasserspeicher",($Daten)/10); 
}
function Process_037006( $Daten )
{
    SetValueInteger("Multitaster_Flur_OG",$Daten); 
}

zumindest bzgl. des Code-Schnipsels den du gepostet hast… und was es bringt? Keine aneinandergereihten if-konstrukte mehr - die wolltest du ja loswerden und ein goto konnte ich dir nicht anbieten :wink:

Es wird für jede Adress/Sensor-Kombination nur noch eine Funktion ausgeführt (die natürlich zu implementieren ist) - ohne mit tausend if’s irgendwelche Prüfungen durchzuführen… aber ob das schneller ist… naja… aber es sind keine if’s mehr dabei :wink:

Hallo Olli,

vielen dank für deine Hilfe. Wie ich den Code nun umsetzten muß, ist mir jetzt klar. Allerdings habe ich immer doch nicht verstanden, was „function“ genau macht oder ist. OK, es wird einen Function mit einem bestimmten Namen generiert, und weiter unten ausgeführt. Aber warum ist z.B. $Daten bestandteil der function? :confused:
Ich habe hier noch keinen Vorteil zu IF entdecken können, auch wird der Code dadurch nicht weniger. Ob das schneller ist, kann ich ja mit Torro’s Laufzeitcode mal testen, obwohl das jetzt mit Multithreating ja auch kein Problem mehr darstellt.
Wenn du nochmal ein paar Minuten Zeit hast, kannst du mir vielleicht nochmal die Funktion von „function“ erklären, aus dem PHP.net bin ich nicht wirklich schlauer geworden.

Viel Grüße,

Thomas

Vielleicht ist es das was du suchst… Aber intern ist das nicht viel anders als eine If-Klausel. Nebenbei ist eine If-Klausel nativ das heisst sehr Hardwarenah. Einfacher kannste es deinem Computer kaum machen.

Switch könnte gefühlsmäßig etwas schneller sein. Musste mal ausprobieren.

<?PHP
switch($Sensor)
{
  case 5:
    switch($Adresse)
    {
      case 18:
        $Daten=(Float)$Daten; 
        SetValueFloat("Temperatur_Garten",($Daten)/10); 
      break;
      case 36:
        SetValueInteger("Helligkeitssensor",$Daten);
      break;
      case 37:
        $Daten=(Float)$Daten; 
        SetValueFloat("Temperatur_Wasserspeicher",($Daten)/10);
      break;
    }
  break;
  case 6:
    echo 'Sensor $Sensor'; 
  break;
}
?>

Habs frei Hand getippt. Ungetestet.

Toni

Hi Toni,

das ist das, was ich gesucht habe :slight_smile:
Wenn man nicht genau weiss, was man sucht, ist es auch schwer, was zu finden.

Ich habe gerade meine PHP Lern-CD durchgeackert und bin auch genau hier gelandet. Allerdings werde ich die Adresse nun mit Switch/Case auswerten und den Sensor dann in Switch mit IF. Mit break kann ich dann die ganze Abarbeitung beenden, das ist ja das, was ich auch wollte.
Jetzt werde ich mir mal noch die Lektion Funktionen anschauen, vielleicht kann ich davon auch noch was verwenden.

Vielen dank für eure Hilfe,

Thomas

Schön, dass ich helfen konnte…

Wenn du if-Klauseln verwendest, dann versuche mit if/elseif zu arbeiten. Das entlastet den Rechner doch schon ziemlich deutlich (wenn man überhaupt von Belastung reden kann). Ols Optimierungsansatz kannst du dann noch versuchen Bedingungen, die sehr häufig auftreten, nach oben zu setzen. Ein Else und Elseif Block wird nämlich nur noch ausgeführt/geprüft wenn alle vorigen Klauseln False ergaben.

Toni

… werde ich mal so versuchen. Adressen sind das so ca. 30 Stück, Sensoren pro Adresse nur 2 (5 u. 6), die anderen sind Aktoren. Die Stationen, die ständig senden wie z.B. Temperaturen usw werde ich dann ganz nach oben setzen, die anderen sind dann Taster u. Schalter und werden nicht so häufig gebraucht und landen weiter unten. Danke für den Hinweiss.

Gruß,

Thomas