Der erste Ausflug ins Scripting

Guten Morgen,
ich mache gerade meine ersten Gehversuche mit einem Script. Für den Test habe ich mich auf 3 Baugruppen beschränkt:

  1. EIB Schaltaktor der eine Heizung an/ausschaltete.
    Anschalten funktioniert z.B.über EIB_SWITCH(25313,true);
  2. Einen Fensterkontakt. Ist dieser offen, soll nicht geheizt werden, also
    EIB_SWITCH(25313,false);
  3. Einen Temperaturfühler. Abhängig von dem Ist Wert und einem vorgegebenen Soll Wert wird die Heizung ein oder ausgeschaltet

Ich schaffe es einfach nicht den Zustandswechsel des Fensterkontaktes, bzw. das Telgramm des Temperaturfühlers in die IPS zu bekommen. :confused:

Kann mir jemand einen Tipp geben?

Danke

Flos

P.S. Ich oute mich gleich mal als PHP Laie …

Hmm … ein paar mehr Infos wären schon hilfreich. Welche Variablen hast du angelegt, welche Scripte(Inhalt?) und wie sind die untereinander verknüpft?? :rolleyes:

Jens

Hallo Flos,

mal ganz einfach und weiter ausbaufähig…

$fenster = IPS_GetValueBoolean(ID-fensterkontakt);
$temp = IPS_GetValueFloat(ID-temperaturfühler);
$temp_an = 20; // Heizung einschalten bei °C
$temp_aus = 23; // Heizung ausschalten bei °C

if ($fenster){
EIB_SWITCH(25313,false);
}
else if ((!$fenster) && ($temp < $temp_an)){
EIB_SWITCH(25313,true);
}
else if ((!$fenster) && ($temp > $temp_aus)){
EIB_SWITCH(25313,false);
}

Die Schalthysterese müsste noch verfeinert werden, sonst würde die Heizung wenn 23°C erreicht sind abschalten und erst wieder bei unter 20°C einschalten. Ich habe jetzt einfach mal 3° K Unterschied genommen.
Für die Nacht ist ebenfalls noch die Absenktemperatur zu beachten, wobei man noch die Variable „Zeit“ mit ins Spiel bringen muss.
Ist auch nur ein ganz einfaches Beispiel für den Anfang zum probieren :wink:

Hallo nancilla,

wenn man in einer if-Abfrage den Zustand einer Boolean-Variable bereits ermittelt hat, dann ist es natürlich nicht mehr nötig im else-Zweig noch einmal das Gegenteil zu bestätigen. Schließlich wird der else-Zweig ja nur dann betreten, wenn das Gegenteil zutrifft.

Damit reduziert sich Dein einfaches Beispiel auf eines, das noch viel einfacher und damit verständlicher ist:

if ($fenster)
	EIB_SWITCH(25313,false);       // bei offenem Fenster immer ausschalten
else
	if ($temp < $temp_an)
		EIB_SWITCH(25313,true);    // bei Untertemperatur einschalten
    else
		EIB_SWITCH(25313,false);   // bei Übertemperatur ausschalten

Bei Deinem Skript handelt es sich übrigens um einen sogenannten „Zweipunkt-Regler“. Bei nicht all zu hohen Ansprüchen liefert er sogar zufriedenstellende Ergebnisse. Eine Temperatur-Hysterese von 3°C ist dafür aber zu hoch. Vermutlich sind 0.5°C in Ordnung.

Aber, wie Du selbst sagst, handelt es sich dabei ja nur um ein Beispiel. :wink:

Gruß
HJH

Hallo HJH,

da hast du natürlich Recht… war auch nur so zum Anfang schnell dahin „gepinselt“:wink:
Ich wusste aber, wenn einer (in dem Fall ich) den Anfang macht, dann bekommt der Flos reihenweise Antworten und alsbald ein funktionsfähiges Ergebnis.
Das ist hier immer so und auch das schöne an diesem Forum… die Diskussion muss sein und die Ideen gehen niemals aus:)
Ich bin nachwievor kein PHP-Profi und lerne durch Ideen, Google und php.net immer weiter dazu.
Am Anfang fragte ich mich, warum habe ich mir IPS angetan, heute möchte ich nichts Anderes mehr. Vor knapp 3 Jahren, wie ich damit anfing, wusste ich nur, dass PHP irgendetwas mit programmieren zutun hat und das haste ich ich. Hardware war meine eigentliche Spezifikation …

Guten Morgen zusammen und danke für die Hilfe.
Die Logik verstehe ich soweit und das Script funktioniert auch in dem Sinn, dass keine Fehler kommen. Wenn ich das Skript abändere so dass Temperatur_ist und Fensterkontakt reine Variablen sinn (also ohne Busanschluss) dann funktioniert auch das Ein-/Ausschalten der Heizung, soweit ich die Variablen richtig vorbesetzte.

<?

if (54511 /*[Testing\Fensterkontakt]*/)
   EIB_SWITCH(17480 /*[Testing\Fussbodenheizung]*/,false);       // bei     offenem Fenster immer ausschalten
 else
   if (27546 /*[Testing\Temp_Ist]*/ < 57558 /*[Testing\Temp_Soll]*/)
       EIB_SWITCH(17480 /*[Testing\Fussbodenheizung]*/,true);    // bei Untertemperatur einschalten
   else
       EIB_SWITCH(17480 /*[Testing\Fussbodenheizung]*/,false);   // bei Übertemperatur ausschalten
 ?>

Das eigentliche Problem tritt in Zeile 1) und 6) auf.
Wie stelle ich es an, das IPS mit Hilfe des Scripts den tatsächlichen Zustand des Fensterkontaktes ausliest (ID54511) bzw die Ist_Temperatur liest (ID57558)
Der Fensterkontakt ist momentan über Objekt hinzufügen, Instanz hinzufügen, EIB, EIBGroup, Funktion: Value eingebunden. Die passendere Funktion mit Boolean habe ich leider nicht gefunden.
Der Temperatursensor ist genauso eingebunden, aber mit der Funktion: FloatValue.
Obwohl ich auf dem EIB Bus die Telegramme mithilfe eines externen Busmonitors sehen kann, scheint es in der IPS nie anzukommen.
Die eigentliche Frage ist also: Wie binde ich EIB Sensoren (Wert bzw. Boolean) richtig in ein Script ein. Das habe ich bisher wohl völlig falsch verstanden

flos

Du prüfst ob die Zahl 27546 kleiner als 57558 ist. Die Antwort ist ja - genauso wie 12 kleiner ist als 13 und 14. Und solange wir die Mathematik nicht neu erfinden wird sich daran auch nichts ändern…

Schau dir die geposteten Beispiele, insbesondere das von nancilla, nochmal genau an. :wink:

Gruß,

Toni

Hallo Toni,
ja das Abprüfen beider Zahlen war natürlich Blödsinn.

Ursprünglich hatte ich das Script von nancilla einfach kopiert und angepasst (IDs mit Strg O eingesetzt):

<?

$fenster = IPS_GetValueBoolean(54511 /*[Testing\Fensterkontakt]*/);
$temp = IPS_GetValueFloat(12197 /*[Testing\Temperaturfühler]*/);
$temp_an = 20; // Heizung einschalten bei °C
$temp_aus = 23; // Heizung ausschalten bei °C

if ($fenster){
EIB_SWITCH(17480 /*[Testing\Fussbodenheizung]*/,false);
}
else if ((!$fenster) && ($temp < $temp_an)){
EIB_SWITCH(17480,true);
}
else if ((!$fenster) && ($temp > $temp_aus)){
EIB_SWITCH(17480,false);
}

?>

Die Funktion IPS_GetValueBoolean sieht genau nach dem aus was ich suche, also eine Funktion die mir über den Bus den Fensterkontaktstatus ausliest. Aber auch nach Anpassen der IDs bekam ich immer diese Fehlermeldung:

Fatal error: Call to undefined function IPS_GetValueBoolean() in [Testing 2] on line 3

Bei der Suche in der Dokumentation habe ich die Funktion dann auch nicht gefunden. Habe es dann mit GetValueBoolean und der Fensterkontaktvariablen unterhalb der Instanz versucht. aber die Variable wird nicht aktualisiert, sie behält den aktuellen Wert unabhängig vom Fensterzustand.

Ich scheitere zu aller erst an dem Versuch den Fensterkontaktstatus in der realen Welt zu ermitteln und die aktuelle Temperatur einzulesen.

Was mache ich in nancillas Script falsch, was habe ich vergessen?

flos

Jepp… Jetzt wo dus sagst… Die heisst auch getValueBoolean() und nicht IPS_GetValueBoolean()." Call to undefined function" - Solche Informationen sind wichtig… :smiley:

Toni

BTW: Benutz doch bite die PHP Tags wenn du Scriptschnipsel postetst. Die sind im Editor oben rechts… :wink:

deshalb hatte ich die Version 3 des Scripts:

<?

$fenster = GetValueBoolean(54511 /*[Testing\Fensterkontakt]*/);
$temp = GetValueFloat(12197 /*[Testing\Temperaturfühler]*/);
$temp_an = 20; // Heizung einschalten bei °C
$temp_aus = 23; // Heizung ausschalten bei °C

if ($fenster){
EIB_SWITCH(17480 /*[Testing\Fussbodenheizung]*/,false);
}
else if ((!$fenster) && ($temp < $temp_an)){
EIB_SWITCH(17480,true);
}
else if ((!$fenster) && ($temp > $temp_aus)){
EIB_SWITCH(17480,false);
}

?>

das ergab folgende Warnung:

Warning: Variable #54511 existiert nicht in C:\Programme\EIB_Tools\IP-Symcon\scripts\40763.ips.php on line 3

Warning: Variable #12197 existiert nicht in C:\Programme\EIB_Tools\IP-Symcon\scripts\40763.ips.php on line 4

Deshalb habe ich dann die Instanzen ID gegen die dazugörigen Variablen getauscht:

<?

$fenster = GetValueBoolean(41764 /*[Testing\Fensterkontakt\Value]*/);
$temp = GetValueFloat(26091 /*[Testing\Temperaturfühler\Value]*/);
$temp_an = 20; // Heizung einschalten bei °C
$temp_aus = 23; // Heizung ausschalten bei °C

if ($fenster){
EIB_SWITCH(17480 /*[Testing\Fussbodenheizung]*/,false);
}
else if ((!$fenster) && ($temp < $temp_an)){
EIB_SWITCH(17480,true);
}
else if ((!$fenster) && ($temp > $temp_aus)){
EIB_SWITCH(17480,false);
}

?>

Ergebnis:

Warning: Variablentyp Float entspricht nicht Boolean in [Testing 2] on line 3

Ist vermutlich deshalb, da die Variable als Value definiert ist und nicht als boolean; habe keinen Weg gefunden sie als boolean zu definieren.

Wenn ich nun den Teil $fenster = GetValue … durch $fenster = true; ersetze, und mich auf das auslesen der ist Temperatur focusiere, gibt es zwar keine Fehler und keine Warnung, aber der vom Temperaturfühler gesendete Wert kommt trotzdem nicht im Script an.

Ich bin ratlos: wie kann ich den Werts eines EIB Sensors in ein IPS bScript bekommen? Oder ist es einfach so, dass die IPS nur eine Einbahnstrasse zu den Aktoren realisiert (senden), aber das Auslesen der Bustelegramme (empfangen) gar nicht funktioniert? Aber dann wäre das ganze natürlich sinnlos.

flos

Was auch total richtig war. Denn die Instanz ist, wenn man so will, dein Fenster und was du wissen willst ist der Zustand des Fensters.

Was du oben geschrieben hast ist sinngemäß:

Wenn das Fenster [Fenster] ist.

Was du wissen wolltest ist:

Wenn das Fenster [offen oder geschlossen] ist.

Darum klappts jetzt.

Ja und genau das macht keinen Sinn. Boolen bedeutet Offen oder Geschlossen, An oder Aus, Wahr oder falsch - True oder false sagt der Programmierer. Deine Temperatur ist aber nicht Boolean (An oder Aus) sondern ein Float. Float ist eine Gleitkommazahl. Das bedeutet 22.6°C zum Beispiel. Auf jeden Fall aber eine Kommazahl (Float) und kein Boolean. Deine Warnung kommt also vollkommen zu Recht.

Hast du denn hier die ID deines Temperaturfühlers oder die der Variable in der die Temperatur steht verwendet?

Prüfe doch mal was drin steht. Neues Script:


$temp = GetValueFloat(26091 /*[Testing\Temperaturfühler\Value]*/);
echo "Temp ist:".$temp;

Dann siehst du ob die Temperatur im Script ankommt. Sie wird dir nämlich unten, wo sonst die Fehler stehen angezeigt.

Edit:

Nochwas… zum spielen setze $fenster mal nicht auf true sondern false. Sonst gehts nicht…

Toni

Hallo flos!

Du schreibst:

Der Fensterkontakt ist momentan über Objekt hinzufügen, Instanz hinzufügen, EIB, EIBGroup, Funktion: Value eingebunden. Die passendere Funktion mit Boolean habe ich leider nicht gefunden.

Du musst Switch bei Funktion des Fensterkontaktes auswählen.:wink:

Schönen Gruß
Egon

Toni,

danke für Dein Skript. Habs gleich mal probiert: Das Resultat:

Temp ist:0

Das deckt sich auch mit der Anzeige in der Objektbaumansicht.
Die Variable wird dort auch mit dem Wert 0 angezeigt, obwohl der Sensor gut 22 Grad meldet. Daraus schließe ich, das ich die Einbindung des Sensors nicht richtig gemacht habe. Die Einbindung habe ich wie folgt gemacht:

  1. Objekt hinzufügen -> Instanz hinzufügen -> Hersteller EIB -> Gerät EIB Group -> Name Temperaturfühler -> Adresse 2.5.4, Funktion FloatValue.
    Danach hat der Temperaturfühler die ID 12197 und die zugehörige Variable 26091
    Im Objektbaum wird unter Aktualisierung „Nie“ angezeigt. Tatsächlich sendet der Sensor zyklisch, bzw. bei gravierenden Änderungen auch sofort. (Über Busmonitor unter Adresse 2.5.4 überprüft

Ich bin davon ausgegangen, dass ich die Aktualisierung im Script anschieben muss. Aber da war ich wohl auf dem Holzweg. Aber wo triggre ich die Aktualisierung dann…

flos

Hallo flos!

Du kämpst ja.

Ich habe bei Funktion nur Value ausgewählt.
Den Button übernehmen haste ja gedrückt-odddr.:smiley:

Der Wert kommt ohne einen Trigger in IPS

Schünen Gruß
Egon

OK, danke an alle für die Hilfe.
Ich raff es bisher einfach nicht.
Da mir Egon jetzt noch die EIB relevanten Dinge genannt hat und mir auch bestätigt hat, dass es keinen Trigger braucht, fange ich jetzt noch mal komplett von vorne an.
Da auch das Testscript mit dem Mediaplayer bei mir nie gelaufen ist, scheint die Grundinstallation schief gelaufen zu sein.

Melde mich nach Neu-(Installation und Einrichtung) zurück.

Danke noch mal für Eure Mühe

flos

Sorry!!! … wie bin ich denn darauf gekommen!!!:rolleyes:

^^Habs ja auch nicht gemerkt :smiley:

Guten Morgen,
so es ist geschafft. Nach einer kompletten Neuinstallation, funktioniert das Skript. Die Aktoren werden wie gewünscht angesteuert, die Sensoren korrekt ausgelesen.
Vielen Dank für die Hilfe.
Bin sicher ich werde noch mehr Unterstützung brauchen.
Aber jetzt freue ich mich erst mal über den kleinen Erfolg!
flos