Shutterscript mit Lamellen

Hallo Leute
Hier mal ein Shutterscript mit Lamellen Ansteuerung.(weil mir die vorhandenen nicht gepasst haben oder zu überladen bzw ungenau waren).

Wer jetzt noch das ganze zu einem Modul basteln kann, wäre TOP :slight_smile: :smiley:

Config PHP

<?
//-------- PARAMETER --------//

$id_state               = 38300 /*[Jalousien\Jalousie Position\Jalousie Centro\state]*/;                    // Process Stufe
$id_dt                  = 51828 /*[Jalousien\Jalousie Position\Jalousie Centro\dt]*/;                       // Timestamp + Fahrzeit = end Timestamp
$id_start               = 28627 /*[Jalousien\Jalousie Position\Jalousie Centro\starttime]*/;                // Timestamp Fahrbefehl
$id_actor               = 46612 /*[Jalousien\Jalousien Bedienung\Jalousie Centro]*/;                        // Jalousie Aktor
$id_errorcnt            = 17290 /*[Jalousien\Jalousie Position\Jalousie Centro\Config\errorcount]*/;        // Fehler Counter

$id_pos_shutter     	= 37292 /*[Jalousien\Jalousie Position\Jalousie Centro\Shutter Position]*/;
$id_shutter_act         = 40579 /*[Jalousien\Jalousie Position\Jalousie Centro\Shutter Position]*/;         // Aktuelle Position Shutter
$id_shutter_src         = 39262 /*[Jalousien\Jalousie Position\Jalousie Centro\Shutter Position\src]*/;		// Letzte Position Shutter
$id_shutter_dst         = 10244 /*[Jalousien\Jalousien Bedienung\Jalousie Centro\Shutter]*/;				// Buttons on Webfront for Shutter

$id_slate_pos           = 54551 /*[Jalousien\Jalousie Position\Jalousie Centro\Slates Position\pos]*/;		// Zwischenspeichern der letzten Slate Position % - damit falls gewünscht nach fahrzeit wieder in die letzte Position gestellt wird
$id_slate_act           = 31560 /*[Jalousien\Jalousie Position\Jalousie Centro\Slates Position]*/;			// Aktuelle Position Slate
$id_slate_src           = 28121 /*[Jalousien\Jalousie Position\Jalousie Centro\Slates Position\src]*/;		// Letzte Position Slate
$id_slate_dst           = 23182 /*[Jalousien\Jalousien Bedienung\Jalousie Centro\Slates]*/;					// Buttons on Webfront for Shutter


$time_slate_0to100      = 3.2;  // Fahrzeit Slates von Geschlossen - Geöffnet
$time_slate_100to0      = 3.2;                           // Fahrzeit Slates von Geöffnet - Geschlossen

$time_shutter_0to100    = 55.0;		// Fahrzeit Shutter von Unten - Oben
$time_shutter_100to0    = 55.0;		// Fahrzeit Shutter von Oben - Unten

define("LOGGING",	false);

include(IPS_GetScript(15074 /*[Jalousien\JalousieMakro]*/)['ScriptFile']);
?>

Makro PHP

<?
//-------- READ --------//

$state			= GetValue($id_state);
$dt				= GetValue($id_dt);
$start			= GetValue($id_start);
$errorcnt		= GetValue($id_errorcnt);

// % werte (höhe)			0%=unten 	100%=oben
$pos_shutter	= GetValue($id_pos_shutter);
$shutter_act	= GetValue($id_shutter_act);
$shutter_src	= GetValue($id_shutter_src);
$shutter_dst	= GetValue($id_shutter_dst);
// % werte (lamelle)		0%=unten	100%=oben
$slate_pos		= GetValue($id_slate_pos);
$slate_act		= GetValue($id_slate_act);
$slate_src		= GetValue($id_slate_src);
$slate_dst		= GetValue($id_slate_dst);

//-------- PROCESS --------//
define("START", 						0);
define("RECHNE_LAMELLENKORREKTUR",		1);
define("WARTEN_LAMELLENKORREKTUR",		2);
define("RECHNE_HOEHENKORREKTUR",		3);
define("WARTEN_HOEHENKORREKTUR",		4);
define("RECHNE_LAMELLENPOSITION",		5);
define("WARTEN_LAMELLENPOSITION",		6);
define("ENDE",							7);

function logInfo($msg){
	if(LOGGING)
		IPS_LogMessage($_IPS['SELF'], $msg);
}

switch($state){
	// Schrittkette ist abgeschlossen, alles zurück auf START
	case ENDE:{
		logInfo("ENDE: abschliessen");
		$state = START;
		break;
	}
	
	// Warten bis die Bewegung für die abschliessende Lamellenposition abgeschlossen ist
	case WARTEN_LAMELLENPOSITION:{
		logInfo("WARTEN_LAMELLENPOSITION: Bewegung läuft");
		IPS_Sleep(200);		// Skript verzögern, verhindert ein volllaufen des Buffers
		$slate_act = $slate_dst;
		if(time() > $dt){
			logInfo("WARTEN_LAMELLENPOSITION: Bewegung abgeschlossen");
			$slate_src = $slate_dst;
			$state = ENDE;
		}
		break;
	}
	
	// Berechnen wie lange bewegt werden muss um die Lamellenposition zu erreichen
	case RECHNE_LAMELLENPOSITION:{
		logInfo("RECHNE_LAMELLENPOSITION: Berechne Lamellen-Bewegung");
		$rt = 0.0;
		$repeat = false;
		if($slate_dst > $slate_src){		// Zielposition liegt höher
			$rt = $time_slate_0to100 * ((float)$slate_dst-(float)$slate_src) / 100.0; 
			if(!ENO_ShutterMoveUpEx($id_actor, $rt))
				$repeat = true;
			logInfo("heben: $rt sec");
		}
		else if($slate_dst < $slate_src){	// zielposition liegt tiefer
			$rt = $time_slate_100to0 * ((float)$slate_src-(float)$slate_dst) / 100.0;
			if(!ENO_ShutterMoveDownEx($id_actor, $rt))
				$repeat = true;
			logInfo("senken: $rt sec");
		}
		else{								// Positionen identisch, keine Korrektur notwendig
			logInfo("ABBRUCH, bereits in Position");
			$state = ENDE;
			break;
		}
		// Startzeit und Endzeit übernehmen
		$dt = time() + $rt;
		$start = time();
		
		if(!$repeat){	// Befehl wurde übernommen, warten bis Bewegung fertig
			$errorcnt = 0;
			$state = WARTEN_LAMELLENPOSITION;
			break;
		}
		
		$errorcnt++;	// 10x wiederholen wenn der Befehl nicht übernommen werden konnte
		if($errorcnt > 10){
			$errorcnt = 0;
			logInfo("ERROR PREPARE_SLATE");
			$state = ENDE;
		}
		break;
	}
	
	case WARTEN_HOEHENKORREKTUR:{
		logInfo("WARTEN_HOEHENKORREKTUR:");
		IPS_Sleep(500);
		
		$endzeit = $dt - $start;			// Gesamte Fahrzeit
		$istzeit = time() - $start;			// Aktuelle Fahrzeit
		$restzeit = $endzeit - $istzeit;	// Verbleibende Fahrzeit
		$fahrweg = $shutter_dst - $shutter_src;
		if($endzeit == 0)
			$endzeit = 1; 	// Schutz gegen division durch 0
		
		$shutter_act = $shutter_src + $fahrweg * $istzeit / $endzeit;
		$pos_shutter = sprintf('(%ds) %d%%', $restzeit, $shutter_act);
		
		if(($_IPS["VARIABLE"] == $id_shutter_dst and $_IPS["VALUE"] == -1) or $shutter_dst == -1){	// Abbruch mit STOP-Befehl
			logInfo("WARTEN_HOEHENKORREKTUR: manueller STOP-Befehl");
			ENO_ShutterStop($id_actor);
			$slate_dst = $slate_src;
			$shutter_src = $_IPS["VALUE"];
			$shutter_dst = $_IPS["VALUE"];
			$pos_shutter = sprintf('manueller STOP');
			$state = ENDE;
			break;
		}
		
		
		if(time() > $dt){
			logInfo("WARTEN_HOEHENKORREKTUR: Bewegung abgeschlossen");
			$slate_src = $slate_pos;
			$shutter_src = $shutter_dst;
			$shutter_act = $shutter_dst;
			$pos_shutter = sprintf('%d%%', $shutter_act);
			$state = RECHNE_LAMELLENPOSITION;
		}
		break;
	}
	case RECHNE_HOEHENKORREKTUR:{
		logInfo("RECHNE_HOEHENKORREKTUR:");
		$rt = 0.0;
		$repeat = false;
		if($shutter_dst > $shutter_src){
		
			$rt = $time_shutter_0to100 * ((float)$shutter_dst-(float)$shutter_src) / 100.0;
			if($shutter_dst == 100.0){
				logInfo("heben: endlos ($rt sec)");
				$slate_dst = $slate_pos;
				if(!ENO_ShutterMoveUp($id_actor))
					$repeat = true;
			}
			else{
				logInfo("heben: $rt sec");
				if(!ENO_ShutterMoveUpEx($id_actor, $rt))
					$repeat = true;
			}
			
		}
		else if($shutter_dst < $shutter_src){
			$rt = $time_shutter_100to0 * ((float)$shutter_src-(float)$shutter_dst) / 100.0;
			if($shutter_dst == 0.0){
				logInfo("senken: endlos ($rt sec)");
				$slate_dst = $slate_pos;
				if(!ENO_ShutterMoveDown($id_actor))
					$repeat = true;
			}
			else{
				logInfo("senken: $rt sec");
				if(!ENO_ShutterMoveDownEx($id_actor, $rt))
					$repeat = true;
			}
		}
		else{
			logInfo("ABBRUCH, höhenkorrektur nicht notwendig");
		}
		
		$dt = time() + $rt;
		$start = time();
		
		if(!$repeat){
			$errorcnt = 0;
			$state = WARTEN_HOEHENKORREKTUR;
			break;
		}
		
		$errorcnt++;
		if($errorcnt > 10){
			$errorcnt = 0;
			logInfo("ERROR RECHNE_HOEHENKORREKTUR");
			$state = ENDE;
		}
		break;
	}
	
	case WARTEN_LAMELLENKORREKTUR:{
		logInfo("WARTEN_LAMELLENKORREKTUR: Bewegung läuft");
		IPS_Sleep(200);
		$slate_act = $slate_pos;
		if(time() > $dt){
			logInfo("WARTEN_LAMELLENKORREKTUR: Bewegung abgeschlossen ($slate_pos)");
			$slate_src = $slate_pos;
			$state = RECHNE_HOEHENKORREKTUR;
		}
		break;
	}
	case RECHNE_LAMELLENKORREKTUR:{
		logInfo("RECHNE_LAMELLENKORREKTUR:");
		$rt = 0.0;
		$repeat = false;
		if($slate_pos > $slate_src){
		
			$rt = $time_slate_0to100 * ((float)$slate_pos-(float)$slate_src) / 100.0; 
			if(!ENO_ShutterMoveUpEx($id_actor, $rt))
				$repeat = true;
			logInfo("heben: $rt sec");
		}
		else if($slate_pos < $slate_src){
			$rt = $time_slate_100to0 * ((float)$slate_src-(float)$slate_pos) / 100.0;
			if(!ENO_ShutterMoveDownEx($id_actor, $rt))
				$repeat = true;
			logInfo("senken: $rt sec");
		}
		else{
			logInfo("ABBRUCH, lamellenkorrektur nicht notwendig");
		}
		
		$dt = time() + $rt;
		$start = time();
		
		
		if(!$repeat){
			$errorcnt = 0;
			$state = WARTEN_LAMELLENKORREKTUR;
			break;
		}
		
		$errorcnt++;
		if($errorcnt > 10){
			logInfo("ERROR RECHNE_LAMELLENKORREKTUR");
			$state = ENDE;
		}
		break;
	}
	
	case START:{
		
		if($_IPS["VARIABLE"] == $id_shutter_dst and $_IPS["VALUE"] >= 0 and $_IPS["VALUE"] <= 100){
			logInfo("START: shutterposition");
			$shutter_dst = $_IPS["VALUE"];
		}
		if($_IPS["VARIABLE"] == $id_slate_dst and $_IPS["VALUE"] >= 0 and $_IPS["VALUE"] <= 100){
			logInfo("START: slateposition");
			$slate_dst = $_IPS["VALUE"];
		}
			
		if($shutter_src == $shutter_dst and $slate_src == $slate_dst){
			logInfo("START: Eingabe ungültig");
			$state = ENDE;
		}
		elseif($shutter_src == $shutter_dst){
			logInfo("START: Lamellen neu ausrichten $slate_src >> $slate_dst");
			$state = RECHNE_LAMELLENPOSITION;
		}
		else{
			logInfo("START: Höhenkorrektur $shutter_src > $shutter_dst (Slate: $slate_dst)");
			if($shutter_src == 100)
				$slate_dst = 0;			// Bei Fahrbewegung von oberster Position, Lamellen nicht nachregeln
			if($shutter_dst > $shutter_src){
				$slate_pos = 100.0;		// Shutter-Korrektur vor Fahrbewegung
			}
			else{
				$slate_pos = 0.0;		// Shutter-Korrektur vor Fahrbewegung
			}
			$state = RECHNE_LAMELLENKORREKTUR;
		}
		break;
	}
	
	default:{
		logInfo("zuruecksetzen (default)");
		$state = START;
		break;
	}
}

//-------- WRITE --------//
if(GetValue($id_shutter_dst) != -1){
	SetValue($id_state, 	$state);
	SetValue($id_dt, 		$dt);
	SetValue($id_start, 	$start);
	SetValue($id_errorcnt, 	$errorcnt);

	// % werte
	SetValue($id_pos_shutter, $pos_shutter);
	SetValue($id_shutter_act, $shutter_act);
	SetValue($id_shutter_src, $shutter_src);
	SetValue($id_shutter_dst, $shutter_dst);
	// % werte
	SetValue($id_slate_pos, $slate_pos);
	SetValue($id_slate_act, $slate_act);
	SetValue($id_slate_src, $slate_src);
	SetValue($id_slate_dst, $slate_dst);
}
elseif(GetValue($id_shutter_dst) == -1 and $_IPS["VARIABLE"] == $id_shutter_dst and $_IPS["VALUE"] >= 0 and $_IPS["VALUE"] <= 100){
	SetValue($id_state, 	START);
	SetValue($id_dt, 		0);
	SetValue($id_start, 	0);
	SetValue($id_errorcnt, 	0);

	// % werte
	SetValue($id_pos_shutter, 0);
	SetValue($id_shutter_act, 0);
	SetValue($id_shutter_src, 0);
	SetValue($id_shutter_dst, 0);
	// % werte
	SetValue($id_slate_pos, 0);
	SetValue($id_slate_act, 0);
	SetValue($id_slate_src, 0);
	SetValue($id_slate_dst, 0);
}
else{
	SetValue($id_state, 	START);
}
?>

Noch ein Printscreen des Objektbaums

und zuletzt noch das webfront

Vielen herzlichen Dank für das Skript. Und was soll so ein Modul dann machen, die 4 Variablen anlegen und die Position berechnen? Das ganze dann unabhängig von dem eigentlichen System, also in dem Fall EnOcean?

Hallo Fonzo

Ja eigentlich muss es noch viel erstellen

-Jalousie Dummy siehe 50664 ( Jalousie " Name im Modul Konfigurierbar")
-Shutter Position(string) mit den unter Integer act, src, pos
-Slates Position (integer) mit den unter Integer src, pos
-Starttime
-state
-dt
usw.

Auswahl des Aktors im Modul
$id_actor = 46612 /[Jalousien\Jalousien Bedienung\Jalousie Centro]/;
$time_slate_0to100 = zeit im modul eintragen
$time_slate_100to0 = zeit im modul eintragen

$time_shutter_0to100 = zeit im modul eintragen
$time_shutter_100to0 = zeit im modul eintragen

würde es ja auch selber probieren aber ich habe echt 0 ahnung von Modulen erstellen…

Ja ist Enocean - aber es darf natürlich von jedem auf seine geräte angepasst werden oder sogar ins script implementiert werden. zb homematic usw

Muss man sich nur trauen so schwer ist das nicht, wenn Fragen sind dann einfach stellen.

Hier findest Du mal für Dein Modul ein Grundgerüst
GitHub - Wolbolar/IPSymconSlat

da musst Du dann noch Deine Funktionen als Methoden ergänzen und vom Modul die Variablen und Profile anlegen lassen.

Hier findest Du die Dokumentation dazu, wenn man Dir helfen kann kannst du ja fragen.

Hier findest Du auch ein Video zur Entwicklung eines einfachen PHP Moduls bzw. da wird erklärt was was macht.