[HM] Funk-Handsender

Die kleinen Funk-Handsender für die HomeMatic als Schlüsselanhänger sind
sehr gut geeignet um bestimmte Szenarien zu aktivieren, wenn man sich nicht im Haus befindet (Auto, Garten).
So kann z.B. beim Kommen oder Verlassen der Wohnung das Licht, Heizung, Rollläden auf den gewünschte Stellung gebracht werden.
Da ein kurzer und langer Tastendruck ausgewertet werden kann, sind mit einem
4-fach Handsender 8 Szenarien aktivierbar.
Das folgende Skript zeigt die Steuerung einer Außenbeleuchtung.
Getriggert wird das Skript jeweils bei „Aktualisierung“ von SHORT und LONG

$id_aktor = 22971 /*[Hof Garten\Flutlicht]*/;

if ($IPS_VARIABLE == 22603 /*[Hof Garten\FB4f 1\PRESS_SHORT]*/) { // SHORT
	HM_WriteValueBoolean($id_aktor, "STATE" , False);
	// Befehle für weitere Geräte
}
if ($IPS_VARIABLE == 17289 /*[Hof Garten\FB4f 1\PRESS_LONG]*/) { // LONG
	HM_WriteValueBoolean($id_aktor, "STATE" , True);
	// Befehle für weitere Geräte
}

Das zweite Skript zeit wie man bis zu 8 Geräte schalten kann:

$id_aktor = 22971 /*[Hof Garten\Flutlicht]*/;
$id_status = 52432 /*[Hof Garten\Flutlicht\STATE]*/;
$status = GetValue($id_status);
$id_done = 40682 /*[ ZBV ]*/;  // nur notwendig für eine Fehlermeldung
// z.B. "Kommunikation gestört"

if ($IPS_VARIABLE == 22603 /*[Hof Garten\FB4f 1\PRESS_SHORT]*/) { // SHORT
	$err = HM_WriteValueBoolean($id_aktor, "STATE" , !$status);
	if ($err === False){
   	    SetValue($id_done, False);
	} else {
  	   SetValue($id_done, True);
	}
	// Platz für weitere Befehle
}
if ($IPS_VARIABLE == 17289 /*[Hof Garten\FB4f 1\PRESS_LONG]*/) { // LONG
	// hier kommen das nächste Gerät hin
}

MST

hm_press_l_s_tree.png

Servus. Habe seit heute eine 12 Kanal Fernbedienung. Aber ich bekomme nur bei einem Tastendruck (kurz oder lang) die Variable „Install_Test“ angezeigt. Bei dieser Variable wird dann immer die Zeit aktualisiert.

Wie bekomme ich denn SHORT und LONG ins IPS?

Habs gerade im Forum gefunden. Meine Posts hier könne also gelöscht werden

Wie kann man den Fehler „Kommunikation gestört“ in IPS erkennen?

Das macht IPS nicht eigenständig, aber über ein Scipt lasse ich mir dazu die entsprechenden Variablen anlegen. Einmal angelegt, wird das Script zyklisch ausgeführt(bei mir alle 2 Stunden) und die Variablen gesetzt:

<?
/*
*******************************************************************************************
Auslesen der Erreichbarkeit von HM-Instanzen - Erstellen, Löschen, Umbenennen der Variablen
*******************************************************************************************
File     :  HM-CCU abfragen der Erreichbarkeit
Trigger  :  zyklisch
Interval :  stündlich
*/

$ccu = HM_GetHost(ID von CCU-Clientsocket);     // IP der Homematic-CCU über Clientsocket-ID abfragen
$function = 2;                                     // Funktion 2 = Abfrage der Erreichbarkeit

$suname = "Kommunikation";                       // Variablenname für STICKY-UNREACH
$sualtname = "Kommunikation";                 // Alternativer Variablenname für STICKY-UNREACH (beim UMBENENNEN)

$create = 1;                                       // ERSTELLEN [Variable 1=Anlegen(Beibehalten) / 0=Löschen]
$rename = 0;                                       // UMBENENNEN [1=JA / 0=NEIN]


if (!$create)  $rename = 0;                        // Wenn Löschen, dann nicht gleichzeitig Umbenennen


// *******************************CCU abfragen - BEGINN**********************************
function GetDeviceStatus($ccu, $function, $devices, &$status)
{
$singleresult = false;

    // Check if $devices is an array or not
    if (is_string($devices))
    {
       $singleresult = true;
        $devicelist = array($devices);
    }
    else
    {
       $devicelist = $devices;
    }

    // Prepare array for status values
    $status = array_flip($devicelist);

    // Build request for CCU
    $request = "";
    foreach($devicelist as $serial)
    {
       if ($function == 1)
       {
            $request .= "var $serial = dom.GetObject('BidCos-RF.$serial:0.LOWBAT').Value();
";
        }
        else
        {
            $request .= "var $serial = dom.GetObject('BidCos-RF.$serial:0.STICKY_UNREACH').State();
";
        }
    }

    // Open socket for CCU-connection
    $fp = fsockopen ($ccu, 8181, $errno, $errstr, 2);
    if (!$fp)
    {
        $status = $errno . "|" . $errstr;
        return false;
    }

    // Sending request to CCU
    stream_set_blocking($fp, 1); // sicher gehen, dass der stream im non blocking Mode arbeitet
    $st = "POST /tclrega.exe HTTP/1.1
Content-type: application/x-www-form-urlencoded
" .
            "Content-Length: " . strlen($request) . "
Connection: Close

";
    fputs($fp, $st . $request);

    // Receiving result from CCU
    $t = "";
    $start = false;
    while (!feof($fp))
    {
        $st = fgets($fp);
        if ($start) $t .= $st;
        if ($st == "
") $start = true;
    }
    fclose($fp);

    // Convert result to XML
    $xml = new SimpleXMLElement($t);

    // Walk through each key and copy status infos to result-array
   foreach($xml as $key => $value)
    {
       if (array_key_exists($key, $status)) $status[$key] = (strtolower((string)$value) == "true");
    }
    if ($singleresult) $status = $status[$devices];
   return true;
}
// *******************************CCU abfragen - ENDE**********************************



$alleInstanzen = IPS_GetInstanceListByModuleType(3); 					// alle I/O Instanzen suchen

// Array ausgeben
foreach($alleInstanzen AS $id)
   {
   $instanz = IPS_GetInstance($id);
	$instanz = $instanz['ModuleInfo'];
	$instanz = $instanz['ModuleName'];
		if ($instanz == "HomeMatic Device")                            // Vergleich ob das Array den Instanz-Name ausgibt
		{
			if ($create)
			{
			$adresse = HM_GetAddress($id);            						// HM-Seriennummer ermitteln
			$devices = substr($adresse,0,10);     								// HM-Seriennummer ohne Sub-Adresse(:xx)
				if ( (@!IPS_GetVariableIDByName($suname, $id) ) > 0)     // Überprüfen ob Variable schon existiert, Ergebnis = NEIN
				{
				$newid = IPS_CreateVariable(0);        						// Variable anlegen
				IPS_SetVariableCustomProfile ($newid, $suname); // Variablenprofil einstellen
				IPS_SetName($newid, $suname);                           // Name für Variable schreiben
				IPS_SetParent($newid, $id);                              // Unter Parent-ID verschieben
				GetDeviceStatus($ccu, $function, $devices, &$status);    // Funktion - Abfrage der CCU
				SetValueBoolean($newid, $status);                        // Wert in Variable schreiben
				}
				else
				{
				$newid = IPS_GetVariableIDByName($suname, $id);         // Überprüfen ob Variable schon existiert, Ergebnis = JA
					if ($rename)
					{
				   IPS_SetName($newid, $sualtname);                         // Name für Variable neu schreiben
				   }
				   else
					{
					GetDeviceStatus($ccu, $function, $devices, &$status);    // Funktion - Abfrage der CCU
					SetValueBoolean($newid, $status);                        // Wert in Variable schreiben
					}
				}
			}
			else
			{
			$newid = IPS_GetVariableIDByName($suname, $id);         // Überprüfen ob Variable existiert, Ergebnis = JA
			IPS_DeleteVariable($newid);                              // Variablen ($lbname) löschen
			}
		 //echo "ID: $id    S-NR: $adresse   Erreichbarkeit(1=gestört): $status"."
";         			// Instanzen kontrollieren
		 //echo "$devices ID:$id  $varloc"."
";
		}
	}
?>

Hallo Nancilla,

danke für die schnelle Komplettlösung!
Ich bekomme folgenden Error:

Warning: Profil mit Namen „Erreichbarkeit“ existiert nicht in C:\IP-Symcon\scripts\17388.ips.php on line 114

Was genau macht das Script?
Ich dachte eigentlich nur daran, dass ich eine Info oder Aktion bekomme wenn eine gerade angesteuerte Instanz nicht erreichbar ist.
Z.B.: „Wenn Instanz XY nicht erreichbar, ISDN an Nummer…“

Ich denke das könnte ich mir aus deinem Script herleiten,doch fehlt mir da noch das know how dafür.
Welche Befehle sind dafür notwendig? Bzw. welche Teile deines Skript’s?

Klar!
Weiss, kurzfristig auch nicht, warum der Fehler mit reingeflutscht ist…
Du musst jedenfalls in Zeile 114 „Ereichbarkeit“ mit „$suname“ ersetzen, dann sollte es funktionieren.

Was genau macht das Script?

Es legt unter allen HM-Instanzen eine Variable „Kommunikation“ an, die zyklisch abgefragt werden kann. Einmal angelegt, wird sie nur noch abgefragt und nicht jedesmal neu angelegt.
Die Variable wird aber pro Adresse nur einmal angelegt und nicht für jeden einzelnen Kanal neu generiert, sodass jeder HM-Aktor nur eine Variable der Erreichbarkeit hat und keine 10 für evtl. 10 Kanäle.

Ich dachte eigentlich nur daran, dass ich eine Info oder Aktion bekomme wenn eine gerade angesteuerte Instanz nicht erreichbar ist.

Genau das praktiziere ich… Wenn ein Event eintritt, dann bekomme ich eine email an den Administrator-Account, oder wohin ich will;)
Aber das wäre das nächste Thema!

EDIT/
Habe das Script angepasst. Hoffe es funktioniert nun wie erwartet :rolleyes:

Wow, cooles Skript!
Danke dafür!!!
Läuft 1A.

Das ist echt super delux, man hat eine Vorstellung und bekommt direkt die Absolute Komplettlösung geliefert.


Kennst du dich zufällig mit dem Text to Speech Modul aus?
Ich lasse mich per ISDN über Alarmzustände informieren, doch die Textstimme schmeiß aus den verschiedenen Skripts die Texte immer durcheinander und bricht die Ansage ab obwohl nicht alles erzählt wurde.

MfG

haz.man :slight_smile:

Ich habe leider doch noch ein Problem.
Das Skript wird im 5 Sekundentakt angetiggert.
Probehalber hatte ich mal einen 4Kanal Schaltaktor vom Strom genommen.
Da sollte dann eigentlich die Kommunikations Variable auf false springen.
Macht sie aber nicht.

Dann ist mir noch aufgefallen das doch jeder Kanal bzw. Instanz seine eigene Variable hat. Das sollte doch so auch nicht sein oder?

Ich habe das überarbeitete Skript so übernommen wie es war und nur die ID meiner CCU eingesetzt. Und natürlich den Zyklischen Tigger eingerichtet.

Sollte ich noch weitere Dinge beachten.

Alle 5 Sekunden:eek: …Damit machst du irgendwann die Kommunikation zur CCU selbst kaputt. Das ist eindeutig zu oft.

Probehalber hatte ich mal einen 4Kanal Schaltaktor vom Strom genommen.Da sollte dann eigentlich die Kommunikations Variable auf false springen.
Macht sie aber nicht.

Die CCU fragt ja selbst die Aktoren nur in gewissen Abständen ab, ob sie erreichbar sind und ich weiss nicht, ob da 5 Sekunden ausreichend sind.

Dann ist mir noch aufgefallen das doch jeder Kanal bzw. Instanz seine eigene Variable hat. Das sollte doch so auch nicht sein oder?

Doch, da hast du Recht es wird für jeden Kanal eine Variable angelegt, weil ja auch jeder Kanal eine Instanz darstellt.
Anders, als ich es w.o. geschrieben hatte… Sry! … War schon spät und hatte schon 2(? :o) Helle getrunken :smiley:
Lässt sich aber momentan nicht anderes realisieren. Zumindest habe ich auf die Schnelle keine Idee.
Dann musst du eben nur einen Kanal zur Auswertung händisch heranziehen.
So mache ich das.
Aber alle 5 Sekunden?.. dafür ist das Script nicht ausgelegt!
Das läuft ja bei mir schon 4,3 Sekunden bei einen Durchgang.
Hängt davon ab, wieviele Instanzen abgefragt werden…

Du hattest doch geschrieben das das script bei dir im2 sekunden Takt getiggert wird. Lag das auch an den zwei Hellen? :wink:

Ich es jetzt auf Minutentakt gestellt.
Trotzdem werden Variablen bei Kommunikationsfehler nicht auf false gestellt.
Im WebUI der HM war der Schaltaktor mit Kommunikationsstörung gelistet.

Die Temperaturfühler z.B. sind alle auf Kommunikation false. ???

Irgendwas stimmt da nicht…

Hast du eine Ahnung?

Nö!
Steht im Posting 5 dieses Threads … „zyklisch ausgeführt(bei mir alle 2 Stunden)“:wink:

Da fällt mir noch was wichtiges ein…
Mein erstes Script passte schon, mit der „Erreichbarkeit“, aber das ist natürlich ein eigenes Vraibalenprofil, was ich mal angelegt hatte, welches du natürlich nicht hast. Deshalb kam der Fehler :rolleyes:
So ist das eben, wenn man irgendwann mal ein Script geschrieben hat, was dann nur noch läuft und läuft und man sich nicht mehr weiter damit beschäftigt.

Dazu mal Screenshots, dass du’s einfacher hast. Kannst natürlich dem Profil einen Namen, nach deinem Belieben geben. Muss nur entsprechend mit dem im Script eingetragenen übereinstimmen.
Wahrscheinlich liegts daran.

Jetzt müsstest du die „Kommunikation“-Variablen wieder löschen.
Machst du mit dem Script. Einfach „$create“ auf 0 setzen und dann starten.
Dann Variablen-Profil anlegen. „$create“ wieder auf 1 setzen und Script neu starten.

Also hier dann nochmals das Script:

   <?
/*
*******************************************************************************************
Auslesen der Erreichbarkeit von HM-Instanzen - Erstellen, Löschen, Umbenennen der Variablen
*******************************************************************************************
File     :  HM-CCU abfragen der Erreichbarkeit
Trigger  :  zyklisch
Interval :  stündlich
*/

$ccu = HM_GetHost(ID von CCU-Clientsocket);     // IP der Homematic-CCU über Clientsocket-ID abfragen
$function = 2;                                     // Funktion 2 = Abfrage der Erreichbarkeit

$suname = "Kommunikation";                       // Variablenname für STICKY-UNREACH
$sualtname = "Kommunikation";                 // Alternativer Variablenname für STICKY-UNREACH (beim UMBENENNEN)

$create = 1;                                       // ERSTELLEN [Variable 1=Anlegen(Beibehalten) / 0=Löschen]
$rename = 0;                                       // UMBENENNEN [1=JA / 0=NEIN]


if (!$create)  $rename = 0;                        // Wenn Löschen, dann nicht gleichzeitig Umbenennen


// *******************************CCU abfragen - BEGINN**********************************
function GetDeviceStatus($ccu, $function, $devices, &$status)
{
$singleresult = false;

    // Check if $devices is an array or not
    if (is_string($devices))
    {
       $singleresult = true;
        $devicelist = array($devices);
    }
    else
    {
       $devicelist = $devices;
    }

    // Prepare array for status values
    $status = array_flip($devicelist);

    // Build request for CCU
    $request = "";
    foreach($devicelist as $serial)
    {
       if ($function == 1)
       {
            $request .= "var $serial = dom.GetObject('BidCos-RF.$serial:0.LOWBAT').Value();
";
        }
        else
        {
            $request .= "var $serial = dom.GetObject('BidCos-RF.$serial:0.UNREACH').State();
";
        }
    }

    // Open socket for CCU-connection
    $fp = fsockopen ($ccu, 8181, $errno, $errstr, 2);
    if (!$fp)
    {
        $status = $errno . "|" . $errstr;
        return false;
    }

    // Sending request to CCU
    stream_set_blocking($fp, 1); // sicher gehen, dass der stream im non blocking Mode arbeitet
    $st = "POST /tclrega.exe HTTP/1.1
Content-type: application/x-www-form-urlencoded
" .
            "Content-Length: " . strlen($request) . "
Connection: Close

";
    fputs($fp, $st . $request);

    // Receiving result from CCU
    $t = "";
    $start = false;
    while (!feof($fp))
    {
        $st = fgets($fp);
        if ($start) $t .= $st;
        if ($st == "
") $start = true;
    }
    fclose($fp);

    // Convert result to XML
    $xml = new SimpleXMLElement($t);

    // Walk through each key and copy status infos to result-array
   foreach($xml as $key => $value)
    {
       if (array_key_exists($key, $status)) $status[$key] = (strtolower((string)$value) == "true");
    }
    if ($singleresult) $status = $status[$devices];
   return true;
}
// *******************************CCU abfragen - ENDE**********************************



$alleInstanzen = IPS_GetInstanceListByModuleType(3);                     // alle I/O Instanzen suchen

// Array ausgeben
foreach($alleInstanzen AS $id)
   {
   $instanz = IPS_GetInstance($id);
    $instanz = $instanz['ModuleInfo'];
    $instanz = $instanz['ModuleName'];
        if ($instanz == "HomeMatic Device")                            // Vergleich ob das Array den Instanz-Name ausgibt
        {
            if ($create)
            {
            $adresse = HM_GetAddress($id);                                    // HM-Seriennummer ermitteln
            $devices = substr($adresse,0,10);                                     // HM-Seriennummer ohne Sub-Adresse(:xx)
                if ( (@!IPS_GetVariableIDByName($suname, $id) ) > 0)     // Überprüfen ob Variable schon existiert, Ergebnis = NEIN
                {
                $newid = IPS_CreateVariable(0);                                // Variable anlegen
                IPS_SetVariableCustomProfile ($newid, "Erreichbarkeit"); // Variablenprofil einstellen
                IPS_SetName($newid, $suname);                           // Name für Variable schreiben
                IPS_SetParent($newid, $id);                              // Unter Parent-ID verschieben
                GetDeviceStatus($ccu, $function, $devices, &$status);    // Funktion - Abfrage der CCU
                SetValueBoolean($newid, $status);                        // Wert in Variable schreiben
                }
                else
                {
                $newid = IPS_GetVariableIDByName($suname, $id);         // Überprüfen ob Variable schon existiert, Ergebnis = JA
                    if ($rename)
                    {
                   IPS_SetName($newid, $sualtname);                         // Name für Variable neu schreiben
                   }
                   else
                    {
                    GetDeviceStatus($ccu, $function, $devices, &$status);    // Funktion - Abfrage der CCU
                    SetValueBoolean($newid, $status);                        // Wert in Variable schreiben
                    }
                }
            }
            else
            {
            $newid = IPS_GetVariableIDByName($suname, $id);         // Überprüfen ob Variable existiert, Ergebnis = JA
            IPS_DeleteVariable($newid);                              // Variablen ($lbname) löschen
            }
         //echo "ID: $id    S-NR: $adresse   Erreichbarkeit(1=gestört): $status"."
";                     // Instanzen kontrollieren
         //echo "$devices ID:$id  $varloc"."
";
        }
    }
?> 

EDIT/
Fehler lag an Zeile 53

$request .= "var $serial = dom.GetObject('BidCos-RF.$serial:0.STICKY_UNREACH').State();
";

funktionierte nicht mehr, obwohls einstmal tat.
Habe die Zeile durch:

$request .= "var $serial = dom.GetObject('BidCos-RF.$serial:0.UNREACH').State();
";

ersetzt und durch Provokation überprüft. Sollte nun wieder funktionieren :smiley:

Gut, dass wir mal drüber „geredet“ haben, sonst wäre mir der Fehler in Zukunft auch nicht gemeldet worden, wenn ich nicht auf die WebUI der CCU schaue.

Profil_Erreichbarkeit.JPG

Profil_Erreichbarkeit_2.JPG

Genial!
Jetzt klappt alles.
Ich kann garnicht genug Lob aussprechen!!! :smiley:
Diese Skript ist ein muss für jeden Homematic Besitzer!!!
Echt feine Sache!

Kann man auch den Batteriestatus mit diesem Skript abfragen?

Jepp! Ist schon da… http://www.ip-symcon.de/forum/f53/hm-instanzen-batteriezustand-erstellen-aendern-u-loeschen-variablen-9183/