Hallo,
hier mal meine neueste Creation zum steuern und positioinieren von Jalousien (LCN only).
Eine genaue Beschreibung steht im Script.
Die Datei im Anhang beinhaltet noch 2 zusätzliche Scripte zum Inbetriebnehmen bzw löschen der beim testen angelegten Variablen, um den Einstieg zu erleichtern
Da es unabhängig vom Shutter Modul arbeitet, kann es auch zum testen oder auch dauerhaft parallel zum Shutter betrieben werden.
Gruß
Smudo
<?
/*
Anleitung
---------
Vorne weg auf jeden Fall erstmal: VERWENDUNG AUF EIGENE GEFAHR!! Regelmäßige Backups sind immer eine gute Idee!
Funktion;
1. Jalousien steuern und positionieren (einzelnd oder in Gruppen)
2. Optional: Software Endschalter
3. Optional: Bereitstellung von 2 Visualisierungsvariablen zur Weiterverarbeitung z.B. im Dashboard oder Webfront
Installation:
1. Script an beliebige Stelle im Objekbaum einfügen.
2. Daten für die Jalousien und die ID der LCNClient-Instanz und Art der Kopplung (PCHK oder LinHK) eintragen.
3. Script mit "ips_runscriptex (ScriptID,array("Jal_ID" => "initialisieren"));" in Betrieb nehmen. (ScriptID durch die tatsächliche ScriptID ersetzen.)
4. Warten bis alle Jalousien hochgefahren sind, fertig!
Funktionen im Detail:
Diese Script dient der Postionierung von Jalousien/Motoren unter Verwendung der LCN-Bus Modulinternen Relaistimer und
funktioniert deswegen natürlich auch nur mit einem LCN Bus-System und unterliegt auch dessen Einschränkungen.
Als da wären:
1. Maximale Laufzeit eines Motors = 240,97 Sekunden.
2. Je länger die Laufzeit, desto größer der Abstand der Anfahbaren Positionen. Ab ca. 30 Sek Laufzeit nur noch eine Auflösung von ca. 1 Sek.
Dies kann durch eine 2. Fahrt mit gleicher Postionsangabe wieder ausgeglichen werden.
3. Es können nur 2 Zielfahrten pro LCN Modul gleichzeitig laufen.
Es können trotzden alle gewünschten Zielfahrten beliebig an das Script übergeben werden, Sie werden zwischengespeichert und
der Reihe nach durchgeführt, sobald Relaistimer frei werden.
4. Ältere Module besitzen keine Relaistimer. Mit diesen Modulen funktioniert das Script dann leider nicht.
Manuelle Bedienung der Jalousien oder das Vorzeitige manuelle Abrechen einer Positionierung werden berücksichtigt, führen
aber zu einer Ungenauigkeit der folgenden Zielfahrten: Eine Fahrt auf einen der beiden Endschalter kalibriert das Ganze dann wieder neu.
Alle notwendigen Variablen (bis zu 6 pro Jalousie) und Ereignisse (1 Pro Jalousie unter dem Script)
werden automatisch angelegt und können auch wieder automatisch entfernt werden.
Als Daten für die Jalousien muss folgendes eingegeben werden:
Index 0: MotorrelaisstatusID: ID der Statusanzeige des Motorrelais
Index 1: RichtungsstatusID: ID der Statusanzeige des Richtungsrelais
Index 2: Laufzeit hoch: Laufzeit der Jalousie von unten nach oben (Bis zum Endschalter).
Index 3: Laufzeit runter: Laufzeit der Jalousie von oben nach unten (Bis zum Endschalter)
Index 4: Name: Ein frei wählbarer Name, mit dem die Jalousie später angesprochen werden kann.
Index 5: Gruppenname: Es können beliebig viele Gruppennamen hintereinander angegeben werden.
Index 6: Gruppenname
... ...
Meine Daten stehen als Beispiel noch drin und müssen natürlich ersetzt werden.
Die Laufzeiten für hoch und runter einfach nur gerade mit einer Uhr messen. Lieber eine Sekunde zu wenig als zu
viel verwenden.(Auch Dezimalzahlen möglich; Dezimalpunkt benutzen, kein Komma)
Jalousien gleicher Größe und gleicher Bauart haben normalerweise auch die gleiche Laufzeit, so daß dann nur ein
Fenster pro Bauart gemessen werden muss. Bei Abweichungen kann man immer noch mal nachmessen.
Gruppen:
Es können beliebig viele Gruppen angelegt werden. Jede Jalousie kann Mitglied beliebig vieler Gruppen gleichzeitg sein.
Eine Jalousie kann also z.B: Gleichzeitig in der Gruppe 'Süden', 'Zentral' und in der Gruppe 'Erdgeschoss' sein.
Eine Gruppe wird angelegt, indem man einfach einen frei wählbaren Gruppennamen im Array Jalousien hinter dem Namen der
Jalousie einträgt (immer in Anführungszeichen und mit Komma getrennt, Beispieldaten beachten).
Aufgerufen wird eine Gruppe indem man als $Jal_ID die Gruppe, angeführt mit 'Gruppe ' (Gruppe und ein Leeerzeichen) angibt.
Ein Beispiel steht unter Bedienung.
Optionen:
Endschalter:
1=AN, 0=Aus, Standard=0
Diese Option aktivert eien Software-Endschalter der, wie der Name schon sagt, den Motor nach erreichen der Endposition abschaltet. Sinnvoll
ist das Ganze, wenn der Zustand des Motors über ein Lämpchen oder eine Visualisierung angezeigt wird.
Bei dem Wert 0 ist die Funktion deaktiviert. Zahlen ab 1 geben die Sekunden an, die der Endschalter nach Erreichen der Endposition mit dem
Abschalten wartet, um eine sichere Offsetposition zu erreichen und somit die aktuelle Positionsvariable kalibriert. Sollte der Endschalter
bei eimem Wert von 3 noch zu früh abschalten, würde ich mal die Laufzeiten, die unter den Jalousiedaten angegeben sind überprüfen. Stimmt der
aktuelle Positionswert nicht mit der tatsächlichen Position überein (z.B. duch Fahrten, die gemacht wurden als IPS nicht lief), kann es sein,
das der Endschalter die manuelle Fahrt immer wieder abbricht. Da dann davon auszugehen ist, das die Werte der anderen Jalousien auch nicht
stimmen, würde ich empfehlen, das Script neu zu initialisieren. Dabei werden alle Jalousien neu kalibriert. Ansonsten Endschalter=0.
Endschalterdelay:
Standard=2, hat bei Ausgeschaltetem Endschalter keine Funktion.
Das Starten der Endschalterfunktion wird um diesen Wert (in Sekunden) verzögert, um bei gleichzeitigen Fahrten von vielen Jalousien
die Aktualisierung der Jalousiendaten abzuwarten. Dadurch wird nebenbei die Anzahl der Aufrufe dieses Scriptes verringert und mit einem Durchlauf
alle sich in Bewegung befindlichen Jalousien berücksichtigt.
Visuvariable:
0=Aus, 1=Positionsvariable, 2=Positionsvariable und Zustandsvariable. Standard=0
Visualisierungsvariablen geben einmal die aktuelle Position (0-100) und den aktuellen Zustand der Jalousie anhand von Integerwerten wieder.
Die Zustandvariable zeigt die Zustände "Jalousie steht"=0, "Jalousie fährt hoch"=1, "Jalousie fährt runter"=2 an. Integerwerte deshalb,
weil man sie am besten in einer Visu weiterverwenden kann.
Bedienung:
Einzelne Positionierung:
Positionierungsbefehl mit:
ips_runscriptex (ScriptID ,array("Jal_ID" => "Büro", "soll" => 60));
übergeben. (ScriptID durch die tatsächliche ScriptID ersetzen.)
fährt die Jalousie mit der Bezeichnung 'Büro' auf 60%.
Gruppe Positionieren:
Positionierungsbefehl mit:
ips_runscriptex (ScriptID ,array("Jal_ID" => "Gruppe Erdgeschoss", "soll" => 45));
übergeben. (ScriptID durch die tatsächliche ScriptID ersetzen.)
fährt alle Jalousien, die Mitglied der Gruppe 'Erdgeschoss' sind, auf 45%.
Steuerung ohne Positionierung:
ips_runscriptex (ScriptID ,array("Jal_ID" => "Gruppe Erdgeschoss", "soll" => "hoch"));
ips_runscriptex (ScriptID ,array("Jal_ID" => "Gruppe Erdgeschoss", "soll" => "runter"));
ips_runscriptex (ScriptID ,array("Jal_ID" => "Gruppe Erdgeschoss", "soll" => "stopp"));
ips_runscriptex (ScriptID ,array("Jal_ID" => "Büro", "soll" => "hoch"));
ips_runscriptex (ScriptID ,array("Jal_ID" => "Wohnzimmer", "soll" => "runter"));
ips_runscriptex (ScriptID ,array("Jal_ID" => "Markise", "soll" => "stopp"));
Alternativ kann die Jalousie auch mit der MotorstatusID anstelle des Namens angesprochen werden.
z.B. "ips_runscriptex (ScriptID,array("Jal_ID" => 58559, "soll" => 55)); (ScriptID durch die tatsächliche ScriptID ersetzen.)
Bei nichtgefallen:
1. Variablen und Ereignisse mit
ips_runscriptex (ScriptID,array("Jal_ID" => "löschen"));
entfernen. (ScriptID durch die tatsächliche ScriptID ersetzen.)
2. Script löschen.
3. Glücklich sein.
Sonstiges:
Die einfachste Art, dieses Script zu includen, ist glaube ich ein kleines Hilfsscript. Ich hab da mal was vorbereitet und ein entsprechendes Script beigelegt.
'JM3Funktion.php' includen und dann Jalousien mit z.B. 'jm3("Gruppe Süden",45);' steuern.
Jalousien, die über Ausgänge gesteuert werden, können mit 2 virtuellen Relais und 2 Logikschaltungen pro Jalousie in der LCN Programmierung betrieben werden.
Dies sollte natürlich eher die Ausnahme sein. Für Anlagen, bei denen die Jalousien hauptsächlich über Ausgänge laufen, ist diese Script dann eher suboptimal.
Mir ist durchaus bewusst, dass man dieses Script auch durch wildes hin und her drücken aus dem Tritt bringen kann, wenn man es unbedingt will
aber für die normale alltägliche Nutzung funktionert es bei mir bisher prima.
*/
//***************************************************************************************
//*****************Hier die LCN Client ID und die Jalousiedaten eingeben*****************
//return;
$LcnClient=35163; //ID für den LCN Client Socket
$kopplung="RLT"; //Kopplung LCN-PCHK = RLT / LinHK = RKT
$jalousien =array( //Motorstatus, Richtungsstatus, Laufzeit hoch, Laufzeit runter, Name, Gruppe1, Gruppe2, Gruppe3...
array(35556,41385,18,18,"Küche","Zentral","Ost-EG","EG","Wohnen"),
array(21767,40856,26,26,"Wohnzimmer","Zentral","EG","Wohnen"),
array(47713,54942,18,18,"Büro","Zentral","EG","Wohnen"),
array(53360,28234,18,18,"Toilette","Zentral","Ost-EG","EG","Wohnen"),
array(48237,17909,18,18,"Schlafzimmer","Zentral","Süd-OG","OG","Schlafen"),
array(46529,48501,18,18,"Ankleide","Zentral","Süd-OG","OG","Schlafen"),
array(43271,44947,18,18,"BadLinks","Zentral","Ost-OG","OG"),
array(19853,46470,18,18,"BadMitte","Zentral","Ost-OG","OG"),
array(12767,56715,18,18,"BadRechts","Zentral","Schlafen","Ost-OG","OG"),
array(30812,31458,18,18,"Gästezimmer","Zentral","OG","Wohnen"),
array(27191,39414,18,18,"Treppenhaus","Zentral","Schlafen","OG"),
array(27600,15357,27,27,"Markise")
);
$endschalter=2; //Verzögerung der automatischen Endabschaltung des Motorrelais in Sekunden, 0=Endschalter aus, 1-2 = Standard
$visuvariable=0; //VisuaisierungsVariable 0->aus / 1->Positionsvariable (int) / 2->Position und aktueller Zustand (Jalousie steht, läuft hoch oder läuft runter)
//**************Ab hier mit Änderungen dann eher vorsichtig sein***************************
//*****************************************************************************************
$endschalterdelay=2; //Verzögert den Start der Endschalter-Funkton um bei Gruppen- oder Zentralfahrten von vielen Jalousie die Aktualisierung der Variablen abzuwarten.
$pause=350; //Pause nach jedem Jalousiestart bzw. Stopp-Befehl. Bei Fahrten mit vielen Jalousien gleichzeitig kann es nötig sein, diesen Wert (Millisekunden)zu erhöhen.
$debug=0; // Debugmodus 1 --> an, 0 --> aus, Standard --> 0
if($IPS_SENDER == "Variable") { //Laufzeiten erfassen (Automatische und manuelle Fahrten)
if ($debug){echo "
******Auslösende Variable= ".$IPS_VARIABLE."
";}
$jal=JMGetJalousieData($IPS_VARIABLE, $jalousien);
$startid=JMCreateVariableByName($jalousien[$jal][0], "JM3 Motorstart", 2);
$possollid=JMCreateVariableByName($jalousien[$jal][0], "JM3 Soll Position", 2);
$posstatid=JMCreateVariableByName($jalousien[$jal][0], "JM3 Positionierung läuft", 0);
$posstat=GetValueBoolean($posstatid);
$motor=GetValue($jalousien[$jal][0]);
if ($motor==true){ //Jalousiemotor an
$mtf=microtime($get_as_float=1);
SetValue($startid,$mtf);
if ($visuvariable==2){
$motorID=IPS_GetParent((int)($jalousien[$jal][0]));
$richtung = GetValueBoolean($jalousien[$jal][1]) ? 2 : 1;
$laufvar=JMCreateVariableByName($motorID, "JM3 Stopp-0 hoch-1 runter-2", 1);
SetValue($laufvar,$richtung);
}
if (($endschalter!=0)&&($posstat==false)){
IPS_SetScriptTimer($IPS_SELF, $endschalterdelay);
}
return;
}
else if ($motor==false){ //Jalousiemotor aus
$mtf=microtime($get_as_float=1);
$start=GetValue($startid);
$laufzeit=$mtf-$start; //Dauer der letzten Fahrt ermitteln
if ($debug){echo "******Gemessene Laufzeit beträgt= ".$laufzeit." Sekunden
";}
$richtung = GetValueBoolean($jalousien[$jal][1]) ? "runter" : "hoch";
$laufzeitmax = GetValueBoolean($jalousien[$jal][1]) ? $jalousien[$jal][3]:$jalousien[$jal][2];
$faktor=100/$laufzeitmax;
$posid=JMCreateVariableByName(($jalousien[$jal][0]), "JM3 Aktuelle Position", 2);
$position_ist = GetValue($posid);
if ($debug){echo "******Ausgelesene Ist-Pos ist: ".$position_ist."
";}
if ($visuvariable==2){
$motorID=IPS_GetParent((int)($jalousien[$jal][0]));
$laufvar=JMCreateVariableByName($motorID, "JM3 Stopp-0 hoch-1 runter-2", 1);
SetValue($laufvar,0);
}
else{
$motorID=IPS_GetParent((int)($jalousien[$jal][0]));
$laufvar=JMCreateVariableByName($motorID, "JM3 Stopp-0 hoch-1 runter-2", 1);
if ($laufvar!=""){
IPS_DeleteVariable($laufvar);
}
}
if ($richtung=="runter"){ //Neue Ist-Position ermitteln
$posneu=($position_ist-($laufzeit*$faktor));
if ($debug){echo "******Variable Laufzeit: ".$laufzeit." Variable Faktor: ".$faktor."
";}
if ($posneu<=0){$posneu=0;} //Endschalter Offset
}
else {
$posneu=($position_ist+($laufzeit*$faktor));
if ($posneu>=100) {$posneu=100;} //Endschalter Offset
}
$possollcalc=GetValue($possollid);
$solldiff=$posneu-$possollcalc; if ($solldiff<0){$solldiff=$solldiff*-1;}
if ($debug){echo "******Neue gemessene Ist-Pos ist: ".$posneu."
";}
if ($debug){echo "******Neue berechnete Ist-Pos ist: ".$possollcalc."
";}
if ($debug){echo "******Die Differenz ist: ".$solldiff."
";}
if ($posstat){ //Wenn Positionierung läuft, berechneten neuen Ist Wert mit gemessenem vergleichen und entsprechend übernehmen
if ($solldiff<=4){ //
$posneu=$possollcalc;
if ($debug){echo "******Berechneter Wert wird für neue Position übernommen.
";}
}
}
else {
if ($debug){echo "******Keine Positionierung(bzw manueller Eingriff vermutet), gemessener Wert wird für neue Position übernommen.
";}
}
if ($visuvariable>=1){
$motorID=IPS_GetParent((int)($jalousien[$jal][0]));
$position=(int)$posneu;
$posist=JMCreateVariableByName($motorID, "JM3 Position", 1);
SetValue($posist,$position);
}
else{
$motorID=IPS_GetParent((int)($jalousien[$jal][0]));
$posist=JMCreateVariableByName($motorID, "JM3 Position", 1);
if ($posist!=""){
IPS_DeleteVariable($posist);
}
}
SetValue($posid,$posneu);
SetValue($posstatid,false);
}
}
if($IPS_SENDER == "TimerEvent"){ //Software-Endschalter
if ($debug){echo "******Endschalter start.
";}
IPS_SetScriptTimer($IPS_SELF, 0);
$timer=241;
$alle = count($jalousien);$e=0;
while ($e < $alle) {
$motorID=IPS_GetParent((int)($jalousien[$e][0]));
$posstatid=JMCreateVariableByName($jalousien[$e][0], "JM3 Positionierung läuft", 0);
$motor=GetValueBoolean($jalousien[$e][0]);
$posstat=GetValueBoolean($posstatid);
if (($posstat==false)&&($motor==true)){
$mtf=microtime($get_as_float=1);
//$richtungID=IPS_GetParent((int)($jalousien[$e][1]));
$startid=JMCreateVariableByName($jalousien[$e][0], "JM3 Motorstart", 2);
$posid=JMCreateVariableByName(($jalousien[$e][0]), "JM3 Aktuelle Position", 2);
$lzhoch = $jalousien[$e][2]; $lzrunter = $jalousien[$e][3];
$richtung=GetValueBoolean($jalousien[$e][1]);
$start=GetValue($startid);
$position_ist = GetValue($posid);
$laufzeitmax = GetValueBoolean($jalousien[$e][1]) ? $jalousien[$e][3]:$jalousien[$e][2];
$laufzeit=$mtf-$start;
$faktor=100/$laufzeitmax;
if ($debug){echo "******Endschalter: Jalousie ".$jalousien[$e][4]." wird auf Endschaltung überprüft.
";}
if ($richtung){ //Aktuelle Ist-Position ermitteln
$posneu=($position_ist-($laufzeit*$faktor));
if ($debug){echo "******Endschalter: Jalousie ".$jalousien[$e][4]." ist aktuell auf Position ".$posneu.".
";}
if ($posneu<=(0-$endschalter)){
LCN_SwitchRelay($motorID, false);
IPS_SLEEP($pause); // Am Ende von Zentralfahrten könnte anosnsten ein kleiner Befehls-Stau entstehen
if ($debug){echo "******Endschalter: Jalousiemotor ".$jalousien[$e][4]." wird ausgeschaltet.
";}
}
else{
$timerneu = $position_ist*($lzrunter/100)-$laufzeit+$endschalter;
If ($timerneu<=$timer){
$timer=$timerneu;
if ($debug){echo "******Endschalter: Jalousie ".$jalousien[$e][4]." muss noch ".$timer." Sekunden laufen.
";}
}
}
}
else {
$posneu=($position_ist+($laufzeit*$faktor));
if ($debug){echo "******Endschalter: Jalousie ".$jalousien[$e][4]." ist aktuell auf Position ".$posneu.".
";}
if ($posneu>=(100+$endschalter)){
LCN_SwitchRelay($motorID, false);
IPS_SLEEP($pause); // Am Ende von Zentralfahrten könnte anosnsten ein kleiner Befehls-Stau entstehen
if ($debug){echo "******Endschalter: Jalousiemotor ".$jalousien[$e][4]." wird ausgeschaltet.
";}
}
else{
$timerneu = (100-$position_ist)*($lzhoch/100)-$laufzeit+$endschalter;
If ($timerneu<=$timer){
$timer=$timerneu;
if ($debug){echo "******Endschalter: Jalousie ".$jalousien[$e][4]." muss noch ".$timer." Sekunden laufen.
";}
}
}
}
}
$e++;
}
if ($timer==241){
IPS_SetScriptTimer($IPS_SELF, 0);
if ($debug){echo "******Endschalter: Scripttimer wird deaktiviert.
";}
}
else{
$settimer=(int)$timer+1;
IPS_SetScriptTimer($IPS_SELF, $settimer);
if ($debug){echo "******Endschalter: Scripttimer wird auf ".$settimer." gesetzt.
";}
}
return;
}
if (!isset($Jal_ID)){$Jal_ID="";}
if ($Jal_ID=="initialisieren"){ // Erstellt Variablen und nimmt einen Offset der Jalousien vor.
$count = count($jalousien);$jal=0;
while ($jal < $count) {
$motorID=IPS_GetParent((int)($jalousien[$jal][0]));
$richtungID=IPS_GetParent((int)($jalousien[$jal][1]));
if ($jalousien[$jal][0]==""){exit ("Keine Jalousie ID, vermutlich Fehler im Array für die Jalousiedaten am Anfang des Scriptes!
");}
$posid=JMCreateVariableByName(($jalousien[$jal][0]), "JM3 Aktuelle Position", 2);
JMCreateEventIDByName($jalousien[$jal][0]);
SetValue($posid,0);
LCN_SwitchRelay($richtungID, false);
LCN_SwitchRelay($motorID, true);
$jal++;
}
return;
}
if ($Jal_ID=="löschen"){ // Löscht alle automatisch angelegten Variablen und Eereignisse zu diesem Script anhand des Arrays $Jalousien
$debug=1;
$stid = IPS_GetEventIDByName("ScriptTimer", $IPS_SELF);
if ($stip!=""){
if ($debug){echo "******Lösche ScriptTimer (".$stid.")
";}
IPS_DeleteEvent($stid);
}
$jmwsid=JMCreateVariableByName($IPS_SELF, "JM3 Warteschlange", 3);
if ($debug){echo "******Lösche Variable JM3 Warteschlange (".$jmwsid.")
";}
IPS_DeleteVariable($jmwsid);
$count = count($jalousien);$jal=0;
while ($jal < $count) {
$posid=JMCreateVariableByName($jalousien[$jal][0], "JM3 Aktuelle Position", 2);
$startid=JMCreateVariableByName($jalousien[$jal][0], "JM3 Motorstart", 2);
$possollid=JMCreateVariableByName($jalousien[$jal][0], "JM3 Soll Position", 2);
$posstatid=JMCreateVariableByName($jalousien[$jal][0], "JM3 Positionierung läuft", 0);
$laufvar=JMCreateVariableByName($jalousien[$jal][0], "Stopp-0 hoch-1 runter-2", 1);
$motorID=IPS_GetParent((int)($jalousien[$jal][0]));
$posist=JMCreateVariableByName($motorID, "JM3 Position", 1);
if ($posist!=""){
if ($debug){echo "******Lösche Variable KM3 Position (".$posist.")
";}
IPS_DeleteVariable($posist);
}
if ($debug){echo "******Lösche Variable JM3 Aktuelle Position (".$posid.")
";}
IPS_DeleteVariable($posid);
if ($debug){echo "******Lösche Variable JM3 Motorstart (".$startid.")
";}
IPS_DeleteVariable($startid);
if ($debug){echo "******Lösche Variable JM3 Soll Position (".$possollid.")
";}
IPS_DeleteVariable($possollid);
if ($debug){echo "******Lösche Variable JM3 Positionierung läuft (".$posstatid.")
";}
IPS_DeleteVariable($posstatid);
if ($laufvar!=""){
if ($debug){echo "******Lösche Variable Stopp-0 hoch-1 runter-2 (".$laufvar.")
";}
IPS_DeleteVariable($laufvar);
}
$eid = @IPS_GetEventIDByName($jalousien[$jal][0], $IPS_SELF);
if ($debug){echo "******Lösche auslösendes Ereignis (".$eid.")
";}
IPS_DeleteEvent($eid);
$jal++;
}
return;
}
if (isset($soll)){ // Befehl für eine Jalousiefahrt oder Positionierung wurde an dieses Script übergeben
$grp= substr($Jal_ID,0,7);// Befehl für Gruppensteuerung herausfiltern
if ($grp=="Gruppe "){
$gruppe=substr($Jal_ID,7);
$posadda=array();
$zeile = count($jalousien);$jal=0;
while ($jal < $zeile) {//Festellen, welche Jalousien in der gewünschten Gruppe sind
$ele = count($jalousien[$jal]);$i=5;
while ($i<$ele){
if ($jalousien[$jal][$i] == $gruppe) {
$posadd=$jalousien[$jal][0].",".$soll;
array_push($posadda,$posadd);
}
$i++;
}
$jal++;
}
if ($debug){echo "******Folgende Jalousien gehören zur Gruppe ".$gruppe." und werden der Warteschlange hinzugefügt
";}
if ($debug){print_r ($posadda);}
}
if (!is_numeric($soll)){
if (IPS_SemaphoreEnter("JM3G", 2000)){
if (isset($posadda)){ //Grundbefehle hoch, runter, stopp für Gruppen ausführen
if ($soll=="hoch"){
$rel="10";
}
if ($soll=="runter"){
$rel="11";
}
if ($soll=="stopp"){
$rel="0-";
}
$counta = count($posadda);
while (0 < $counta) {
$motorID=IPS_GetParent((int)($posadda[0]));
$modulinst = IPS_GetInstanceParentID($motorID);$modul1 = LCN_GetTarget($modulinst);
$relaisint=LCN_GetChannel($motorID);
$relais=substr_replace('--------',$rel,$relaisint-1,2);
$j=1;
while ($j < $counta) { // Jalousien der Gruppe zusammenfassen, die an einem Modul angeschlossen sind
$motorID=IPS_GetParent((int)($posadda[$j]));
$modulinst = IPS_GetInstanceParentID($motorID);$modul = LCN_GetTarget($modulinst);
if ($modul == $modul1) {
$relaisint=LCN_GetChannel($motorID);
$relais=substr_replace($relais,$rel,$relaisint-1,2);
array_splice ($posadda,$j,1);
$j--;
}
$j++;
$counta = count($posadda);
}
$modulpck=sprintf("%03d", $modul1);
$pck=">M000".$modulpck.".RL".$relais.chr(10); // Alle Jalousien der Gruppe und eines Moduls mit einem einzelnen LCN Befehl gleichzeitig ansteuern (nur 1 Befehl für bis zu 8 Relais)
CSCK_SendText($LcnClient,$pck);
IPS_SLEEP($pause);
if ($debug){echo "******PCK Befehl für die Gruppensteuerung Grundbefehle= ".$pck."
";}
array_splice ($posadda,0,1);
$counta = count($posadda);
}
IPS_SemaphoreLeave("JM3G");
return;
}
$jal=JMGetJalousieData($Jal_ID, $jalousien); //Index aus dem Array $jalousien der betreffenden Jalousie feststellen
$motorID=IPS_GetParent((int)($jalousien[$jal][0]));
$richtungID=IPS_GetParent((int)($jalousien[$jal][1]));
if ($soll=="hoch"){
LCN_SwitchRelay($richtungID, false);
LCN_SwitchRelay($motorID, true);
return;
}
if ($soll=="runter"){
LCN_SwitchRelay($richtungID, true);
LCN_SwitchRelay($motorID, true);
return;
}
if ($soll=="stopp"){
LCN_SwitchRelay($motorID, false);
return;
}
IPS_SLEEP($pause);
IPS_SemaphoreLeave("JM3G");
}
}
if ($grp!="Gruppe "){
$jal=JMGetJalousieData($Jal_ID, $jalousien);
$posadd=$jalousien[$jal][0].",".$soll;
$posadda=array($posadd);
}
}
if (IPS_SemaphoreEnter("JM3", 3000)){ // Du kümmst hier net rein!
if (isset($posadda)){ // Falls ein neuer Positionierungsbefehl vorhanden, diesen in die Warteschlange schreiben,
$warteschlange=JM3warteschlange("set",$posadda);
if ($debug){echo "******Der Warteschlange wurde= ".$posadd." hinzugefügt.
";}
}
else {$warteschlange=JM3warteschlange("get",""); // ansonsten Scriptaufruf durch Motorvariable, Warteschlange auslesen um sie auf weitere Abarbeitungsmöglichkeiten zu überprüfen
if ($debug){echo "******Warteschlange eingelesen.
";}
}
$countw = count($warteschlange);
if ($countw!=0){
if ($debug){echo "******Die Warteschlange hat= ".$countw." Einträge.
";}
if ($debug){print_r ($warteschlange);}
$i=0;
while ($i < $countw) { //die einzelnen Punkte der Warteschlange durhgehen
$data=explode(",",$warteschlange[$i]);
$id=$data[0];$value=$data[1];
if ($debug){echo "******Jalousie= ".$id." Sollwert= ".$value."
";}
$jal=JMGetJalousieData($id, $jalousien);
if ($jalousien[$jal][4]==""){exit;}
$motorID=IPS_GetParent((int)($jalousien[$jal][0]));
$richtungID=IPS_GetParent((int)($jalousien[$jal][1]));
$modulinst = IPS_GetInstanceParentID($motorID);$modulint = LCN_GetTarget($modulinst);$modul=sprintf("%03d", $modulint);
if ($debug){echo "******Ziel-Jalousie läuft über Modul ".$modul."
";}
$countj = count($jalousien);$j=0;
$poscount=0;
while ($j < $countj) { // Überprüfen, wie viele Relaistimer pro Modul laufen (Max 2 möglich)
$motorIDj=IPS_GetParent((int)($jalousien[$j][0]));
if ($jalousien[$j][4]==""){exit;}
$modulinstj = IPS_GetInstanceParentID($motorIDj);$modulintj = LCN_GetTarget($modulinstj);$modulj=sprintf("%03d", $modulintj);
if ($modulj == $modul) {
$posstatid=JMCreateVariableByName($jalousien[$j][0], "JM3 Positionierung läuft", 0);
$posstat= GetValue($posstatid);
if ($posstat){
if ($debug){echo "******Positionierung der Jalousie ".$jalousien[$j][4]." ist aktiv!!
";}
$poscount++;
}
else {if ($debug){echo "******Positionierung der Jalousie ".$jalousien[$j][4]." ist nicht aktiv.
";}}
}
$j++;
}
if ($poscount<=1){ //Ein Relaistimer ist frei, die Positionierung kann durchgeführt werden
if ($debug){echo "******Relaistimer frei: ".(2-$poscount).".
******Positionierung für Jalousie ".$jalousien[$jal][4]." wird gestartet.
";}
$motorstatus=GetValue($jalousien[$jal][0]);
if ($motorstatus){ //Motor läuft bereits, Motor wird gestoppt, Befehl bleibt in der Warteschlange
LCN_SwitchRelay($motorID, false);
}
else{ //Richtung und Laufzeit festlegen und Relaistimer an Modul senden
$relaisint=LCN_GetChannel($motorID); $relais=substr_replace('00000000','1',$relaisint-1,1);
$posid=JMCreateVariableByName(($jalousien[$jal][0]), "JM3 Aktuelle Position", 2);$position_ist = GetValue($posid);
$possollid=JMCreateVariableByName(($jalousien[$jal][0]), "JM3 Soll Position", 2);
$posstatid=JMCreateVariableByName($jalousien[$jal][0], "JM3 Positionierung läuft", 0);
$lzhoch = $jalousien[$jal][2]; $lzrunter = $jalousien[$jal][3];
$laufzeitmax = GetValueBoolean($jalousien[$jal][1]) ? $jalousien[$jal][3]:$jalousien[$jal][2];
$faktor=100/$laufzeitmax;
$LCNRTint=0;
if ($value > $position_ist){ // Bestimmung der Laufrichtung und Laufzeit (hoch)
LCN_SwitchRelay($richtungID, false);
$dauer = (($value-$position_ist)*($lzhoch/100));
$LCNRTint=GetLCNRT($dauer); $LCNRT=sprintf("%03d", $LCNRTint);
$LCNtime=GetLCNtime($LCNRT);
SetValue($possollid,($position_ist+$LCNtime*$faktor));
}
if ($value < $position_ist){ // Bestimmung der Laufrichtung und Laufzeit (runter)
LCN_SwitchRelay($richtungID, true);
$dauer = (($position_ist-$value)*($lzrunter/100));
$LCNRTint=GetLCNRT($dauer); $LCNRT=sprintf("%03d", $LCNRTint);
$LCNtime=GetLCNtime($LCNRT);
SetValue($possollid,($position_ist-$LCNtime*$faktor));
}
if ($LCNRTint <= 7){ // Überprüfung der Schaltzeit des Relais.
if ($debug){echo "******Wir wollen es mal nicht übertreiben, da klappert höchstens mal kurz das Relais.
";}
$LCNRT="0"; $LCNtime=0;
}
if ($debug){echo "******LCN Relaistimer = ".$LCNRT.". Das entspricht ".$LCNtime." Sekunden.
";}
if ($LCNRT=="0"){ // Jalousie passt scho
if ($debug){echo "******Positionierung nicht sinnvoll. Eintrag ".$i." (".$warteschlange[$i].") wird gelöscht.
";}
$warteschlange=JM3warteschlange("unset","$i");
$i--;
}
else { //Endlich setzt sich die olle Rollade mal in Bewegung.
SetValue($posstatid,true);
$pck=">M000".$modul.".".$kopplung.$LCNRT.$relais.chr(10);
CSCK_SendText($LcnClient,$pck);
IPS_SLEEP($pause);
if ($debug){echo "******PCK Befehl= ".$pck;}
if ($debug){echo "******Positionierung wurde eingeleitet. Eintrag ".$i." (".$warteschlange[$i].") wird gelöscht.
";}
$warteschlange=JM3warteschlange("unset","$i");
$i--;
}
}
}
else { //Modul mit 2 Relaistimern belegt, nächste Positionierung aus Warteschlange vornehmen
if ($debug==1){echo "******In diesem Modul laufen bereits ".$poscount." Relaistimer. Der Befehl bleibt in der Warteschlange
";}
}
$countw = count($warteschlange);
$i++;
}
}
else{ //Warteschlange ist leer
if ($debug){echo "******Die Warteschlange ist leer. Endlich! Mann, ist das ein Stress hier. Hast du keine Playstation, mit der du Spielen kannst?
";}
}
if (isset($IPS_SENDER)){
if($IPS_SENDER == "Execute") {
echo "
****** Übrigens macht es nicht viel Sinn, dieses Script über den 'Ausführen' Button zu starten,
****** aber wenn es dir Spass macht, drück ruhig noch ein paar mal drauf.
";
}
}
IPS_SemaphoreLeave("JM3"); //so, jetzt dürfen auch mal die anderen wieder ran.
}
else {
if ($debug){echo "******Script an dieser Stelle wegen Semaphore abgebrochen. Finger in Po, Mexico? Nein, es geht weiter.
";}
ips_runscriptex ($IPS_SELF ,array("Jal_ID" => $Jal_ID, "soll" => $soll));
return;
}
function JM3Warteschlange($WSorder, $WSvalue){ //Warteschlange abfragen oder Einträge hinzufügen oder löschen. $order = get, set, unset; $Value = Array
global $IPS_SELF;
$jmwsid=JMCreateVariableByName($IPS_SELF, "JM3 Warteschlange", 3);
$warteschlange = array();
$warteschlange = unserialize(GetValue($jmwsid));
if (!is_array($warteschlange)) {
$warteschlange = array();
}
$countws = count($WSvalue);$k=0;
while ($k < $countws) {
if ($WSorder=="get"){
return($warteschlange);
}
if ($WSorder=="set"){
array_push($warteschlange,$WSvalue[$k]);
}
if ($WSorder=="unset"){
array_splice ($warteschlange,$WSvalue[$k],1);
}
$k++;
}
SetValue($jmwsid,serialize($warteschlange));
return($warteschlange);
}
function GetLCNRT($time){ //Leider ist mir keine gescheite Formel hierfür eingefallen. Man kann ruhig blöd sein, man muss sich nur zu helfen wissen :)
if ($time<=0.97){
$LCNRTint= (int)($time/0.03);
return $LCNRTint;
}
if ($time<=2.89){
$LCNRTint=(int)(($time-0.96)/0.06+32);
return $LCNRTint;
}
if ($time<=6.73){
$LCNRTint=(int)(($time-2.88)/0.12+64);
return $LCNRTint;
}
if ($time<=14.41){
$LCNRTint=(int)(($time-6.72)/0.24+96);
return $LCNRTint;
}
if ($time<=29.77){
$LCNRTint=(int)(($time-14.4)/0.48+128);
return $LCNRTint;
}
if ($time<=60.49){
$LCNRTint=(int)(($time-29.76)/0.96+160)
;return $LCNRTint;
}
if ($time<=121.93){
$LCNRTint=(int)(($time-60.48)/1.92+192);
return $LCNRTint;
}
if ($time<=240.97){
$LCNRTint=(int)(($time-121.92)/3.84+224);
return $LCNRTint;
}
else {
echo "*** Fehler: Laufzeiten über 240,96 Sek können nicht verarbeitet werden ***";
exit;
}
}
function GetLCNtime($LCNRT){ //und nochmal Halli Galli rückwärts, immer noch ohne gescheite Formel
if ($LCNRT<=32){
$LCNtime= $LCNRT*0.03;
return $LCNtime;
}
if ($LCNRT<=64){
$LCNtime=($LCNRT-32)*0.06+0.96;
return $LCNtime;
}
if ($LCNRT<=96){
$LCNtime=($LCNRT-64)*0.12+2.88;
return $LCNtime;
}
if ($LCNRT<=128){
$LCNtime=($LCNRT-96)*0.24+6.72;
return $LCNtime;
}
if ($LCNRT<=160){
$LCNtime=($LCNRT-128)*0.48+14.4;
return $LCNtime;
}
if ($LCNRT<=192){
$LCNtime=($LCNRT-160)*0.96+29.76;
return $LCNtime;
}
if ($LCNRT<=224){
$LCNtime=($LCNRT-192)*1.92+60.48;
return $LCNtime;
}
if ($LCNRT<=255){
$LCNtime=($LCNRT-224)*3.84+121.92;
return $LCNtime;
}
else {
echo "*** Fehler: Relaistimer über 255 sind nicht möglich ***";
exit;
}
}
function JMCreateVariableByName($id, $name, $type) { //Variablen auslesen bzw. erstellen
global $IPS_SELF;
$vid = @IPS_GetVariableIDByName($name, $id);
if($vid===false) {
$vid = IPS_CreateVariable($type);
IPS_SetParent($vid, $id);
IPS_SetName($vid, $name);
IPS_SetInfo($vid, "Variable vom Jalousiemaster 3.0");
}
return $vid;
}
function JMCreateEventIDByName($id) { //Ereignisse auslesen bzw. erstellen
global $IPS_SELF;
$eid = @IPS_GetEventIDByName($id, $IPS_SELF);
if($eid===false) {
$eid = IPS_CreateEvent(0);
IPS_SetEventTrigger($eid, 1, $id);
IPS_SetParent($eid, $IPS_SELF);
IPS_SetName($eid, $id);
IPS_SetEventActive($eid, true);
}
return $eid;
}
function JMGetJalousieData($id, $jalousien) { //Index für abgefragte Jalousie ermitteln
$count = count($jalousien);$jal=0;
while ($jal < $count) {
if (($jalousien[$jal][0] == $id)or($jalousien[$jal][4] == $id)) {
break;
}$jal++;
}
if (($jalousien[$jal][0]!=$id)and($jalousien[$jal][4]!=$id)) {
exit ("Jalousie nicht gefunden
");
}
return $jal;
}
?>
jm3.zip (10.4 KB)