[HM-Instanzen] Batteriezustand, Erstellen, Ändern u. Löschen der Variablen

Hervorgegangen aus diesem Thread und diesem Thread ist meine Gesamtlösung:

Das Setzen des Batteriezustands in die entsprechenden Boolean-Variablen und falls die Variablen noch nicht existieren, werden sie automatisch mit frei wählbarem Namen angelegt. Zudem besteht die Möglichkeit, die Variablen umzubenennen oder zu löschen.

Achtung! Werden die Variablen gelöscht und danach neu angelegt, haben sich die ID’s geändert!

Beim ersten Durchlauf (wenn die Variablen neu angelegt werden müssen) können einige Sekunden vergehen, bevor alles „an Ort und Stelle ist“:wink:

<?
/*
*******************************************************************************************
Auslesen des Batteriezustands an HM-Instanzen - Erstellen, Löschen, Umbenennen der Variablen
*******************************************************************************************
File     :  
Trigger  :  
Interval :  
*/

$ccu = HM_GetHost(ObjektID von HomeMatic Socket);     // IP der Homematic-CCU abfragen
$function = 1;                                     // Funktion 1 = Abfrage des Batteriezustands

$lbname  = "Batterie";                             // Variablenname für LOW-BATT
$altname = "HM-Batterie";                         	// Alternativer Name der Variable (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($lbname, $id) ) > 0)     // Überprüfen ob Variable schon existiert, Ergebnis = NEIN
				{
				$newid = IPS_CreateVariable(0);        						// Variable anlegen
				IPS_SetVariableCustomProfile ($newid, "~Battery");       // Variablenprofil einstellen
				IPS_SetName($newid, $lbname);                           // 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($lbname, $id);         // Überprüfen ob Variable schon existiert, Ergebnis = JA
					if ($rename)
					{
				   IPS_SetName($newid, $altname);                           // 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($lbname, $id);         // Überprüfen ob Variable existiert, Ergebnis = JA
			IPS_DeleteVariable($newid);                              // Variablen ($lbname) löschen
			}
		
		}
	}
?>

Hallo nancilla,

vielen Dank für das Skript.

Ich habe es übernommen und ausprobiert. Die Variablen für den Batteriestatus wurden noch angelegt, da diese gefehlt haben.

Hat alles und super funktioniert.

Wäre nett, wenn Du noch einen Beitrag mit einem Link zu diesem Script im Homematic-Ordner erstellst.

Das Skript ist absolut hilfreich bei der Anlage der Variablen. IPS legt nicht alle (so wie in der Doku genannt) Variablen automatisch an.

Das Skritp ist absout top, notwendig und Voraussetzung für weitere Entwicklungen und Auswertungen.

Danke für die investierte Zeit. :wink:

Viele Grüße
wesseli

Danke!

Ich habe das selbe Script auch auf die „STICKY-UNREACH“ Funktion abgeändert (Var-Namen etc.) und extra laufen. Mit Absicht habe ich diese Funktion hier nicht mit eingebaut, weil es eigentlich reicht, die „LOW-BATT“-Abfrage 1-2 mal täglich ausführen zu lassen, jedoch die „STICKY-UNREACH“-Abfrage öfters (bei mir momentan stündlich).

hi nancilla,

Frage kann man das Script vielleicht auch so umschreiben, dass es die aktuellen Status von mehren Sensoren (Fenster-Kontakte) ausliest und diese in einer bestimmten Variable speichert.

Gruß

Jay

Hallo Zusammen,

das Script funktioniert bei mir leider nicht. Sobald ich
es ausführe, erscheint dieser Fehler:


Fatal error: Uncaught exception ‚Exception‘ with message ‚String could not be parsed as XML‘ in C:\Programme\IP-Symcon\scripts\47503.ips.php:83
Stack trace:
#0 C:\Programme\IP-Symcon\scripts\47503.ips.php(83): SimpleXMLElement->__construct(’’)
#1 C:\Programme\IP-Symcon\scripts\47503.ips.php(129): GetDeviceStatus(‚192.168.2.2‘, 1, ‚GEQ0233297‘, Array)
#2 {main}
thrown in C:\Programme\IP-Symcon\scripts\47503.ips.php on line 83


Die Geräte SN: GEQ0233297 ist die Homematic Wetterstation (Kombisensor OC3)

Habe IP-Symcon via LAN-Adapter und BidCos-Service laufen.

Kann mir bitte jemand helfen???

Tausend Dank!
Micha

Hi Micha,

das Script ist für den direkten Zugriff über die CCU geschrieben.
Ich gehe davon aus, dass es über den Bidcos-Service und den LAN-Adapter nicht funktioniert.

Mit meiner Konstellation kann ich aber einen Test direkt nur mit LAN-Adapter nicht nachstellen.
Geändert/angepasst werden müsste eigentlich nur…

// *******************************CCU abfragen - BEGINN**********************************
............
// *******************************CCU abfragen - ENDE**********************************

Wenn überhaupt geht mit dem BC-Service… Eventuell kann das jemand anpassen?

Hallo nancilla,

danke für Deine schnelle Antwort.
Ich habe bereits das Script an einigen Stellen angepasst.
Eine Vernindung zum BidCos Service besteht. zumindest bekomme ich hier keine Fehlermeldung.

Ändere ich z.B. den Port im Script, erhalte ich sofort einen Verbindungsfehler.

Es muss also noch was anderes sein. Irgendwie scheint es so, als ob das Script Schreibprobleme mit der XML Datei hat.

Ich schau mir das nochmal an.
Falls zwischenzeitlich irgendjemand eine Lösung in Verbindung mit dem LAN-Adapter hat, würde ich mich über eine kurze Antwort sehr freuen.

Danke und Grüße,
Micha

Hallo Nancilla, (ist das wirklich Dein Name?)
das script schein zu laufen… vielen Dank dafür.
Ich bekomme allerdings Fehlermeldungen mit denen ich nicht so recht was anfangen kann. Vielleicht hast Du hier eine Idee?

array_flip() expects parameter 1 to be array, boolean given in C:\Programme\IP-Symcon\scripts\23508.ips.php on line 41

Warning: Invalid argument supplied for foreach() in C:\Programme\IP-Symcon\scripts\23508.ips.php on line 45

Warning: array_key_exists() expects parameter 2 to be array, null given in C:\Programme\IP-Symcon\scripts\23508.ips.php on line 88

Warning: array_key_exists() expects parameter 2 to be array, null given in C:\Programme\IP-Symcon\scripts\23508.ips.php on line 88

Warning: array_key_exists() expects parameter 2 to be array, null given in C:\Programme\IP-Symcon\scripts\23508.ips.php on line 88

Warning: Variable wurde als „Nur-Lesen“ markiert und kann nicht verändert werden in C:\Programme\IP-Symcon\scripts\23508.ips.php on line 130


#40:     // Prepare array for status values
#41:    $status = array_flip($devicelist);

#45:     foreach($devicelist as $serial)

#88:       if (array_key_exists($key, $status)) $status[$key] = (strtolower((string)$value) == "true");

#130:      SetValueBoolean($newid, $status);                        // Wert in Variable schreiben

Würde mich freuen wenn Du hier weiterhelfen kannst… Wie „gesagt“ das Script scheint zu laufen aber die Fehlermeldungen hätte ich doch gerne weg. Mit fehlt hierzu (noch) das nötige PHP Wissen.

Liebe Grüße aus Handewitt
//Sven

Nö:D ist doch mein Nick.

Tritt der Fehler mit CCU oder LAN-Adapter auf?

Guten Morgen,
der Fehler tiritt in Verbindung mit der CCU auf.

Allen einen Sonnigen Tag :slight_smile:

Hallo Sven,

hast du am Script irgendetwas verändert, außer der ID vom Homematic-CCU-Socket (die eingetragen werden muss)?

Welche IPS-Version nutzt du?

Ich habe jetzt mal die neue Beta probiert.
Weder da, noch mit der Release tritt ein Fehler auf.
Allerdings habe ich noch nachwievor TCPDump auf der CCU…

Hallo,
nö, nix geändert… ausser Zeile11 ($ccu…)
Aktuell Version 2.20
TCPDUMP wird bei mir auch immer noch eingesetzt.

Ich habe mal Testweise

function GetDeviceStatus($ccu, $function, $devices, &$status)
{
$singleresult = false;
	echo $ccu;
	echo ";";
	echo $function;
	echo ";";
	echo $devices;
	echo ";;";

„Eingebaut“.
Dies ergibt dann folgende Ausgabe…

------schnipp---------------
192.168.80.20;1;FEQ00845490
192.168.80.20;1;GEQ00256220
192.168.80.20;1;FEQ00623340
192.168.80.20;1;0
Warning: array_flip() expects parameter 1 to be array, boolean given in C:\Programme\IP-Symcon\scripts\23508.ips.php on line 47

Warning: Invalid argument supplied for foreach() in C:\Programme\IP-Symcon\scripts\23508.ips.php on line 51

Warning: array_key_exists() expects parameter 2 to be array, null given in C:\Programme\IP-Symcon\scripts\23508.ips.php on line 94

Warning: array_key_exists() expects parameter 2 to be array, null given in C:\Programme\IP-Symcon\scripts\23508.ips.php on line 94

Warning: array_key_exists() expects parameter 2 to be array, null given in C:\Programme\IP-Symcon\scripts\23508.ips.php on line 94

192.168.80.20;1;FEQ00623340
192.168.80.20;1;FEQ00623340
192.168.80.20;1;FEQ00623340
192.168.80.20;1;FEQ00623340
------schnipp---------------

Es sieht so aus, als wenn der Fehler auftritt, wenn das Script zu den RS485 Komonenten kommt (FEQ00623340 ist ein HMW-Sen-SC-12-DR).
Ich habe da 14x HMW-Sen-SC-12-DR verbaut. Ich Vermute mal dann man noch irgendwie die Kabelgebundenen Komponenten ausklamern muss…??
Bzw. die Function GetDeviceStatus nur aufrufen darf, wenn es sich um eine BidCos Komponenten handelt.

Danke schon mal…

//Sven

Hallo nochmal,
habe es nun wie folgt gelöst:


-----schnipp--------------
                    if ($devices!='0')
						  	{
							  	GetDeviceStatus($ccu, $function, $devices, &$status);    // Funktion - Abfrage der CCU
-----schnipp--------------

Vielleicht hilfts jemandem der das gleiche Problem hat…

Nachtrag:
Der weitere Fehler:

Warning: Variable wurde als „Nur-Lesen“ markiert und kann nicht verändert werden in C:\Programme\IP-Symcon\scripts\23508.ips.php on line 130

Kommt zustande, wenn man eine (oder mehrere) WinMatic einsetzt…


$lbname  = "Batterie";                             // Variablenname für LOW-BATT

Die Variable Batterie wird seitens WinMatic selbst gesetzt. Hier wird die Prozentuale Batterie Kapazität angegeben.

Einfach:


$lbname  = "Batterie";                             // Variablenname für LOW-BATT

in


$lbname  = "LowBatt";                             // Variablenname für LOW-BATT

ändern und es gibt keine Fehler mehr.

Das vermutete ich schon, weil im Script Bidcos-RF-Instanzen abgefragt werden.

 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();
";
        }
    }

Dieser Abschnitt (Beginn/Ende CCU-Auslesen) stammt aber nicht von mir, sondern wurde nur eingefügt. Siehe meinen ersten Beitrag. Da ich keine drahtgebundenen HM-Komponenten habe, läuft es bei mir tadellos durch.

Eventuell kann man die Abfrage der kabelgebundenen Module ausklammern?
Meine Idee… Abfrage nach „ModuleType“ mit „IPS_GetInstance“.
Dazu müsste ich aber wissen, was bei den Wired-Modulen in der settings.xml als „ModuleType“ eingetragen ist.
Bei mir steht da immer Wert „3“.
Und ich frage mich, ob man so die Typen unterscheiden kann? Ich habe leider nur Funk.

Nee, ich sehe gerade in der Doku, dass „3“ nur den Inhalt „Geräte Instanzen“ ausgibt.
Damit sollte es dann auch nicht gehen… Hat noch jemand eine Idee? Anhand der Module-ID vielleicht?

Der Fehler ist eigentlich nur eine formelle Warnung und kein Fehler.
Kann ebenso ignoriert werden.

Helfen sollte auch ein @ vor der Befehlszeile… also

@SetValueBoolean($newid, $status);                        // Wert in Variable schreiben

Hallo,
versuche auch den Batteriestatus meiner HomeMatic-Geräte auszulesen. Bekomme jedoch beim „Wert in Variable schreiben“ eine Fehlermeldung (Bild1). Im Objektbaum ist auch zu sehen, dass die Werte nicht geschrieben werden und ich denke, dass der Stautus „OK“ nicht der tatsächliche Status ist.

immergut

P.s. Habe keine CCU (nur LAN-Adapter)

Ich schreib’s nochmal:

Dieses Script wurde programmiert zum Auslesen der CCU und funktioniert mit wireless HM-Geräten, die keinen eigenen Batteriestatus an IPS liefern.

Zum Auslesen über den LAN-Adapter müsste dieser Abschnitt überarbeitet werden:

// *******************************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**********************************

Da ich aber eine CCU mit 2 verbundenen LAN-Adaptern einsetze und diese gut funktionierende Konfiguration nicht zerreissen will, habe ich keine Möglichkeit das Script anzupassen bzw. die korrekte Funktion zu verifizieren.

Gerne kann sich jemand daran beteiligen.

ip-symcon aktuelle Version (2.30)
CCU FM 1.503

Hallo bekomme leider folgende Fehlermeldung:

Warning: array_flip() expects parameter 1 to be array, boolean given in C:\Programme\IP-Symcon\scripts\55893.ips.php on line 41

Warning: Invalid argument supplied for foreach() in C:\Programme\IP-Symcon\scripts\55893.ips.php on line 45

Warning: array_key_exists() expects parameter 2 to be array, null given in C:\Programme\IP-Symcon\scripts\55893.ips.php on line 88

Warning: array_key_exists() expects parameter 2 to be array, null given in C:\Programme\IP-Symcon\scripts\55893.ips.php on line 88

Warning: array_key_exists() expects parameter 2 to be array, null given in C:\Programme\IP-Symcon\scripts\55893.ips.php on line 88

Hat einer eine Idee

Mit Einführung des Homematic-Configurator’s in IPS ist dieses Script nur noch als Beispiel zur Funktionsweise zu betrachten… in diesem Sinne OUT und bedarf keinerlei Nachfragen…