FHT Zeitabgleich für IPS V2.x (Synchronisation)

Ich stelle heute mal ein neues FHT Zeitabgleichs-Script für die IPS-Version 2.x (inkl. 2.2) vor. Es gab bereits ein tolles ähnliches Script für die V1, dessen Grundgedanken ich dabei aufgefasst habe. Von dieser V1-Version gibt es mittlerweile auch wenigstens 2 „Übersetzungen“ für die V2. Allerdings hatte ich bereits bei der V1 das Problem, dass meine FHT Ihre Befehle sehr unzuverlässig bei der FHZ abholten. Das konnte dazu führen, dass die Uhr des FHT plötzlich falsch lief.
(Beispiel: Die FHZ sendet um x:15 Uhr „es ist x:15 Uhr“ und das FHT holt sich diesen Befehl erst um x:39 Uhr aus der Queue der FHZ ab…)
Somit war ich gezwungen eine Variante mit Empfangskontrolle zu basteln. Und das funktioniert etwa so:
Das Script sucht sich nach seinem Start automatisch das FHT, das am längsten nicht mehr synchronisiert wurde und beginnt mit dem Zeitabgleich:

  1. Das Script wartet, bis die gesamte Queue der FHZ frei ist – das ist später für die Empfangskontrolle wichtig
  2. Berechnet das nächste Zeitfenster für den Empfang von Daten des jeweiligen FHT und wartet darauf – das habe ich aus der Diskussion zum o.g. Script für die V1 übernommen (obwohl es eigentlich nicht mehr nötig wäre…) Im Script habe ich das als „Timeport“ bezeichnet.
  3. Wenige Sekunden vor dem „Timeport“ wird die aktuelle Minute an das FHT gesendet. Sollte die Minute innerhalb dieser wenigen Sekunden noch umspringen, wird dies berücksichtigt. (Deshalb wäre das warten auf den „Timeport“ eigentlich nicht nötig…)
  4. Wenige Sekunden NACH diesem Timeport wird die FHZ-Queue wieder ausgelesen. Wenn diese wieder komplett frei ist, ist das Sekunden-Signal garantiert angekommen à weiter zu 5.
    Ansonsten ist das Signal vermutlich nicht abgerufen worden und könnte die Zeiteinstellung des FHT nach dem verspäteten Abruf verfälschen. Also warten bis das Signal (zu spät) abgerufen wurde und dann zurück zu 2.
  5. Nach der zweifellos erfolgreichen Übertragung des Minuten-Signals wird jetzt noch die aktuelle Stunde an die FHT übertragen (sicher = sicher).
  6. Auch hier wird der Abruf des Signals über die FHZ-Queue überwacht. Sofern die Queue innerhalb der aktuellen Stunde wieder auf Null ist, wurde dieses Signal ganz sicher rechtzeitig von dem FHT abgerufen. Ansonsten (falls die Stunde umspringt, bevor das Signal bei dem FHT ist) wird auch dieser Schritt wiederholt -> zurück zu 5.

Dieses Script setzt sich also so lange immer wieder einen eigenen Script-Timer, bis das FHT garantiert rechzeitig die richtigen Zeit-Signale abgerufen hat – selbst wenn das Stunden dauern sollte! Danach unternimmt das Script selbstständig nichts mehr: Für das Update des nächsten FHT muss dieses Script also möglichst von einem externen Script wieder gestartet werden (vielleicht reicht auch ein Script-Timer?). Ideal ist ein Zeitpunkt nachts (wenn wenig Funkverkehr ist) – und möglichst kurz nach einem Stundenwechsel. (z.B. 02:10 Uhr)…

Ich habe dieses Script jetzt zur Veröffentlichung bewusst nicht mehr „verschönt“ um nicht noch einen Fehler zu generieren – das ist buchstäblich meine auskommentierte Version, die bei mir seit 6 Monaten fehlerfrei läuft (jetzt auch unter V2.2). Es sind auch reichlich „echo“-Kommentare drin, die die Funktionen verdeutlichen.

Im Gegensatz zu der oben erwähnten Vorgänger-Version für die V1 ist hier allerdings etwas handarbeit bei der Installation erforderlich:

1.) Für jede FHT muss manuell eine String-Variable angelegt werden. Diese Variable wird dann vom Script im „Klartext“ beschrieben, was zur Beobachtung und Kontrolle der Funktion recht interessant ist.
2.) Innerhalb des Scripts muss (im oberen Bereich) für jede FHT eine Zeile zur Belegung der Array-Daten eingefügt werden: „ID der FHT“, „ID der Variable aus Punkt 1.“, „ID der Status-Variable des Ventilantriebs der FHT“.
3.) In der ersten Zeile bitte die ID der FHZ eintragen (statt der „00000“).

-NACHTRAG: DURCH DIE ÄNERDUNGEN IM BEITRAG NR. 9 VON HIRSCHBRAT (weiter unten) ENTFALLEN DIE HIER GENANNTEN „HANDARBEITEN“. Dadurch wird das Script „Plug&Play-fähig“ wie die Vorgängerversionen der V1! :slight_smile:

Und jetzt endlich zum Script:


<?
$FHZ_ID=00000 /*[FHZ 1300 PC]*/;
$Sende_Interval_Ventilpos=115;
$Signal_vor_Sendezeit=11;
$FHT_Liste=array();

//FHT-Daten in Array ablegen: FHT-ID, FHT-Zeitabgleich-Variable, FHT-Ventil-Variable
$FHT_Liste[]=array(11111 /*[erste_FHT_ID]*/,22222 /*[erste_String_Variable]*/,33333 /*[erste_FHT_Ventil_ID]*/);
$FHT_Liste[]=array(44444 /*[zweite_FHT_ID]*/,55555/*[zweite_String_Variable]*/,66666 /*[zweite_FHT_Ventil_ID]*/);
$FHT_Liste[]=array(77777 /*[dritte_FHT_ID]*/,88888 /*[dritte_String_Variable]*/,99999 /*[dritte_FHT_Ventil_ID]*/);

//FHT mit dem ältesten Update suchen
$aeltester_Wert=9999999999999;
$weitersuchen=TRUE;
foreach($FHT_Liste as $FHT_Daten)
	{
	$v=IPS_GetVariable($FHT_Daten['1']);
	$letztes_Update=$v['VariableUpdated'];
	if((($letztes_Update<$aeltester_Wert) OR (GetValue($FHT_Daten['1'])<>"gesendet")) AND $weitersuchen==TRUE)
	   {
		$aeltester_Wert=$letztes_Update;
		if(GetValue($FHT_Daten['1'])<>"gesendet") $weitersuchen=FALSE; //Falls diese FHT bereits in bearbeitung ist, nicht weitersuchen
		$FHT_ID=$FHT_Daten['0'];
		$FHT_Variable=$FHT_Daten['1'];
		$FHT_Ventil_Variable=$FHT_Daten['2'];
		}
	}

echo $FHT_ID." 
".$FHT_Variable." 
".$FHT_Ventil_Variable." 
".$weitersuchen." 
";


//Stunde wurde gesendet - Jetzt prüfen
if(substr((GetValue($FHT_Variable)),0,12)=="sende Stunde")
	{
	Stunde_pruefen($FHT_ID, $FHT_Variable, $IPS_SELF, $FHZ_ID);
	return;
	}


//Uhrzeit prüfen - zum Stundenwechsel könnte es zur Verschiebung kommen
if(date('i')>50)
	{
	echo "ungünstige Zeit (Stundenwechsel) - warten...";
	IPS_SetScriptTimer ($IPS_SELF,300);
	return;
	}
if(date('i')<5)
	{
	echo "ungünstige Zeit (Stundenwechsel) - warten...";
	IPS_SetScriptTimer ($IPS_SELF,120);
	return;
	}
	

//Buffer der FHZ prüfen - freier Buffer ist zur Empfangskontrolle erforderlich
$Freie_Buffer=FHZ_GetFreeBuffer($FHZ_ID);
if($Freie_Buffer<10)
	{
	echo "Buffer belegt... 2 Minuten warten";
   IPS_SetScriptTimer ($IPS_SELF,120); //nächster Versuch in 2 Minuten (auf Buffer warten)
	return;
	}

//------------------   Was soll getan werden?   --------------------
//Minute wurde gesendet - Jetzt Stunde senden
if(GetValue($FHT_Variable)=="Minute gesendet")
	{
	Stunde_senden($FHT_ID, $FHT_Variable, $IPS_SELF);
	return;
	}


//----------------- Minute senden  ----------------------------------
//letzten und nächsten Timeport / Sendeplatz ermitteln
$v=IPS_GetVariable($FHT_Ventil_Variable);
$letzter_Timeport_Zeit=$v['VariableUpdated'];
$letzter_Timeport=intval(time()-$letzter_Timeport_Zeit);
echo "letzter Empfang: ".$letzter_Timeport." s 
";
if($letzter_Timeport>$Sende_Interval_Ventilpos)
	{
	echo "letzte Ventilposition nicht empfangen - nächster Versuch in 1,5 Minuten!";
   IPS_SetScriptTimer ($IPS_SELF,90); //nächster Versuch in 2 Minuten (Warte auf Empfang der Ventilposition)
	return;
	}
$Empfang_in=$Sende_Interval_Ventilpos-$letzter_Timeport;
echo "nächster Timeport: ".$Empfang_in." s 
";
$Sende_in=$Empfang_in-$Signal_vor_Sendezeit;
if ($Sende_in < -1)  //Sendeplatz überspringen (Signal_vor_Sendzeit um mehr als eine Sekunde unterschritten)
	{
	$Sende_in=$Sende_in+$Sende_Interval_Ventilpos;
	}
echo "Sende in ".$Sende_in." s 
";


//Signal senden oder Script beim nächsten Timeport neu starten
if ($Sende_in < 13) //Timeport getroffen - Signal senden
	{
	echo "Timeport getroffen - jetzt senden! 
 ";
   IPS_SetScriptTimer ($IPS_SELF, 0);
	$sende_Minute=date('i',time()+$Empfang_in); //aktuelle Minute zum voraussichtlichen Zeitpunkt des Empfangs
	SetValue($FHT_Variable,"sende m=".$sende_Minute);
   FHT_SetMinute($FHT_ID,intval($sende_Minute));
   IPS_SetScriptTimer ($IPS_SELF,0);  //zunächst löschen um neuen Programmstart während Empfangstest zu vermeiden
	$Empfangstest=TRUE; //nächsten Programmteil starten
	}
	ELSE //warten auf nächsten Timeport
	{
	echo "Setze Script-Timer auf ".$Sende_in." s 
";
	IPS_SetScriptTimer ($IPS_SELF, $Sende_in);
	SetValue($FHT_Variable,"sende in ".$Sende_in."s");
   $Empfangstest=FALSE; //nächsten Programmteil nicht starten
	}
//------------------------------ Empfangstest für Minutensignal ------------------------------
if ($Empfangstest==TRUE)
	{
	IPS_Sleep(1000); //warten bis Signal im Buffer ist
	$Durchlauf=0;
	while((FHZ_GetFreeBuffer($FHZ_ID)<10) AND ($Durchlauf<20))
	   {
		$Durchlauf=$Durchlauf+1;
		//echo "Buffer geprüft - Signal wartet 
";
		IPS_Sleep(1000);
		}
	if(FHZ_GetFreeBuffer($FHZ_ID)==10)
	   {
		echo "Signal wurde nach ".$Durchlauf." Sekunden abgerufen! 
";
		SetValue($FHT_Variable,"Minute gesendet");
      IPS_SetScriptTimer ($IPS_SELF,60);  //erneut starten um Übertragung der Stunde zu starten
		}
		ELSE //Signal wurde nicht abgerufen
		{
      echo "Fehler - Signal wurde nach 20 Sek nicht abgerufen! 
";
		SetValue($FHT_Variable,"Fehler!");
      IPS_SetScriptTimer ($IPS_SELF,120); //nächster Versuch in 2 Minuten (neues Signal senden)
		}
	}


//---------------------------- ab hier Definition der Funktionen zur Stundenübertragung -------------

function Stunde_senden($FHT_ID, $FHT_Variable, $IPS_SELF)
	{
	$akt_Stunde=date('H');
	SetValue($FHT_Variable,"sende Stunde ".$akt_Stunde);
	echo "Sende Stunde ".$akt_Stunde." 
";
	FHT_SetHour($FHT_ID,intval($akt_Stunde));
	IPS_SetScriptTimer ($IPS_SELF,60);  //erneut starten um Empfang der Stunde zu prüfen
	}

function Stunde_pruefen($FHT_ID, $FHT_Variable, $IPS_SELF, $FHZ_ID)
	{
	if(FHZ_GetFreeBuffer($FHZ_ID)<10) //Signal wurde noch nicht empfangen
	   {
		echo "Stunde wurde noch nicht abgerufen - warte weiter 
";
      echo "gesendete Stunde: ".substr(GetValue($FHT_Variable),-2)."
";
		echo "aktuelle Stunde: ".intval(date('H'))."
";
		IPS_SetScriptTimer ($IPS_SELF,60); //in einer Minute erneut prüfen
		return;
		}
	ELSE //Stunden-Signal wurde abgerufen
		{
		//Wurde die Stunde rechzeitig abgerufen (Stundenwechsel)?
		if(substr(GetValue($FHT_Variable),-2)==intval(date('H')))
			{
			echo "akutelle Stunde wurde erfolgreich übertragen! 
 Script-Timer wird gelöscht. 
";
         echo "übertragene Stunde: ".substr(GetValue($FHT_Variable),-2)."
";
			echo "aktuelle Stunde: ".intval(date('H'))."
";
			IPS_SetScriptTimer ($IPS_SELF,0);  //Vorgang beendet - Script-Timer löschen
      	SetValue($FHT_Variable,"gesendet");
      	return;
			}
		ELSE
		   {
         echo "Stunde wurde zu spät übertragen! 
 neuer Versuch! 
";
         echo "übertragene Stunde: ".substr(GetValue($FHT_Variable),-2)."
";
			echo "aktuelle Stunde: ".intval(date('H'))."
";
			IPS_SetScriptTimer ($IPS_SELF,60);  
      	SetValue($FHT_Variable,"Minute gesendet");
      	return;
			}
		}
		
	}

?>

PS: Der erste Schritt des Scripts nach dem Start beginnt etwa im oberen Drittel" //Uhrzeit prüfen - …". (Leider konnte ich die Funktionen nicht ganz in der logischen Abfolge halten…)

Viele Grüße, Euer douglas882

Hallo,

teste das gerade. Vielen Dank schonmal für das Skript!

Zwei Kleinigkeiten bislang: In der Zeile

        IPS_SetScriptTimer ($IPS_SELF,60); /In einer Minute erneut prüfen 

fehlt ein /.

Außerdem wäre es noch sinnvoll, wenn man die ID der FHZ mittels Konstante weiter oben festlegen könnte, das erspart einem das Suchen und ersetzen :slight_smile:

Hallo douglas882, hallo Forum,

ich versuche mich auch gerade an dem script. Ich nutze 2.1 und weiß nicht, was Du mit „ID der Status-Variable des Ventilantriebs der FHT“ meinst. Ich habe überhaupt gar keine Statusvariable für den Ventilantrieb. Bislang war ich auch immer der Meinung, dass diese gar nicht mit der FHZ kommunizieren. Wozu braucht Dein script die Statusvariable eines Stellantriebes und wo finde ich die?

Danke.

Meine IP-Symcon Verwaltungskonsole sieht so aus, wie im Anhang.

Sorry, war lange nicht mehr hier - und jetzt so spät in der Nacht…

Die Variable heißt bei dir einfach „Position“. Der Wert dieser Variable wird nicht verwendet, sondern nur der Zeitpunkt ihrer letzten Aktualisierung (alle 2 Minuten). Daraus lässt sich berechnen, wann die FHT das nächste Mal bereit ist, Daten zu empfangen.

@sokkederheld: Das mit der FHZ-ID hatte ich total übersehen und damit wohl auch im ersten Beitrag falsch geschrieben. Hier muß tatsächlich jeder die „31040“ im Script gegen die eigene ID der FHZ austauschen - sorry dafür! :o
Ich werde das bei nächster Gelegenheit gemäß Deinem Vorschlag umsetzen, muß jetzt aber ins Bett!

MfG, douglas882

Ach was solls: Ich habs doch gleich gemacht. Die Änderung habe ich im ersten Beitrag direkt übernommen.
Also falls jemand das Script bereits im Einsatz hat und den Fehler noch nicht bemerkt hat: Bitte im gesamten Script die 31040 gegen die eigene ID ersetzen (vier mal insgesamt).
Ansonsten ist in der oben geposteten Version dieser Bug jetzt behoben…

Gute N8, douglas882

Danke,
funktioniert alles. Lediglich in Zeile 150 musste ich die FHZ-ID-Variable gegen den „ID-Wert“ 17842 tauschen. Mit Variable habe ich immer eine Fehlermeldung bekommen. Vielleicht stimmt da ja noch etwas nicht.
Trotzdem vielen Dank.
poronneb

Ok, das war eigentlich klar: Die Variable $FHZ_ID muß auch an die Funktion übergeben werden, damit sie da drin verwendet werden kann. Ich habe das in Zeile 35 und 150 behoben. (Die Zeilen können sich beim Kopieren etwas verschieben).
@poronneb: Deine Variante geht natürlich auch (ID unten eintragen).

MfG, douglas882

Hier noch eine kleine Ergänzung, mit der man das Aufsuchen der IDs der einzelnen Objekte flexibler gestalten kann:

Das FHZ1x00PC Modul:

$FHZ_ID = IPS_GetObjectIDByName("FHZ1X00PC", 0); //ID des FHZ1300 Moduls

Ich habe meine FHT_80Bs in einer Kategorie names „Heizung“ stehen.

$heizungID = IPS_GetObjectIDByName("Heizung", 0); // ID der Heizungsgruppe

Dann folgt für jeden FHT_80b der Raumname, die notwendige Stringvariable heisst „FHT_Time“ und die Ventilvariable (normalerweise als „Position“ benannt) heisst „Ventil“. Dies muss gegebenenfalls in euren Skripten angepasst werden.

$heizungID = IPS_GetObjectIDByName("Heizung", 0); // ID der Heizungsgruppe
$FHT_Raum1ID = IPS_GetObjectIDByName("Eingangsbereich", $heizungID); // ID des Raumes
$FHT_Raum1_TimeID = IPS_GetObjectIDByName("FHT_Time", $FHT_Raum1ID); // ID der Stringvariable
$FHT_Raum1_VentilID = IPS_GetObjectIDByName("Ventil", $FHT_Raum1ID); // ID des Ventils
$FHT_Raum2ID = IPS_GetObjectIDByName("Arbeitszimmer", $heizungID); // ID des Raumes
$FHT_Raum2_TimeID = IPS_GetObjectIDByName("FHT_Time", $FHT_Raum2ID); // ID der Stringvariable
$FHT_Raum2_VentilID = IPS_GetObjectIDByName("Ventil", $FHT_Raum2ID); // ID des Ventils
$FHT_Raum3ID = IPS_GetObjectIDByName("Wohnzimmer", $heizungID); // ID des Raumes
$FHT_Raum3_TimeID = IPS_GetObjectIDByName("FHT_Time", $FHT_Raum3ID); // ID der Stringvariable
$FHT_Raum3_VentilID = IPS_GetObjectIDByName("Ventil", $FHT_Raum3ID); // ID des Ventils
$FHT_Raum4ID = IPS_GetObjectIDByName("Bad", $heizungID); // ID des Raumes
$FHT_Raum4_TimeID = IPS_GetObjectIDByName("FHT_Time", $FHT_Raum4ID); // ID der Stringvariable
$FHT_Raum4_VentilID = IPS_GetObjectIDByName("Ventil", $FHT_Raum4ID); // ID des Ventils
$FHT_Raum5ID = IPS_GetObjectIDByName("WC", $heizungID); // ID des Raumes
$FHT_Raum5_TimeID = IPS_GetObjectIDByName("FHT_Time", $FHT_Raum5ID); // ID der Stringvariable
$FHT_Raum5_VentilID = IPS_GetObjectIDByName("Ventil", $FHT_Raum5ID); // ID des Ventils

Daraus wird dann die FHT_Liste hergestellt.

$FHT_Liste[]=array($FHT_Raum1ID /*[erste_FHT_ID]*/,$FHT_Raum1_TimeID /*[erste_String_Variable]*/,$FHT_Raum1_VentilID /*[erste_FHT_Ventil_ID]*/); // Eingangsbereich
$FHT_Liste[]=array($FHT_Raum2ID /*[zweite_FHT_ID]*/,$FHT_Raum2_TimeID/*[zweite_String_Variable]*/,$FHT_Raum2_VentilID /*[zweite_FHT_Ventil_ID]*/); // Arbeitszimmer
$FHT_Liste[]=array($FHT_Raum3ID /*[dritte_FHT_ID]*/,$FHT_Raum3_TimeID /*[dritte_String_Variable]*/,$FHT_Raum3_VentilID /*[dritte_FHT_Ventil_ID]*/); // Wohnzimmer
$FHT_Liste[]=array($FHT_Raum4ID /*[dritte_FHT_ID]*/,$FHT_Raum4_TimeID /*[dritte_String_Variable]*/,$FHT_Raum4_VentilID /*[dritte_FHT_Ventil_ID]*/); // Bad
$FHT_Liste[]=array($FHT_Raum5ID /*[dritte_FHT_ID]*/,$FHT_Raum5_TimeID /*[dritte_String_Variable]*/,$FHT_Raum5_VentilID /*[dritte_FHT_Ventil_ID]*/); //WC

Cheers,

Andreas

Hallo,

erstmal vielen Dank für das nützliche Skript.
Ich habe ein paar Änderungen vorgenommen, so dass das Skript nun vollautomatisch ohne Anpassungen laufen sollte.
Einfach nur ein Skript anlegen, den Inhalt von unten hineinkopieren und ausführen.

An Hand der GUID’s sucht es sich nun ALLE FHT-Instanzen (egal in welcher Kategorie diese liegen) und ermittelt die Variable der Ventilposition (es macht auch nichts, wenn diese umbenannt wurde).
Dann legt es für jede FHT eine (versteckte) Variable „TimeSync“ an.

Sobald man das Skript startet, läuft es so lange bis alle FHTs synchronisiert wurden.

Wenn man z.B. jeden Monat alle FHTs einmal synchronisieren möchte, muss man nur noch einen Timer anlegen, der das Skript einmal im Monat startet.

<?

$FHZ_ID = IPS_GetObjectIDByName("FHZ1X00PC", 0); //ID des FHZ1300 Moduls
$Sende_Interval_Ventilpos=115;
$Signal_vor_Sendezeit=11;
$FHT_Liste=FHTCreateList();

// Zähler für FHTs, die bereits synchronisiert wurden
$count = CreateVariableByName($IPS_SELF, "Count", 1);
echo "FHT: ".(GetValue($count)+1)." von ".sizeof($FHT_Liste)."
";


//FHT mit dem ältesten Update suchen
$aeltester_Wert=9999999999999;
$weitersuchen=TRUE;
foreach($FHT_Liste as $FHT_Daten)
    {
    $v=IPS_GetVariable($FHT_Daten['1']);
    $letztes_Update=$v['VariableUpdated'];
    if((($letztes_Update<$aeltester_Wert) OR (GetValue($FHT_Daten['1'])<>"gesendet")) AND $weitersuchen==TRUE)
       {
        $aeltester_Wert=$letztes_Update;
        if(GetValue($FHT_Daten['1'])<>"gesendet") $weitersuchen=FALSE; //Falls diese FHT bereits in bearbeitung ist, nicht weitersuchen
        $FHT_ID=$FHT_Daten['0'];
        $FHT_Variable=$FHT_Daten['1'];
        $FHT_Ventil_Variable=$FHT_Daten['2'];
        }
    }

echo $FHT_ID." 
".$FHT_Variable." 
".$FHT_Ventil_Variable." 
".$weitersuchen." 
";


//Stunde wurde gesendet - Jetzt prüfen
if(substr((GetValue($FHT_Variable)),0,12)=="sende Stunde")
    {
    $result = Stunde_pruefen($FHT_ID, $FHT_Variable, $IPS_SELF, $FHZ_ID);
    if ($result)                 // Wenn Stunde erfolgreich ünertragen, Timer setzten für nächste FHT
    {
   	if (GetValue($count) < sizeof($FHT_Liste)-1)
   	{
			IPS_SetScriptTimer($IPS_SELF, 10);
			SetValue($count, GetValue($count) + 1);
		} else                     //Wenn alle FHT synchronisiert wurde, Timer ausschlten
			{
	   		SetValue($count, 0);
				IPS_SetScriptTimer($IPS_SELF, 0);
				echo "Alle FHTs synchronisiert
";
			}
    }
    return;
    }


//Uhrzeit prüfen - zum Stundenwechsel könnte es zur Verschiebung kommen
if(date('i')>50)
    {
    echo "ungünstige Zeit (Stundenwechsel) - warten...";
    IPS_SetScriptTimer ($IPS_SELF,300);
    return;
    }
if(date('i')<5)
    {
    echo "ungünstige Zeit (Stundenwechsel) - warten...";
    IPS_SetScriptTimer ($IPS_SELF,120);
    return;
    }


//Buffer der FHZ prüfen - freier Buffer ist zur Empfangskontrolle erforderlich
$Freie_Buffer=FHZ_GetFreeBuffer($FHZ_ID);
if($Freie_Buffer<10)
    {
    echo "Buffer belegt... 2 Minuten warten";
   IPS_SetScriptTimer ($IPS_SELF,120); //nächster Versuch in 2 Minuten (auf Buffer warten)
    return;
    }

//------------------   Was soll getan werden?   --------------------
//Minute wurde gesendet - Jetzt Stunde senden
if(GetValue($FHT_Variable)=="Minute gesendet")
    {
    Stunde_senden($FHT_ID, $FHT_Variable, $IPS_SELF);
    return;
    }


//----------------- Minute senden  ----------------------------------
//letzten und nächsten Timeport / Sendeplatz ermitteln
$v=IPS_GetVariable($FHT_Ventil_Variable);
$letzter_Timeport_Zeit=$v['VariableUpdated'];
$letzter_Timeport=intval(time()-$letzter_Timeport_Zeit);
echo "letzter Empfang: ".$letzter_Timeport." s 
";
if($letzter_Timeport>$Sende_Interval_Ventilpos)
    {
    echo "letzte Ventilposition nicht empfangen - nächster Versuch in 1,5 Minuten!";
   IPS_SetScriptTimer ($IPS_SELF,90); //nächster Versuch in 2 Minuten (Warte auf Empfang der Ventilposition)
    return;
    }
$Empfang_in=$Sende_Interval_Ventilpos-$letzter_Timeport;
echo "nächster Timeport: ".$Empfang_in." s 
";
$Sende_in=$Empfang_in-$Signal_vor_Sendezeit;
if ($Sende_in < -1)  //Sendeplatz überspringen (Signal_vor_Sendzeit um mehr als eine Sekunde unterschritten)
    {
    $Sende_in=$Sende_in+$Sende_Interval_Ventilpos;
    }
echo "Sende in ".$Sende_in." s 
";


//Signal senden oder Script beim nächsten Timeport neu starten
if ($Sende_in < 13) //Timeport getroffen - Signal senden
    {
    echo "Timeport getroffen - jetzt senden! 
 ";
   IPS_SetScriptTimer ($IPS_SELF, 0);
    $sende_Minute=date('i',time()+$Empfang_in); //aktuelle Minute zum voraussichtlichen Zeitpunkt des Empfangs
    SetValue($FHT_Variable,"sende m=".$sende_Minute);
   FHT_SetMinute($FHT_ID,intval($sende_Minute));
   IPS_SetScriptTimer ($IPS_SELF,0);  //zunächst löschen um neuen Programmstart während Empfangstest zu vermeiden
    $Empfangstest=TRUE; //nächsten Programmteil starten
    }
    ELSE //warten auf nächsten Timeport
    {
    echo "Setze Script-Timer auf ".$Sende_in." s 
";
    IPS_SetScriptTimer ($IPS_SELF, $Sende_in);
    SetValue($FHT_Variable,"sende in ".$Sende_in."s");
   $Empfangstest=FALSE; //nächsten Programmteil nicht starten
    }
//------------------------------ Empfangstest für Minutensignal ------------------------------
if ($Empfangstest==TRUE)
    {
    IPS_Sleep(1000); //warten bis Signal im Buffer ist
    $Durchlauf=0;
    while((FHZ_GetFreeBuffer($FHZ_ID)<10) AND ($Durchlauf<20))
       {
        $Durchlauf=$Durchlauf+1;
        //echo "Buffer geprüft - Signal wartet 
";
        IPS_Sleep(1000);
        }
    if(FHZ_GetFreeBuffer($FHZ_ID)==10)
       {
        echo "Signal wurde nach ".$Durchlauf." Sekunden abgerufen! 
";
        SetValue($FHT_Variable,"Minute gesendet");
      IPS_SetScriptTimer ($IPS_SELF,60);  //erneut starten um Übertragung der Stunde zu starten
        }
        ELSE //Signal wurde nicht abgerufen
        {
      echo "Fehler - Signal wurde nach 20 Sek nicht abgerufen! 
";
        SetValue($FHT_Variable,"Fehler!");
      IPS_SetScriptTimer ($IPS_SELF,120); //nächster Versuch in 2 Minuten (neues Signal senden)
        }
    }


//---------------------------- ab hier Definition der Funktionen zur Stundenübertragung -------------

function Stunde_senden($FHT_ID, $FHT_Variable, $IPS_SELF)
    {
    $akt_Stunde=date('H');
    SetValue($FHT_Variable,"sende Stunde ".$akt_Stunde);
    echo "Sende Stunde ".$akt_Stunde." 
";
    FHT_SetHour($FHT_ID,intval($akt_Stunde));
    IPS_SetScriptTimer ($IPS_SELF,60);  //erneut starten um Empfang der Stunde zu prüfen
    }

function Stunde_pruefen($FHT_ID, $FHT_Variable, $IPS_SELF, $FHZ_ID)
    {
    if(FHZ_GetFreeBuffer($FHZ_ID)<10) //Signal wurde noch nicht empfangen
       {
        echo "Stunde wurde noch nicht abgerufen - warte weiter 
";
      echo "gesendete Stunde: ".substr(GetValue($FHT_Variable),-2)."
";
        echo "aktuelle Stunde: ".intval(date('H'))."
";
        IPS_SetScriptTimer ($IPS_SELF,60); //in einer Minute erneut prüfen
        return;
        }
    ELSE //Stunden-Signal wurde abgerufen
        {
        //Wurde die Stunde rechzeitig abgerufen (Stundenwechsel)?
        if(substr(GetValue($FHT_Variable),-2)==intval(date('H')))
            {
            echo "akutelle Stunde wurde erfolgreich übertragen! 
 Script-Timer wird gelöscht. 
";
         echo "übertragene Stunde: ".substr(GetValue($FHT_Variable),-2)."
";
            echo "aktuelle Stunde: ".intval(date('H'))."
";
            IPS_SetScriptTimer ($IPS_SELF,0);  //Vorgang beendet - Script-Timer löschen
          SetValue($FHT_Variable,"gesendet");
          return true;
            }
        ELSE
           {
         echo "Stunde wurde zu spät übertragen! 
 neuer Versuch! 
";
         echo "übertragene Stunde: ".substr(GetValue($FHT_Variable),-2)."
";
            echo "aktuelle Stunde: ".intval(date('H'))."
";
            IPS_SetScriptTimer ($IPS_SELF,60);
          SetValue($FHT_Variable,"Minute gesendet");
          return false;
            }
        }

    }



function FHTCreateList()
{
$guid = '{A89F8DFA-A439-4BF1-B7CB-43D047208DDD}';  //FHT GUID
$ids = IPS_GetInstanceListByModuleID($guid);
 foreach($ids as $id)
 {
 //FHT-Daten in Array ablegen: FHT-ID, FHT-Zeitabgleich-Variable, FHT-Ventil-Variable
   $FHT_Liste[]=array($id, CreateVariableByName($id, "TimeSync", 3), IPS_GetStatusVariableID($id, "PositionVar"));
  }
  return $FHT_Liste;
}


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, "this variable was created by script #$IPS_SELF");
        IPS_SetHidden($vid, true);
    }
    return $vid;
}

?>

Funktioniert einwandfrei. Danke :slight_smile:

Funktioniert bei mir auch einwandfrei - danke…
Gruß Matthias:)

hi funktioniert super :slight_smile:

Gute Arbeit Hirschbrat! Ich habe gleich mal einen Vermerk in meinem ersten Beitrag eingefügt.

MfG, douglas882

ich hab mir das Script gestern Abend mal eingebaut, bekomme aber jedesmal die Meldung
> Buffer belegt… 2 Minuten warten

oder auch ab und zu

>ungünstige Zeit (Stundenwechsel) - warten…

Muß ich nur mehr Geduld haben oder läuft da was Schief?
Wie lange darf es dauern bis ich nervös werden darf?

Ansgar

Wenn keine Fehler vorhanden sind und der Funkverkehr deines FS20-Netzes gering ist so sollte das Skript innerhalb weniger Stunden durch sein.

Bei Tests hat es schon mal 6 Stunden gedauert bis alle FHT´s erreicht wurden.

Kannst Du dir nebenbei mal die TimeSync-Variablen der FHT´s mal anschauen dort sollte schon mal was drin stehen wenn das Skript sauber arbeitet. Auch die Count-Variable unter dem Sync-Skript sollte Stück für Stück hochzählen wenn es in Betrieb ist, je gesynchten FHT zählt es um eins hoch.

  1. Buffer belegt… 2 Minuten warten
    Bedeutet, dass noch ein Befehl in der FHZ gespeichert ist, der noch nicht von einer FHT abgeholt wurde.
    Sollte dies immer auftreten (vlt. wenn eine FHT Empfangsprobleme hat), würde ich die FHZ mal für einige Zeit vom USB Anschluss nehmen, in der Hoffnung dass dann der Puffer gelöscht wird.

  2. ungünstige Zeit (Stundenwechsel) - warten…
    Das passiert jede Stunde einmal (10 min vor bis 5 min nach Stundenwechsel) um Problemen beim Stundenwechsel aus dem Weg zu gehen.

Die Meldungen sollten dich also nicht beunruhigen

Bei Tests hat es schon mal 6 Stunden gedauert bis alle FHT´s erreicht wurden.

wieviele Hundert hast Du denn. :rolleyes:

Bei mir laufen 4 Stück, 15 min dann ist alles passiert. Ich lass das jetzt jeden ersten im Monat um 01:10.00 laufen, damit sollte das passen. :slight_smile:

Also 1 FHT bei mir hat mit der Betondecke zwischendrin echt Stress…

Ich schaue mal ob ich meine FHZ nicht mal an die Fritzbox packe und damit dieses Problem eliminieren kann…

Aktuell braucht das Script auch seine Zeit…

Gruss
B71

Hallo Rainer,

eigentlich nur 5 Stück aber wenn halt einer schwer erreichbar ist dann steht das Skript bis er erreichbar ist.

Der zweite Durchlauf dauert nur 45 Minuten:D

Ich hab den IPS Server mal neu gestartet, leider mit dem gleichen Ergebnis. Die FHZ hatte ich vorher auch schon mal für 3 Minuten abgezogen.

Im LOG steht folgendes:

----cut----------
31.08.2010 19:48:20.01 | 18623 | DEBUG | ExecuteThreadID #5 | Skriptausführung: 18623.ips.php ~ Absender: Ereignis #46760, Zeit Ereignis
31.08.2010 19:48:20.08 | 18623 | MESSAGE | ExecuteThreadID #5 | [Keller\FHT Zeit setzen] = FHT: 1 von 4
19603
38351
44867

Buffer belegt… 2 Minuten warten
31.08.2010 19:48:20.08 | 18623 | DEBUG | ExecuteThreadID #5 | Ausgeführt, Resultat: 1, Erfolgreich: True, Zeit: 7 ms
-----------cut-------------

Die ID´s die dort angezeigt werden sind vom FHT im Wohnzimmer, und zwar Instanz, Timesync und Ventilposition.

In diesem Zyklus geht es alle zwei Minuten weiter. Nur einmal nach dem Neustart hatte ich eine andere Fehlermeldung:

--------------cut---------

31.08.2010 19:38:50.01 | 18623 | DEBUG | ExecuteThreadID #1 | Skriptausführung: 18623.ips.php ~ Absender: Ereignis #46760, Zeit Ereignis
31.08.2010 19:38:50.29 | 18623 | MESSAGE | ExecuteThreadID #1 | [Keller\FHT Zeit setzen] = FHT: 1 von 4
19603
38351
44867

letzter Empfang: 162 s
letzte Ventilposition nicht empfangen - nächster Versuch in 1,5 Minuten!
31.08.2010 19:38:50.29 | 18623 | DEBUG | ExecuteThreadID #1 | Ausgeführt, Resultat: 1, Erfolgreich: True, Zeit: 28 ms
-----cut------

So viel FS20 Geräte haben wir nicht, das es funkmäßig überlastet wäre. Wobei die Schaltsicherheit schon ziemlich schlecht ist, ich werde die ganzen kritischen und WAF-abhängigen Geräte wohl nach und nach gegen HM´s tauschen.

Aber erst muß ich die Heizung in den Griff kriegen, so langsam wirds kalt draussen :wink:

Ansgar