Alternative zum ShutterControl für LCN User

Achtung: Funktioniert nicht mehr ab IPS Version 2.1.

Hallo zusammen,

da das Shuttercontrol Modul für LCN an der ein oder anderen Stelle noch ein wenig hinkt, habe ich mal ein alternatives Script dazu gemacht. Wer Interesse hat, kann es sich ja mal anschauen bzw ausprobieren.

Jalousiemaster

Dieses Script dient zur Positionserfassung, Endabschaltungund Positioinierung von Relaisgesteurten Jalousien am LCN Bus.
Es erfasst jede Bewegung einer Jalousie. Der aktuelle IST-Wert kann im Objektbaum abgefragt und z.B.
für eine Visualisierung oder sonstige Zwecke verwendet werden. Zusätzlich wird das Motorrelais nach Erreichen der
Endposition abgeschaltet und somit ein Eventuell vorhandenes Kontrollämpchen ebenfalls. Eine Positionierung
einzelner Jalousien ist ebenfalls möglich. Die Positionierung ist nich zu 100% genau, sollte aber für die
meisten Zwecke absolut ausreichen. Manuelle Steuerung über Taster in den Zimmern oder andere Scripte werden
berücksichtigt und beeinflussen die Positionserfassung dieses Scriptes nicht.


Anleitung zur Installation:

  1. Das Script kann an bliebiger Stelle im Objektbaum angelegt werden. Es ist nur ein Script für alle Jalousien notwendig.
  2. Daten der zu steuernden Jalousien im Skript sorgfältig eintragen.
  3. Alle MotorStatus-ID´s (nicht die Jalousien ID´s) der zu steuernden Jalousien als Ereignis „Variablenänderung“ zum Script hinzufügen.
  4. Das Scipt mit „ips_runscriptex (SciptID ,array(„Jal_ID“ => 0,„Soll“ => „reset“));“ initialisieren.

Die ScriptID muss natürlich mit der tatsächlichen ID ersetzen, welche man im Objektbaum ablesen kann.
Alle Jalousien fahren dabei hoch.


Positionierung:

Positionen gezielt anfahren kann man mit z.B.:
ips_runscriptex (SciptID ,array(„Jal_ID“ => 31238,„Soll“ => „65“));
oder in der neuen kann auch der Name der JAlousie verwendet werden, also z.B.
ips_runscriptex (35325 ,array(„Jal_ID“ => Schlafzimmer, „Soll“ => 45));

Die Jal_ID ist wieder die Motorstatusrelais ID, die auch an der ersten Stelle in der Jalousien.cfg Datei steht. Nicht die Jalousien ID!
Die ScriptID muss natürlich wieder duch die richtige ID des Scriptes ersetzt werden.
Das Beispiel: ips_runscriptex (14526 ,array(„Jal_ID“ => 31238,„Soll“ => „65“));
würde also die Jalousie „WohnzimmerSüd“ auf halbe Höhe fahren.
Der Sollwert wird in % angegeben. Bei 50% hält die Jalousie nicht auf der halben höhe
da beim Auffahren ein gewisser Leerlauf und das Öffnen der Schlitze abgezogen werden muss.
Eine halb geöffnete Jalousie erreicht man bei ca. 65%. Jalousiefahrten kleiner
als 5% können nicht genau gefahren werden. Die Genauigkeit der Positionierung lässt nach, je häufiger
man die Position wechselt ohne auf einen Endschalter zu fahren. Ein Fahren auf einen
Endschalter nach oben oder unten kalibriert die Positionierung neu.

Änderungen in der neuen Version:
Die Jalousiedaten sind wieder in das Skript gewandert und nicht mehr in einer eigenen Datei.
Die interne Erkennung ob es sich um einen manuelle Bewegung oder eine Positionierung handelt, wurde vorher über Timings gemacht. Da es dabei aber bei höherer Buslast mit dem Timing nicht mehr klappte und es zu Fehlern kam, habe ich dazu einen zusätzliche Variable eingebaut.
Zur Positionierung kann jetzt auch anstelle der MotorstatusID auch der im Array angegebene Jalousiename verwendet werden.

Ich empfehle bei gleichzeitiger Positionierung mehrerer Jalousien, diese in einem Zeitlichen Abstand von 1-2 Sekunden anlaufen zu lassen, um die Genauigkeit zu erhöhen.
Ich weiss, dass das Skript einige Stellen aufweist, die übel um die Ecke programmiert sind aber das erst mal so weit dabei rausgekommen. Ich werde mich bei Gelegenheit nochmal dransetzen das ganze überarbeiten. Ich hoffe auch die Genauigkeit noch verbessern zu können. Hilfe von geübten Skriptern nehme ich dazu gerne an.:slight_smile: Aber vorerst erfüllt es seinen Zweck bei mir zu meiner Zufriedenheit.

<?php
//Motorstatus, Richtungsstatus, Laufzeit hoch, Laufzeit runter, Name
$jalousien =array( 
	array(58559 /*[Büro\.Jalousie Büro\Status]*/,16290,18,18,"Büro"),
	array(25413 /*[Toilette\.Jalousie Toilette\Status]*/,24630,18,18,"Toilette"),
	array(31238 /*[Badezimmer\.Jalousie Badezimmer links\Status]*/,15509,18,18,"BadLinks"),
	array(29206 /*[Badezimmer\.Jalousie Badezimmer mitte\Status]*/,39645,18,18,"BadMitte"),
	array(53298 /*[Badezimmer\.Jalousie Badezimmer rechts\Status]*/,24212,18,18,"BadRechts"),
	array(28536 /*[Flur/Treppenhaus\.Jalousie Treppenhaus\Status]*/,40108,18,18,"Treppenhaus"),
	array(21655 /*[Gästezimmer\.Jalousie Gästezimmer\Status]*/,15866,18,18,"Gästezimmer"),
	array(58957 /*[Küche\.Jalousie Küche\Status]*/,24920,18,18,"Küche"),
	array(53310 /*[Schlafzimmer\.Jalousie Ankleidezimmer\Status]*/,41276,18,18,"Ankleide"),
	array(11401 /*[Schlafzimmer\.Jalousie Schlafzimmer\Status]*/,14193,18,18,"Schlafzimmer"),
	array(59238 /*[Wohnzimmer\.Jalousie Wohnzimmer\Status]*/,16605,26,26,"Wohnzimmer"),
	array(41883 /*[Terrasse/Garten\Markise\Status]*/,33775,20,20,"Markiseraus")
);

$debug = 0; if ($debug==1){print "
";}
if (($Soll >= "1")&&($Soll <= "99")){
   $jal=GetJalousieData($Jal_ID, $jalousien);
   if ($debug==1){print "JalousieArray: ".$jal."
";}
	$ids = ($jalousien[$jal][0]);	$id = (int)$ids; $rids = ($jalousien[$jal][1]); $rid = (int)$rids;
	if ($debug==1){print "ID: ".$id."
RID: ".$rid."
";}
	$motorIDS =IPS_GetObject($id); $motorID = $motorIDS["ParentID"];
	if ($debug==1){print "MotorID: ".$motorID."
";}
	$richtungIDS = IPS_GetObject($rid);	$richtungID = $richtungIDS["ParentID"];
	$name = $jalousien[$jal][4]; $JalLZ=$name."_Jal_LZ"; $lzhoch = $jalousien[$jal][2];	$lzrunter = $jalousien[$jal][3];	$PosIst=$name."_Jal_Ist";
   $vid=CreateVariableByName($motorID, $PosIst, 1);
	$motor = GetValueBoolean($ids) ? "an" : "aus";
	if ($motor == "aus"){
		if ($debug==1){print "Motor: ".$motorID."
"; print "Richtung: ".$richtung."
";}
		$eid=CreateEventIDByName($id, "Timer für Variable: ".$id, 1);
		$PositionIst = GetValue($vid);
		if ($Soll > $PositionIst){
	   	$richtung = "hoch";
			LCN_SwitchRelay($richtungID, False);
			$dauer = (($Soll-$PositionIst)*($lzhoch/100));}
		if ($Soll < $PositionIst){
			$richtung = "runter";
      	LCN_SwitchRelay($richtungID, true);
			$dauer = (($PositionIst-$Soll)*($lzrunter/100));}
		else if ($Soll == $PositionIst){
			exit ("Position ist bereits erreicht");}
		$dauer=$dauer-0.2; //Korrektur der Busverzögerung (Sekunden)
		if ($debug==1){print "PositionierungsLaufzeit ist: ".$dauer."
";}
		if ($dauer<=1){$dauer=1;if ($debug==1){print "Laufzeit wurde auf 1 Sekunde korrigiert";}}
		IPS_SetEventCyclic($eid, 0, 0, 0, 0, 1, $dauer);
     	IPS_SetEventCyclicTimeBounds($eid, time(), 0);
     	IPS_SetEventActive($eid, true);
   	$zeit=microtime();
		$zeittemp=explode(" ",$zeit);
		$zeit=$zeittemp[0]+$zeittemp[1];
		$zeitneu=substr($zeit,5,8);
		$vidlz=CreateVariableByName($id, $JalLZ, 2);
		$posstat=CreateVariableByName($id, "Positionierung läuft", 0);
		SetValue($posstat, true);
   	SetValue($vidlz, $zeitneu);
		LCN_SwitchRelay($motorID, true);
		}
	if ($motor=="an"){
		LCN_SwitchRelay($motorID, false);
     	IPS_Sleep(1000);
     	ips_runscriptex ($IPS_SELF,array("Jal_ID" => $id, "Soll" => $Soll));
		}
	}
if ($Soll == "reset"){
	Print "
 
Jalousiemaster reset wird gestartet
 
";
	$count = count($jalousien);$i=0;
   while ($i < $count) {
      print "Jalousie Nr.: ".($i+1)." (".$jalousien[$i][4].")
";
		$zeit=microtime();
		$zeittemp=explode(" ",$zeit);
		$zeit=$zeittemp[0]+$zeittemp[1];
		$zeitneu=substr($zeit,5,8);
      $ids = ($jalousien[$i][0]);	$id = (int)$ids;
		$rids = ($jalousien[$i][1]); $rid = (int)$rids;
   	$name = $jalousien[$i][4];
		$JalLZ=$name."_Jal_LZ";
		print "Zeitvariable= ".$JalLZ."
";
		//print "VariablenID: ".$id."
";
		$vidlz=CreateVariableByName($id, $JalLZ, 2);
  		SetValue($vidlz, $zeitneu);
		$motorIDS =IPS_GetObject($id); $motorID = $motorIDS["ParentID"];
		$richtungIDS = IPS_GetObject($rid);	$richtungID = $richtungIDS["ParentID"];
		LCN_SwitchRelay($richtungID, False);
		LCN_SwitchRelay($motorID, true);
		$dauer=($jalousien[$i][3]+5);
		$eid=CreateEventIDByName($id, "Timer für Variable: ".$id, 1);
	  	IPS_SetEventCyclic($eid, 0, 0, 0, 0, 1, $dauer);
  		IPS_SetEventCyclicTimeBounds($eid, time(), 0);
  		IPS_SetEventActive($eid, true);
		print "MotorstatusID= ".$id."
";
      print "MotorID= ".$motorID."
";
      print "RichtungID= ".$richtungID."
";
      print "Laufzeit= ".$dauer."
";
      print "Reset für Jalousie Nr.: ".($i+1)." (".$name.") durchgeführt
 
";
		IPS_Sleep(1000);
		;$i++;
		print "
 
";
		}
	}

if($IPS_SENDER == "Execute")	{
	echo "Diese Skript kann so nicht ausgeführt werden.
";
	exit ("Erlaubte Trigger: Variable, Timer, ips_runscriptex mit MotorstatusID und Sollwert.
");}
if($IPS_SENDER == "Variable")	{
	$zeit=microtime();
	$zeittemp=explode(" ",$zeit);
	$zeit=$zeittemp[0]+$zeittemp[1];
	$zeitneu=substr($zeit,5,8);
   $jal=GetJalousieData($IPS_VARIABLE, $jalousien);
	$name = $jalousien[$jal][4];
   $id=intval($jalousien[$jal][0]);
	$jid=IPS_GetObject($id['ParentID']);
	$motor = GetValueBoolean($jalousien[$jal][0]) ? "an" : "aus";
	$richtung = GetValueBoolean($jalousien[$jal][1]) ? "runter" : "hoch";
	$laufzeit = GetValueBoolean($jalousien[$jal][1]) ? $jalousien[$jal][3]:$jalousien[$jal][2];
	$Faktor=100/$laufzeit;
	if ($debug==1) {
		echo "
JalousieID = ".$id."
";
		echo "Jalousie Name = ".$name."
";
		echo "Motor = ".$motor."
";
		echo "Richtung = ".$richtung."
";
		echo "Laufzeit ist: ".$laufzeit."
";}
	if($IPS_SENDER == "Variable")	{
		$PosIst=$name."_Jal_Ist";
		$JalLZ=$name."_Jal_LZ";
		$Timer=$name."_Jal_Timer";}
   $motorIDS =IPS_GetObject($IPS_VARIABLE); $motorID = $motorIDS["ParentID"];
	$vid=CreateVariableByName($motorID, $PosIst, 1);
	$eid=CreateEventIDByName($IPS_VARIABLE, "Timer für Variable: ".$IPS_VARIABLE, 1);
	$PositionIst = GetValue($vid);
	$posstatid=CreateVariableByName($IPS_VARIABLE, "Positionierung läuft", 0);
	$posstat= (GetValueBoolean($posstatid));
	if ($debug==1){print "ausgelesene Ist-Pos ist: ".$PositionIst."
Positionierungsstatus ist: ".$posstat."
";}
 if (($motor == "an")&&($posstat == false)) {
		$vidlz=CreateVariableByName($IPS_VARIABLE, $JalLZ, 2);
		$zeit1 = (GetValue($vidlz)/100);
   	$zeitmessung=$zeitneu-$zeit1;
		$zeitmessung=substr($zeitmessung,0,6);
      if ($debug==1){print "Zeitmessung ergab: ".$zeitmessung."
";}
		if ($zeitmessung <= 0){SetValue($vidlz, $zeitneu);exit ("Script mit Fehler abgebrochen, bitte reset durchführen");}
		if ($zeitmessung >= 1){
	 		SetValue($vidlz, $zeitneu);
			if ($richtung=="runter"){
		   	$dauer=(($PositionIst+10)/$Faktor);
		   	}
			else {
				$dauer=((110-$PositionIst)/$Faktor);
				}
			if ($dauer <= 0){$dauer = 1;}
			if($IPS_VALUE == True) {
		   	IPS_SetEventCyclic($eid, 0, 0, 0, 0, 1, $dauer);
   	  		IPS_SetEventCyclicTimeBounds($eid, time(), 0);
      		IPS_SetEventActive($eid, true);
   	  		if(!GetValue($IPS_VARIABLE)) {
   	     		SetValue($IPS_VARIABLE, true);
					}
   	 		}
			}
		}
	else if($motor == "aus") {
	   SetValue($posstatid, false);
		if ($debug==1){print "Motor aus, neue Position wird ermittelt und gespeichert
";}
		IPS_SetEventActive($eid, false);
  		$vidlz=CreateVariableByName($IPS_VARIABLE, $JalLZ, 2);
		$zeit1 = (GetValue($vidlz)/100);
   	$zeitmessung=$zeitneu-$zeit1;
		$zeitmessung=substr($zeitmessung,0,6);
		if ($debug==1) {print "Zeitmessung ergab: ".$zeitmessung."
";}
		if ($richtung=="runter"){
	   	$PosNeu=($PositionIst-($zeitmessung*$Faktor));
			if ($PosNeu<=0){$PosNeu=0;}
			}
  		else {
     		$PosNeu=($PositionIst+($zeitmessung*$Faktor));
			if ($PosNeu>=100) {$PosNeu=100;}
			}
		if ($debug==1){print "ID PosIST: ".$vid."
"; print "Neue Position: ".$PosNeu."
";}
		SetValue($vid, $PosNeu);
		}
	}

if($IPS_SENDER == "TimerEvent"){
   IPS_SetEventActive($IPS_EVENT, false);
   $event = IPS_GetObject($IPS_EVENT);
   $rid = IPS_GetObject($event['ParentID']);
	LCN_SwitchRelay($rid['ParentID'], false);
}

function GetJalousieData($id, $jalousien) {
	$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 wurde nicht in der Jalousien.cfg Datei gefunden
");
	}
	return $jal;
}

function CreateVariableByName($id, $name, $type)	{
   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, "Diese Variable wurde vom Script #$IPS_SELF erstellt");
   }
   return $vid;
}

function CreateEventIDByName($id, $name, $type)	{
   global $IPS_SELF;
   $eid = @IPS_GetEventIDByName($name, $id);
   if($eid===false) {
      $eid = IPS_CreateEvent($type);
      IPS_SetEventScript($eid, $IPS_SELF);
      IPS_SetParent($eid, $id);
      IPS_SetName($eid, $name);
      IPS_SetInfo($eid, "Dieses Ereignis wurde vom Script #$IPS_SELF erstellt");
   }
   return $eid;
}
?>


Bestimmt nicht perfekt programmiert aber es funktioniert bei mir sehr gut.

Gruß
Smudo