HomeMatic - RSSI, Batterie und unerreichbar

Da ich durch die Suche nichts gefunden habe, habe ich selbst was gebastelt.

Im groben und ganzen baut das Script hier drauf auf
HM_RequestStatus — IP-Symcon :: Automatisierungssoftware

Was macht das Script ?
Es liest die folgenden Werte aus den HomeMatic Geräten aus
[b]- RSSI_DEVICE

  • RSSI_PEER
  • LOWBAT
  • UNREACH[/b]

So schaut das Ganze im WebFront als Übersicht aus


die einzelnen Tabellen gibt es auch einzeln

Voraussetzung

  • Es muss die MAINTENANCE Instanz zum jeweiligen Gerät vorhanden sein
    –> Hierbei bietet es sich an diese Instanz dann in die Instanz vom jeweiligen Gerät zu ziehen und den Namen MAINTENANCE nicht zu ändern

in dem Fall wird dann im WebFront der Name der übergeordneten Instanz angezeigt

Wer das nicht möchte der kann die Instanz auch woanders einordnen, in dem Fall muss dann aber der Name von MAINTENANCE geändert werden auf eines der folgenden Formate
MAINTENANCE - GeräteName
MAINTENANCE-GeräteName
MAINTENANCEGeräteName
GeräteNameMAINTENANCE

Das Wort MAINTENACE wird dann im WebFront raus gefiltert, so wird dann aus MAINTENANCE - FB1 nur FB1

Installation

  • im Objektbaum an gewünschter Stelle ein neues Skript erstellen
    –> Rechtsklick
    Screenshot_559.jpg

–> Namen eintragen und auf OK
Screenshot_560.jpg

–> auf der sich öffnenden Seite den vordefinierten Inhalt entfernen und an dessen Stelle diesen Code einfügen

<?

// GoodList
$goodList[] = "RSSI_DEVICE";
$goodList[] = "RSSI_PEER";
$goodList[] = "LOWBAT";
$goodList[] = "UNREACH";

$ids = IPS_GetInstanceListByModuleID("{EE4A81C6-5C90-4DB7-AD2F-F6BBD521412E}");

$htmlRSSI_PEER   = "";
$htmlRSSI_DEVICE = "";
$htmlLOWBAT      = "";
$htmlUNREACH     = "";
$evenOrNotEven1  = 1;
$evenOrNotEven2  = 1;
$evenOrNotEven3  = 1;
$evenOrNotEven4  = 1;

foreach($ids as $id){
	$oo = IPS_GetObject($id);
	// MAINTENANCE is required in the name of the object
	if(stripos($oo['ObjectName'], "MAINTENANCE", 0) !== false){
	    $cids = IPS_GetChildrenIDs($id);
	    foreach($cids as $cid)	    {
	        $o = IPS_GetObject($cid);
	        if($o['ObjectIdent'] != "") {
				if(!in_array($o['ObjectIdent'], $goodList)) continue;
			
	            if(@HM_RequestStatus($id, $o['ObjectIdent']) === false) {
	                echo "Error: ".IPS_GetLocation($id)." - " . $o['ObjectIdent'] . "
";
					//break;
	            }else{
					//echo "OK: ".IPS_GetLocation($id)." - " . $o['ObjectIdent'] . "
";
				}

				$value = GetValue($cid);
				
				// Try to generate a good Name for the WebFront
				$fromName = $oo['ObjectName'];
				if(strtoupper($fromName) == "MAINTENANCE") {
					$pid = IPS_GetObject(IPS_GetParent($id));
					$fromName = $pid['ObjectName'];
					//print_r($pid);
				}elseif(stripos($fromName, "MAINTENANCE")  !== false){
					$fromName = str_ireplace("MAINTENANCE -", "", $fromName);
					$fromName = str_ireplace("MAINTENANCE-", "", $fromName);
					$fromName = str_ireplace("MAINTENANCE", "", $fromName);
					$fromName = trim($fromName);
				}else{
					// maybe we need this later
				}
				
				// generate the input for the different html boxes
				if($o['ObjectIdent'] == "RSSI_PEER"){
					$evenOrNotEven1++;
					$textColor = ($value < -100 ? '#B40404' : '#0B610B');
					if($evenOrNotEven1 % 2 != 0){
						$color  = ' style="background-color:#000000; color:#ffffff;"';
						$color2 = ' style="background-color:#000000; color:' . $textColor . ';"';
					}else{
						$color  = ' style="background-color:#080808; color:#ffffff;"';
						$color2 = ' style="background-color:#080808; color:' . $textColor . ';"';
					}
					$htmlRSSI_PEER   .= '<tr><td' . $color . '>' . $fromName . '</td><td align="right"' . $color2 . '> ' . $value . ' dBm </td></tr>';
				}
				
		   		if($o['ObjectIdent'] == "RSSI_DEVICE"){
					$evenOrNotEven2++;
					$textColor = $value == -65535 ? '#ffffff' : ($value < -100 ? '#B40404' : '#0B610B');
					if($evenOrNotEven2 % 2 != 0){
						$color  = ' style="background-color:#000000; color:#ffffff;"';
						$color2 = ' style="background-color:#000000; color:' . $textColor . ';"';
					}else{
						$color  = ' style="background-color:#080808; color:#ffffff;"';
						$color2 = ' style="background-color:#080808; color:' . $textColor . ';"';
					}
					$htmlRSSI_DEVICE .= '<tr><td' . $color . '>' . $fromName . '</td><td align="right"' . $color2 . '> ' . ($value == -65535 ? 'n.a.' : $value . ' dBm') . ' </td></tr>';
				}
				
		   		if($o['ObjectIdent'] == "LOWBAT"){
					$evenOrNotEven3++;
					$textColor = ($value == true ? '#B40404' : '#0B610B');
					if($evenOrNotEven3 % 2 != 0){
						$color  = ' style="background-color:#000000; color:#ffffff;"';
						$color2 = ' style="background-color:#000000; color:' . $textColor . ';"';
					}else{
						$color  = ' style="background-color:#080808; color:#ffffff;"';
						$color2 = ' style="background-color:#080808; color:' . $textColor . ';"';
					}
					$htmlLOWBAT      .= '<tr><td' . $color . '>' . $fromName . '</td><td align="center"' . $color2 . '> ' . ($value == true ? 'Low Bat' : 'OK') . ' </td></tr>';
				}
				
		   		if($o['ObjectIdent'] == "UNREACH"){
					$evenOrNotEven4++;
					$textColor = ($value == true ? '#B40404' : '#0B610B');
					if($evenOrNotEven4 % 2 != 0){
						$color  = ' style="background-color:#000000; color:#ffffff;"';
						$color2 = ' style="background-color:#000000; color:' . $textColor . ';"';
					}else{
						$color  = ' style="background-color:#080808; color:#ffffff;"';
						$color2 = ' style="background-color:#080808; color:' . $textColor . ';"';
					}
					$htmlUNREACH     .= '<tr><td' . $color . '>' . $fromName . '</td><td align="center"' . $color2 . '> ' . ($value == true ? 'Error' : 'OK') . ' </td></tr>';
				}
	        }
	    }
	}else{
		//print_r($oo);
	}
}

$htmlRSSI_PEER   = '<table><tr><td><b>Device</b></td><td><b>Value</b></td></tr>' . $htmlRSSI_PEER .'</table>';
$htmlRSSI_DEVICE = '<table><tr><td><b>Device</b></td><td><b>Value</b></td></tr>' . $htmlRSSI_DEVICE .'</table>';
$htmlLOWBAT      = '<table><tr><td><b>Device</b></td><td><b>Value</b></td></tr>' . $htmlLOWBAT .'</table>';
$htmlUNREACH     = '<table><tr><td><b>Device</b></td><td><b>Value</b></td></tr>' . $htmlUNREACH .'</table>';

/*
echo $htmlRSSI_PEER;
echo $htmlRSSI_DEVICE;
echo $htmlLOWBAT;
echo $htmlUNREACH;
*/

saveValue("HM_MAINTENANCE", "RSSI_PEER",   $htmlRSSI_PEER);
saveValue("HM_MAINTENANCE", "RSSI_DEVICE", $htmlRSSI_DEVICE);
saveValue("HM_MAINTENANCE", "LOWBAT",      $htmlLOWBAT);
saveValue("HM_MAINTENANCE", "UNREACH",     $htmlUNREACH);
saveValue("HM_MAINTENANCE", "OVERVIEW",    "<table><tr><td><b>RSSI_PEER</b></td><td><b>RSSI_DEVICE</b></td><td><b>UNREACH</b><td><b>LOWBAT</b></td></td></tr><tr valign='top'><td>" . $htmlRSSI_PEER . "</td><td>" . $htmlRSSI_DEVICE . "</td><td>" . $htmlUNREACH . "</td><td>" . $htmlLOWBAT . "</td></tr></table>");

function saveValue($instanceName, $variableName, $html){
	global $_IPS;
	
	$dummyInstanceName = $instanceName;
	$dummyInstanceInfo = $instanceName;
	
	$valueName = $variableName;
	$valueInfo = $variableName;
	
	// Check if the Dummy Instance is already available
	$port = "";
	$childs = IPS_GetChildrenIDs($_IPS['SELF']);
	foreach($childs as $child) {
		$o = IPS_GetObject($child);
		if(strpos($o["ObjectInfo"], $dummyInstanceInfo)!== false) {
			$port = $child;
			break;
		}
	}
	
	// create a new Dummy Instance
	if($port == ""){
		$port = IPS_CreateInstance("{485D0419-BE97-4548-AA9C-C083EB82E61E}");  // Dummy Instance 
				IPS_SetName($port, $dummyInstanceName);
				IPS_SetInfo($port, $dummyInstanceInfo);
				IPS_SetParent($port, $_IPS['SELF']);
	}
	
	// Check if the Variable is available in Port Dummy Instance
	$varID  = "";
	$childs = IPS_GetChildrenIDs($port);
	foreach($childs as $child) {
		$o = IPS_GetObject($child);
		if(strpos($o["ObjectInfo"], $valueInfo)!== false) {
			$varID = $child;
			break;
		}
	}
	
	// Create new Variable
	if($varID == ""){
		$varID = IPS_CreateVariable(3); // 0:Boolean 1:Integer 2:Float 3:String
				 IPS_SetParent($varID, $port);
				 IPS_SetName($varID, $valueName);
				 IPS_SetInfo($varID, $valueInfo);
				 IPS_SetVariableCustomProfile($varID, "~HTMLBox");
	}
	
	SetValueString($varID, $html);
}
?>

Dabei aufpassen das vor <? bzw nach ?> keine Leerzeichen oder Zeilenumbrüche sind

einmal auf „Ausführen“ klicken, dadurch werden die Daten ausgelesen und die Variablen erstellt.
Das kann man so oft wie man will machen, also auch wenn man später einmal eine MAINTENANCE Instanz hinzugefügt hat.

Jetzt wollen wir ja sicherlich noch dass das Script immer wieder mal neue Daten holt.
Je nach dem wie viele HM Geräte man hat kann das schon etwas dauern, hier sollte man das Abfrageintervall also nicht zu klein/schnell wählen. Ein mal die Stunde sollte vollkommen ausreichen, theoretisch reicht es auch alle 12 Stunden aus wenn man nur nach einer leeren Batterie gucken will.

Wenn man mal was testen möchte kann man das Script ja immer noch manuell ausführen.

Das Abfrageintervall stellen wir wie folgt ein.
In der Leiste wo wir eben auf „Ausführen“ geklickt haben klickt ihr 3 Buttons weiter nach links auf den Button „Ereignis hinzufügen“

dann „Zyklisches Ereignis“ auswählen und auf „Weiter >>“ klicken

Screenshot_563.jpg

Auf der nächsten Seite dann „Stündlich“ auswählen, das Intervall bei Alle X Stunden einstellen und wieder auf „Weiter >>“ klicken

Screenshot_564.jpg

Auf der nächsten Seite braucht nichts verändert werden, es sollte „Script starten“ ausgewählt sein und bei Ziel sollte das eben erstellte Script ausgewählt sein. (wenn nicht bitte auswählen)

Screenshot_565.jpg

Im Objektbaum sollte jetzt unter dem Script (ich habe meins „Spielerei“ genannt) das eben erstellte Ereignis auftauchen.

Jetzt nur noch die jeweilige InfoBox
[b]- RSSI_DEVICE

  • RSSI_PEER
  • LOWBAT
  • UNREACH
  • OVERVIEW[/b]
    über eine Kategorie ins Webfront verlinken

Rechtsklick in die gewünscht Kategorie, dann (sorry hier gehen nur 10 Bilder deswegen als Text)
Objekt hinzufügen --> Link hinzuügen --> die InfoBox im Objektbaum auswählen

So ich hoffe das ich es auf für Anfänger gut genug erklärt habe und das es so etwas noch nicht gab ^^

Viel Spaß damit

Gefällt mir. :slight_smile: Leider kann ich es nicht direkt umsetzen, da ich das Skript hiernutze. Lässt sich Dein Ansatz vielleicht auf „Gerätename TECH“ anpassen/erweitern?

Grüße
galleto

Wie meinst Du das mit TECH ?

Wenn ich mir das andere Script anschaue wurde das aus MAINTENANCE --> NameTECH gemacht

Theoretisch müsstest Du im Script alle reinen „MAINTENANCE“ (also da wo nur MAINTENANCE steht) durch TECH ersetzen

Also einmal

if(stripos($oo['ObjectName'], "MAINTENANCE", 0) !== false){ 

ersetzen durch

if(stripos($oo['ObjectName'], "TECH", 0) !== false){ 

und dann unter
// Try to generate a good Name for the WebFront

                $fromName = $oo['ObjectName'];
                if(strtoupper($fromName) == "MAINTENANCE") {
                    $pid = IPS_GetObject(IPS_GetParent($id));
                    $fromName = $pid['ObjectName'];
                    //print_r($pid);
                }elseif(stripos($fromName, "MAINTENANCE")  !== false){
                    $fromName = str_ireplace("MAINTENANCE -", "", $fromName);
                    $fromName = str_ireplace("MAINTENANCE-", "", $fromName);
                    $fromName = str_ireplace("MAINTENANCE", "", $fromName);
                    $fromName = trim($fromName);
                }else{
                    // maybe we need this later
                } 

ersetzen durch

                $fromName = $oo['ObjectName'];
                if(strtoupper($fromName) == "TECH") {
                    $pid = IPS_GetObject(IPS_GetParent($id));
                    $fromName = $pid['ObjectName'];
                    //print_r($pid);
                }elseif(stripos($fromName, "TECH")  !== false){
                    $fromName = str_ireplace("TECH-", "", $fromName);
                    $fromName = str_ireplace("TECH-", "", $fromName);
                    $fromName = str_ireplace("TECH", "", $fromName);
                    $fromName = trim($fromName);
                }else{
                    // maybe we need this later
                } 

ungetestet und ohne Gewähr :wink:

Danke, funktioniert. :slight_smile:

Kannst Du mit folgender Fehlermeldung etwas anfangen?

Error: HomeMatic Socket CCU2\Strom\Bad\SWITCH TECH - LOWBAT

Das ist eine Steckdose mit Leistungsmessung (HM-ES-PMSw1-Pl). Die Variable LOWBAT existiert.

Eine entsprechende Fehlermeldung habe ich auch noch bei einer Fernbedienung bezüglich UNREACH. :confused:

EDIT: Die Fehler kommen bei jedem Durchlauf.

Grüße
galleto

Das Gerät hat kein Lowbat. Somit meckert deine CCU (Error).
Schau hier:

Warum sollte ein 230V Gerät auch einen Batteriestatus haben ^_^;

Michael

Danke. Das klingt erstmal logisch. Aber in IPS haben alle Steckdosen eine LOWBAT-Variable und keine andere wird vom Skript bemeckert. :confused:

Grüße
galleto

War sie auch vorhanden bevor das Script lief?
Beim mir hat kein 230v Gerät einen Batteriestatus. Die Datenpunktliste von EQ3 ist da ausschlaggebend nicht das was irgendein Script in IPS anlegt.
Zumal unrech eh als Servicemeldung kommt, braucht man den Datenpunkt nicht.
Und Batteriewerte werden automatisch übertragen (da die Geräte eh nicht aktiv per Funk abgefragt werden müssen).
Michael

Ja einige Komponenten haben sinnlose Variablen, warum auch immer.

Man könnte das jetzt im Bezug auf die VariabelID „raus programmieren“

oder man unterdrückt die Meldung, dazu

echo "Error: ".IPS_GetLocation($id)." - " . $o['ObjectIdent'] . "
"; 

ersetzen durch

//echo "Error: ".IPS_GetLocation($id)." - " . $o['ObjectIdent'] . "
"; 

unterdrücken ist aber nicht unbedingt immer der saubere Weg da die fehlerhafte Abfrage trotzdem gemacht wird

Eine weitere Alternative wäre die entsprechende Variabel im IPS Objektbaum in der MAINTENANCE Instanz vom betroffenen Gerät zu löschen

Ich denke, dass die Systemvariablen von IPS (HM-Konfigurator) kamen. Löschen hilft. :smiley: IPS meckert zwar und sagt, bei einem Neustart würden die gelöschten Systemvariablen wieder hergestellt; stimmt aber nicht. Auch das Skript legt sie nicht wieder an. Also hab ich gleich noch ein paar Variablen gespart, auch gut.

Grüße
galleto

Der Konfigurator legt gar keine Variablen an. Nur Instanzen.
Diese erzeugen dann ihre Variablen, anhand der von der CCU gemeldeten Datenpunkte.
Michael

Würde bedeuten, da können die LOWBAT-Variablen nicht herkommen? Merkwürdig. Von Hand habe ich sie jedenfalls nicht bei allen Steckdosen (und auch Schaltern) angelegt.

Grüße
galleto

Das muss dann ein Fehler in der CCU2 sein, low BAT wurde bei mir nicht zu viel angelegt aber dafür z.b. für einen IP BSM wurde ACTUAL_TEMPERATURE erstellt

Hallo,

hier noch ein Tipp für diejenigen, die die Maintenance Instanzen erst gar nicht in IPS anlegen wollen und trotzdem die RSSI Werte sehen wollen. Es gibt seit langer Zeit das Programm HM Inventory, welches die RSSI Werte ebenfalls anzeigt. Nachteilig ist dabei allerdings, dass dann keine IPS Bezeichnungen angezeigt werden.

Diese Problem ist aber bei den Heizungs- und Wandthermostaten nicht wirklich relevant, wenn man die Instanz mit den Heizungsdaten in IPS angelegt hat, was allgemein der Fall sein dürfte. Dann erscheinen die Geräte nochmals in der Liste mit der IPS Bezeichnung.

https://www.symcon.de/forum/threads/17633-HM_Inventory

Gruß
Hans

Hallo zusammen,

irgendwie steh ich auf dem Schlauch. Habe das Skript so kopiert und auf dem einen Rechner funktioniert es ohne Probleme und auf dem anderen Rechner klappt das gleiche Skript nicht => Das Skript läuft ohne Fehler durch, aber es werden keine Daten in die HTML Tabellen geschrieben.
Beim anderen Rechner klappt alles perfekt.

Bei beiden Rechner sind die entsprechenden Instanzen in Maintenance umbenannt worden.

Hat vielleicht jemand eine Idee?

Gruß
Mike

Hat sich erledigt. Fehler gefunden! Die Verlinkung war falsch! :wink:

Hallo Nisbo,

ich möchte mich nur für das Script bedanken. Es funktioniert einwandfrei ohne Problem.

Vielen Dank!!

Gruß
Thomas