Geräte und Kanäle

Moin,

das hinzufügen von Geräten war eigentlich recht einfach. Es werden automatisch die Standardkanäle des Devices genommen und Statusvariablen angelegt.

Wie können jedoch „Trigger“ auf andere Kanäle eines gerätes gesetzt werden?

Beispielsweise hat ein Jalousieaktor: LEVEL und WORKING standardmäßig.

Wie füge ich nun aber STICKY_UNREACH als Datenpunkt hinzu? Die Addresse dafür wäre ja: <DEVICEADR>:0.STICKY_UNREACH

Viele Grüße
Sascha

Oder kann ich irgendwie per PHP-Script auf die Geräte zugreifen mit dem entsprechenden Datapoint zugreifen?

Hi,

ja Du kannst auch direkt die CCU ansprechen:

<?php

function Post_Request ($sdata)
{
 $start=time();
 $fp = fsockopen ("192.168.178.99", 8181, $errno, $errstr, 2);
// $fp = fsockopen ("127.0.0.1", 8181, $errno, $errstr, 30);
 
 if (!$fp) 
     echo "$errstr ($errno)<br />
";
 else 
    {
	stream_set_blocking  ( $fp  , 1 ); // sicher gehen, dass der stream im non blocking Mode arbeitet
		  $st = "POST /tclrega.exe HTTP/1.1
";
		  $st = $st . "Content-type: application/x-www-form-urlencoded
";
		  $st = $st . "Content-Length: ". strlen($sdata) ."
";
		  $st = $st . "Connection: Close

";
		  
      fputs($fp,$st.$sdata); 
      $st = "";
      $t = fgets($fp,500);
      $st = $st . $t . "
";
	  
       while ($t != "
") 
       {
        $t = fgets($fp,500);
       }
      $t = "";

      while (!feof($fp))
        {      
         $t .= fgets($fp,10000);
        }

    fclose($fp);
  }

//  $xml = new SimpleXMLElement($t);
//  return $xml->result; 



ereg("<result>(.*)<\/result>",$t,$result);
//print_r($result);


return $result[1];

}

?>

Für 192.168.178.99 musst Du die IP-Adresse Deiner CCU angeben. Danach erfolgt der Aufruf per:

$befehl="var result = dom.GetObject('BidCos-RF.DEQ0010906:0.STICKY_UNREACH');"
$result=Post_Request ($befehl);

in $result steht dann das Ergebnis. Aber bitte beachten, dass $result immer ein String ist! Du kannst so auch alle Geräte schalten, den Batteriestatus abfragen, Systemvariablen auslesen…

Ich wünsche einen schönen Tag.

Christoph.

IP-Symcon zeigt nur Variablen an, die sich verändern. Sobald die CCU eine Veränderung an einem Datenpunkt sendet, wird diese auch in IP-Symcon angezeigt.

paresy

Hi,

Ja stimmt, wenn IPS aber gerade nicht aktiv ist, dann werden Änderungen beim nächsten IPS Start nicht angezeigt.

Hierfür ist obiges Script geeignet um den Status später noch abfragen zu können. Die dazugehörige IPS Variable muss dann natürlich vom Script entsprechend dem zurückgelieferten Status gesetzt werden.

Ach ja eine kleine Einschränkung habe ich noch. Wenn ständig die Statis abgefragt werden, kann das die CCU lahmlegen. Wer z. B. 120 Geräte pro Minute abfragt und das über Stunden, der wird seine CCU öfter neu starten müssen. Die Funktion muss also vorsichtig benutzt werden. Geräte, die ohnehin ständig Werte liefern sollten von der Abfrage ausgenommen werden.

Ein weiterer Trick um die Abfragen zu minimieren besteht darin, mehrere Geräte gleichzeitig abzufragen. Hierzu müssen die Befehle einfach hintereinander gesetzt werden. Ein Aufruf reicht dann aus. Die Variablen müssen natürlich alle unterschiedlich benannt werden, dann kann man aus dem XML-Ergebnis alle Daten abfragen.

Ich wünsche einen schönen Tag.

Christoph.

Hallo!

Für alle, die mehrere Geräte abfragen wollen hier mal meine Funktion, die aus obigem Script von Christoph entstanden ist. Die Funktion kann Verbindungsstatus oder Batteriestatus abfragen, und zwar mit einer Anfrage für ein oder mehrere Geräte mit nur einer Abfrage der CCU.
Je nach Aufruf liefert die Funktion ein boolean oder ein Array of boolean.

Das Script ist zwar nicht unbedingt optimal geschrieben, aber es funktioniert zuverlässig :slight_smile:


/*******************************************************************************
    Holt div. Statuswerte für einen oder mehrere Aktoren mit einer
    kombinierten Anfrage von der CCU und liefert diese als String/Array
    an den Aufrufer zurück.

    $ccu      = IP- oder Hostadresse der CCU
    $function = 1 (für Batteriewarnung) ODER 2 (für Verbindungsstatus)
    $devices  = string mit Seriennummer (1 Gerät) oder
                    array mit Seriennummern (mehrere Geräte)
    $status   = Resultat(e) der Abfragen. Wenn ein Gerät abgefragt wurde dann
                    ist das Ergebnis ein boolean, welcher den entsprechenden Status
                    wiedergibt. Wenn eine mehrfachabfrage durchgeführt wurde dann
                    ist status ein Hash. Die Keys entsprechen den Geräte-ID's, die
                    Werte sind booleans die den entsprechenden Status signalisieren.
 *******************************************************************************/
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;
}

Hi,

nur zur Richtigstellung: Die Funktion ist von Alex (mehr weiß ich von ihm leider auch nicht). Der Code war bei dem PHP-Server für die CCU dabei.

Ich wünsche einen schönen Tag.

Christoph.

Hallo Thorsten,

ich habe dein Script zur abfrage von „STICKY_UNREACH“ und „LOWBAT“ im Einsatz. Es funktioniert gut. :slight_smile:

Besten Dank dafür.

Bis dann

Martin

PS: Für „STICKY_UNREACH“ habe ich eine Zeile geändert in


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

Ich stell mich gerade biss’l blöd an mit dem Script von Thorsten…

Wie erfolgt da die Abfrage?
Ich habe mal zum Test versucht, den Batteriestatus verschiedener Devices abzufragen. Unteranderem habe ich gerade eine Fernbedienung, die niedrigen Batteriestand meldet, aber egal was, ich bekomme im „True“ (1) als Echo.

$ccu = '192.168.12.60';
$function = 1;
$devices = 'EEQ0005550';

echo GetDeviceStatus($ccu, $function, $devices, &$status);

Hier ist doch sicher etwas falsch:confused:

Hallo nancilla

Das Ergebnis steht in $status!!

So sieht das bei mir aus


$ccu = "192.168.2.100";
$function = 1;
//Ergeschoss
$devices[] = $SNR_UG_Rauchmelder;
$devices[] = $SNR_Fur_UG_Schalter;
$devices[] = $SNR_Wohnen_Fernbedienung;
$devices[] = $SNR_Wohnen_Antrieb_Heizung_links;
$devices[] = $SNR_Wohnen_Antrieb_Heizung_rechts;
$devices[] = $SNR_Wohnen_Fenster_links;
$devices[] = $SNR_Wohnen_Terrassentuer;
$devices[] = $SNR_Wohnen_Thermostat_Set;

//Obergeschoss
$devices[] = $SNR_OG_Rauchmelder;
$devices[] = $SNR_Flur_OG_Schalter;
$devices[] = $SNR_Flur_OG_Schalter_TreppeDG;
$devices[] = $SNR_Buero_Tuer_Schalter;
$devices[] = $SNR_Buero_Fenster_Schalter;
$devices[] = $SNR_Buero_Fenster;
$devices[] = $SNR_Abstellraum_Schalter;
$devices[] = $SNR_Schlafzimmer_Fenster;

//Dachgeschoss
$devices[] = $SNR_DG_Rauchmelder;
$devices[] = $SNR_Dachboden_Schalter;
$devices[] = $SNR_Heizungsraum_Schalter;

GetDeviceStatus($ccu, $function, $devices, &$status);

foreach($status as $key => $value)
{

	Switch($key)
	{
		case $SNR_UG_Rauchmelder:
			SetValue($id_LOWBAT_UG_Rauchmelder, $value);
			break;
		case $SNR_Fur_UG_Schalter:
			SetValue($id_LOWBAT_Fur_UG_Schalter, $value);
			break;
		case $SNR_Wohnen_Fernbedienung:
			SetValue($id_LOWBAT_Wohnen_Fernbedienung, $value);
			break;
		case $SNR_Wohnen_Antrieb_Heizung_links:
			SetValue($id_LOWBAT_Wohnen_Antrieb_Heizung_links, $value);
			break;
		case $SNR_Wohnen_Antrieb_Heizung_rechts:
			SetValue($id_LOWBAT_Wohnen_Antrieb_Heizung_rechts, $value);
			break;
		case $SNR_Wohnen_Fenster_links:
			SetValue($id_LOWBAT_Wohnen_Fenster_links, $value);
			break;
		case $SNR_Wohnen_Terrassentuer:
			SetValue($id_LOWBAT_Wohnen_Terrassentuer, $value);
			break;
		case $SNR_Wohnen_Thermostat_Set:
			SetValue($id_LOWBAT_Wohnen_Thermostat_Set, $value);
			break;
			
		case $SNR_OG_Rauchmelder:
			SetValue($id_LOWBAT_OG_Rauchmelder, $value);
			break;
		case $SNR_Flur_OG_Schalter:
			SetValue($id_LOWBAT_Flur_OG_Schalter, $value);
			break;
		case $SNR_Flur_OG_Schalter_TreppeDG:
			SetValue($id_LOWBAT_Flur_OG_Schalter_TreppeDG, $value);
			break;
		case $SNR_Buero_Tuer_Schalter:
			SetValue($id_LOWBAT_Buero_Tuer_Schalter, $value);
			break;
		case $SNR_Buero_Fenster_Schalter:
			SetValue($id_LOWBAT_Buero_Fenster_Schalter, $value);
			break;
		case $SNR_Buero_Fenster:
			SetValue($id_LOWBAT_Buero_Fenster, $value);
			break;
		case $SNR_Abstellraum_Schalter:
			SetValue($id_LOWBAT_Abstellraum_Schalter, $value);
			break;
		case $SNR_Schlafzimmer_Fenster:
			SetValue($id_LOWBAT_Schlafzimmer_Fenster, $value);
			break;

		case $SNR_DG_Rauchmelder:
			SetValue($id_LOWBAT_DG_Rauchmelder, $value);
			break;
		case $SNR_Dachboden_Schalter:
			SetValue($id_LOWBAT_Dachboden_Schalter, $value);
			break;
		case $SNR_Heizungsraum_Schalter:
			SetValue($id_LOWBAT_Heizungsraum_Schalter, $value);

	}

Bis dann

Martin

Hi Martin!

Seltsam… genau das hatte ich probiert und egal welche Ser# ich eingetragen hatte, als Ergebnis bekam ich immer 1 :confused:
Der von mir vorhin gepostete Code war eigentlich nur eine „Verzweifelungstat“ und der letze Versuch.

Nun habe ich es nochmal probiert:

$ccu = '192.168.12.60';
$function = 1;
$devices = 'EEQ0005550';

GetDeviceStatus($ccu, $function, $devices, &$status);

echo $status;

…und bekomme wirklich nur bei der w.o. erwähnten FB eine 1, also True für LOWBATT.
Naja, wahrscheinlich hatte ich trotzdem irgendwo einen Fehler in der Syntax.

Danke! Jetzt kann ich weiter machen :slight_smile:

[P.S. und EDIT]/
Zusammenfassend aus Thorsten’s Script und Martin’s Beispiel, habe ich das ganze mal vereinfach, wobei das Erstellen einer String-Variable entfällt und alles automatisiert abläuft => http://www.ip-symcon.de/forum/f53/hm-instanzen-batteriezustand-erstellen-aendern-u-loeschen-variablen-9183/

Hi,

bei mir funktioniert das Skript leider nicht. In $t steht am Ende immer nur „/tclrega.exefalsefalse“ und kein XML drin. Die Homematic antwortet allerdings richtig - ich habe den Netzwerkverkehr mit Wireshark mitgeschnitten:

POST /tclrega.exe HTTP/1.1
Content-type: application/x-www-form-urlencoded
Content-Length: 148
Connection: Close

var GEQ0168810 = dom.GetObject('BidCos-RF.GEQ0168810:0.LOWBAT').Value();
var GEQ0169150 = dom.GetObject('BidCos-RF.GEQ0169150:0.LOWBAT').Value();
HTTP/1.1 200 OK
Server: ise GmbH HTTP-Server v2.0
Accept-Ranges: bytes
Cache-Control: no-store, no-cache
Content-Type: text/xml
Content-Length: 150
Date: Sat, 13 Feb 2010 21:03:13 GMT

<xml><exec>/tclrega.exe</exec><sessionId></sessionId><httpUserAgent></httpUserAgent><GEQ0168810>false</GEQ0168810><GEQ0169150>false</GEQ0169150></xml>

Hat jemand einen Tip wie ich das vollständige XML erhalte?

Grüße
Martin

Hallo Martin,

ich vermute mal, Du lässt das Ergebnis einfach im Browser anzeigen. Dabei wird natürlich alles was in <???></???> steht weggelassen, da es sich um Befehle für den Browser handelt. Alles was nicht in den Klammern steht, bkommst Du angezeigt.

Du musst jetzt Dein Ergebnis noch entsprechend zerlegen.

Ich wünsche einen schönen Tag.

Christoph.

Hi Christoph,

danke für den Tipp - es war zwar nicht der Browser sondern der „echo“ Befehl. Filtert genauso die gesamte XML Struktur raus…

Grüße
Martin

Verwende das Script von bruns8234 um den LOWBAT-Status eines Gerätes auszulesen. Funktioniert auch soweit, dass es mir im Webfront den Wert 0 ausgibt, jedoch ohne Angabe der GeräteID.

  1. Wie kann ich einstellen, dass mir die GeräteID mit angezeigt wird?
  2. Wie und wo binde ich jetzt die Abfrage für mehrere Geräte ein?

Grüße und Danke für eure Hilfe
Jürgen

Der Lowbat Status wird doch angezeigt wenn die Adresse :0 angelegt wurde.

Das steht auch schon zig mal geschrieben.

Hallo Rainer,
das habe ich auch schon zig mal gelesen. Wollte ja nur den LOWBAT-Status zwischendurch auslesen lassen. Das gleiche gilt für den UNREACH-Status.
Grüße
Jürgen

Hallo Thorsten,

erstmal finde ich das Skript gut. Da ich mich bzgl. der Kommunikation zwischen IPS und CCU nicht wirklich gut auskenne, folgende Frage:

Kann man das Skript so anpassen, dass es bei Übergabe der Geräte ID den aktuellen Status aller Variablen zurückgibt? (z.B. in einem zwedimensionalen Array [Variablenname][Wert]).

Hintergrund: Auch ich möchte, bei einem IPS Neustart, die Variablen prüfen und bei Abweichung zwischen CCU und IPS, IPS aktualisieren. Das Skript zum Durchlaufen aller HM-Komponenten bekomme ich, denke ich, hin. Allerdings macht das nur Sinn, wenn man deine Funktion erweitern kann. Die Kombi aus beiden Skripts wäre dann sicher Sinnvoll für alle Homematic User deren IPS Dienst auch mal aus ist. (z.b. Nachts bei der Datensicherung)

Beste Grüße!
Smokey

P.S.: Das war er, mein erster Beitrag im Forum!

Hallo zusammen,

dieses Skript aktualisiert bei mir nun nach dem Neustart des IPS Dienstes die Homematic Variablen. Es wird vom EventHandler automatisch beim Start des Dienstes ausgeführt.

Gruß
Smokey

PS: Die INSTALL_TEST Variable wird ausgeschlossen, verursacht beim Fensterdrehgriffkontakt einen Fehler. Was macht diese Variable überhaupt??!?


<?

$guid = "{EE4A81C6-5C90-4DB7-AD2F-F6BBD521412E}";  //guid Homematic

$alleInstanzen = IPS_GetInstanceListByModuleID($guid);

foreach ($alleInstanzen as $InstanzID)
{
   //echo IPS_GetName($InstanzID)."
";
	$adresse = HM_GetAddress($InstanzID);
	//echo $adresse."
";
   $alleVariablen = IPS_GetStatusVariableIdents($InstanzID);
   if(sizeof($alleVariablen) > 0){
	   foreach ($alleVariablen as $VariablenName)
   	{
			$VariablenID = IPS_GetStatusVariableID($InstanzID, $VariablenName);
			//echo $VariablenName."
";
			if($VariablenName != "INSTALL_TEST"){
			   HM_RequestStatus($InstanzID, $VariablenName);
			}
			//echo "	".$VariablenID." - ".$VariablenName." - ".GetValue($VariablenID)."   ".HM_RequestStatus($InstanzID, $VariablenName)."
";

	   }
	}
}

?>

Hallo Smokey,
dein Script ist super. Die Variablen werden aktualisiert. Bekomme jedoch am Ende 3 mal die gleiche Fehlermeldung in Zeile 19. Woran kann das denn liegen?

Gruß, immergut