Wochenplan auslesen

Hallo Leute,

es gibt bereits mehrere Einträge zu diesem Thema, gleichwohl ist mir nicht klar welche Version aktuell die Beste ist…

  • Wie lese ich den aktuellen Zustand im Wochenplan aus?
  • Gibt es eine Nachricht die ich „abonieren“ kann wenn ein eingetragenes Ereignis beginnt oder endet? Oder muss das zyklisch eingelesen werden?

Joachim

…da es offensichtlich hier keine Innovationsprünge gab, verwende ich jetzt dieses: LINK

  • Nachrichten werden dazu offenbar auch nicht versandt wenn ein Wechsel der Aktivität stattfindet, so dass hier dann in der Konsequenz ein minütliches Pollen angesagt ist?

  • Wie kann ich bei der Erstellung des Modules alle Zeiträume z.B. mit ID 0 „vorbefüllen“? (Ohne das die Bestandsdaten die ggf. vorhanden sind überschrieben werden, jedoch „unbestimmte“ Zeiträume nicht vorkommen können?

Joachim

Was möchtest du denn erreichen? Der Wochenplan (wenn er unter einem Skript hänge) ruft diese ja bei jedem Wechsel auf. Somit kannst du sehr wohl darauf reagieren. Falls du von „außerhalb“ dies mitbekommen willst, geht es über die MessageSink und PHP-Modul. Nall-Chan hat da eins im Angebot, wenn ich mich recht entsinne.

Für deine zweite Frage gibt es nichts „fertiges“. Da musst du dich selber drum’ kümmern.

paresy

Hallo Paresy,

zunächst einmal war die Idee für ein PHP-Modul einen Wochenplan (Mo, Di, Mi, Do, Fr, Sa, So) zu erstellen in dem nur tägliche eine Sperrzeit" definiert wird. Ich stellte dann fest, dass im Webfront dann immer der ganze Tag - unabhängig von der Eingabe - gesetzt wurde…
Also habe ich nun zwei Möglichkeiten definiert: Sperrzeiten und Freigabe.
So weit, so gut…
Jetzt geht es darum festzustellen, in welcher Phase (Sperrzeit, Freigabe oder undefiniert (wenn der Wochenplan noch gar nicht gefüllt wurde)) ich mich befinde. Dazu benutzt ich Dein Skript aus dem oben verlinktem Thread.
Jedoch sind die Ergebnisse die ich nun testweise alle 60 Sekunden ausführe, nicht so richtig nachvollziehbar.
Obwohl für den jetzigen Zeitpunkt etwas definiert ist, ist das Ergebnis des Skriptes offenbar „0“, vergeben wurden für Freigabe ID 1 und für die Sperrzeit die ID 2.
Möglicherweise ist mein Ansatz hier zum Umgang mit dem Wochenplan nicht ganz korrekt…:confused:

Joachim

—was mache ich:
Im ApplyChanges:

$this->RegisterEvent("Wochenplan", "IPS2Watering_Event_".$this->InstanceID, 2, $this->InstanceID, 30);
		// Anlegen der Daten für den Wochenplan
		for ($i = 0; $i <= 6; $i++) {
			IPS_SetEventScheduleGroup($this->GetIDForIdent("IPS2Watering_Event_".$this->InstanceID), $i, pow(2, $i));
		}
IPS_SetEventScheduleAction($this->GetIDForIdent("IPS2Watering_Event_".$this->InstanceID), 1, "Freigabe", 0x40FF00, "IPS2Watering_SetState(\$_IPS['TARGET'], 1);");	
		IPS_SetEventScheduleAction($this->GetIDForIdent("IPS2Watering_Event_".$this->InstanceID), 2, "Sperrzeit", 0xFF0040, "IPS2Watering_SetState(\$_IPS['TARGET'], 1);");	

Wobei RegisterEvent ist:

	private function RegisterEvent($Name, $Ident, $Typ, $Parent, $Position)
	{
		$eid = @$this->GetIDForIdent($Ident);
		if($eid === false) {
		    	$eid = 0;
		} elseif(IPS_GetEvent($eid)['EventType'] <> $Typ) {
		    	IPS_DeleteEvent($eid);
		    	$eid = 0;
		}
		//we need to create one
		if ($eid == 0) {
			$EventID = IPS_CreateEvent($Typ);
		    	IPS_SetParent($EventID, $Parent);
		    	IPS_SetIdent($EventID, $Ident);
		    	IPS_SetName($EventID, $Name);
		    	IPS_SetPosition($EventID, $Position);
		    	IPS_SetEventActive($EventID, true);  
		}
	}  

Das Auslesen mit dem Skript:

	public function GetWeekplanState()
	{
		$this->SendDebug("GetWeekplanState", "Wochenplan Status einlesen", 0);
		$e = IPS_GetEvent($this->GetIDForIdent("IPS2Watering_Event_".$this->InstanceID));
		$actionID = false;
		//Durch alle Gruppen gehen
		foreach($e['ScheduleGroups'] as $g) {
		    //Überprüfen ob die Gruppe für heute zuständig ist
		    if($g['Days'] & date("N") > 0) {
			//Aktuellen Schaltpunkt suchen. Wir nutzen die Eigenschaft, dass die Schaltpunkte immer aufsteigend sortiert sind.
			foreach($g['Points'] as $p) {
			   if(date("H") * 3600 + date("i") * 60 + date("s") >= $p['Start']['Hour'] * 3600 + $p['Start']['Minute'] * 60 + $p['Start']['Second']) {
			      $actionID = $p['ActionID'];
			   } else {
			      break; //Sobald wir drüber sind, können wir abbrechen.
			   }
		       }
			break; //Sobald wir unseren Tag gefunden haben, können wir die Schleife abbrechen. Jeder Tag darf nur in genau einer Gruppe sein.
		    }
		}
		SetValueInteger($this->GetIDForIdent("WeekplanState"),  intval($actionID));
	}
  • Das Ergebnis ist leider nicht das Erwartet (also das was im Wochenplan im Webfront eingetragen wurde)
  • Der Wochenplan stellt die Tage nicht in der erwarteten Reihenfolge dar (die Tage sind durcheinander)

Joachim

…ich habe herausgefunden, dass jeweils nur das Tagesprogramm im Wochenplan für Monatg geprüft wird - und eben leider nicht für Mittwoch…
Noch mal die Vorlage von Paresy in Gänze:

public function GetWeekplanState()
	{
		$this->SendDebug("GetWeekplanState", "Wochenplan Status einlesen", 0);
		$e = IPS_GetEvent($this->GetIDForIdent("IPS2Watering_Event_".$this->InstanceID));
		$actionID = false;
		//Durch alle Gruppen gehen
		foreach($e['ScheduleGroups'] as $g) {
		    //Überprüfen ob die Gruppe für heute zuständig ist
		    if($g['Days'] & date("N") > 0) {
			//Aktuellen Schaltpunkt suchen. Wir nutzen die Eigenschaft, dass die Schaltpunkte immer aufsteigend sortiert sind.
			foreach($g['Points'] as $p) {
			   if(date("H") * 3600 + date("i") * 60 + date("s") >= $p['Start']['Hour'] * 3600 + $p['Start']['Minute'] * 60 + $p['Start']['Second']) {
			      $actionID = $p['ActionID'];
			   } else {
			      break; //Sobald wir drüber sind, können wir abbrechen.
			   }
		       }
			break; //Sobald wir unseren Tag gefunden haben, können wir die Schleife abbrechen. Jeder Tag darf nur in genau einer Gruppe sein.
		    }
		}
		$this->SendDebug("GetWeekplanState", "Ergebnis: ".intval($actionID), 0);
		SetValueInteger($this->GetIDForIdent("WeekplanState"),  intval($actionID));
	}

Ich vermute den Fehler hier in dieser Zeile:

  if($g['Days'] & date("N") > 0) {

Jemand eine Idee?

Joachim

Hallo,
ja das ist das Problem versuch mal …

 if(($g['Days'] & pow(2,date("N",time())-1)) > 0)

… wenn Du Dir die Beitrage anschauen würdest, hier ist die Problematik gelöst

[b]Link zu GetWeekplanState

Link zu SaveWeekplanToFile[/b]

… hier sieht Du dann wie man einer Group (Tagen) die Zeiten setzen kann ==> man muss leider immer von 00:00 aufsetzen, eine Funktion für „umdefinieren“ fehlt

//RESTORE ScheduleGroups + + + + + + + + + + + + + + + + + + + + + + + +

//Group 0
IPS_SetEventScheduleGroup($ID,0,124);

IPS_SetEventScheduleGroupPoint($ID,0,0,3,15,0,1);
IPS_SetEventScheduleGroupPoint($ID,0,1,7,4,30,3);
IPS_SetEventScheduleGroupPoint($ID,0,2,14,20,30,2);
IPS_SetEventScheduleGroupPoint($ID,0,6,19,30,0,0);

tgusi74

(Wochenplan, WeekplanState, SaveWeekplan, SaveWeekplanToFile)

Hallo tgusi74,

vielen Dank für Deinen Beitrag. Das sieht schon mal deutlich besser aus als vorher!:smiley:

Joachim

Ich hab den Thream mal ins richtige Forum verschoben.

Grüße,
Kai

…einen habe ich noch…:smiley:

Ich möchte gerne wissen wie lenge der aktuelle Status andauert.

//Aktuellen Schaltpunkt suchen. Wir nutzen die Eigenschaft, dass die Schaltpunkte immer aufsteigend sortiert sind.
				foreach($g['Points'] as $p) 
				{
			   		if(date("H") * 3600 + date("i") * 60 + date("s") >= $p['Start']['Hour'] * 3600 + $p['Start']['Minute'] * 60 + $p['Start']['Second']) 
					{
						$Starttime = $p['Start']['Hour'] * 3600 + $p['Start']['Minute'] * 60 + $p['Start']['Second'];
						$Endtime = ($p + 1)['Start']['Hour'] * 3600 + ($p + 1)['Start']['Minute'] * 60 + ($p + 1)['Start']['Second'];
						$actionID = $p['ActionID'];
			   		} 
					else 
					{
			      			break; //Sobald wir drüber sind, können wir abbrechen.
			   		}
		       		}
				break; //Sobald wir unseren Tag gefunden haben, können wir die Schleife abbrechen. Jeder Tag darf nur in genau einer Gruppe sein.

Die Zeile:

$Endtime = ($p + 1)['Start']['Hour'] * 3600 + ($p + 1)['Start']['Minute'] * 60 + ($p + 1)['Start']['Second'];

funktioniert so nicht.

Di Idee war, das die Startzeit des folgenden Points das Ende der jetzigen darstellt.

Wie komme ich an die Dauer der aktuellen Phase?

Joachim

Ich denke die einfachste Variante ist es hier über IPS_GetEvent(…)[‚NextRun‘] zu gehen. Das ist nämlich der Zeitstempel der nächsten Ausführung

Hallo Dr.Niels,

der Tip war sehr gut! Vielen Dank.

War jetzt ein bisschen Rechnerei die Werte und damit die Differenz ausrechnen zu können, hat sich aber gelohnt.

Joachim