Mich hat das Thema mit der fehlenden Unterstützung der Service-Messages die Tage mal wieder richtig angenervt und daher habe ich was gebaut.
Und zwar besteht das aus zwei Teilen
- eine Systemvariable auf der HM-Seite, die eine Liste der Servicemessages enthält und das dazugehörige Script
- auf der Seite von IPS ein Script, das diese Variable dekodiert und in meinem Fall in eine HTML-Box füllt
Programm auf HM-Seite
Programm auf HM-Seite
object svObjects = dom.GetObject(ID_SYSTEM_VARIABLES);
string svVarName = "Servicemeldungen-Liste";
object svObj = dom.GetObject(ID_SYSTEM_VARIABLES).Get(svVarName);
if (!svObj){
svObj = dom.CreateObject(OT_VARDP);
svObj.Name(svVarName);
svObj.ValueType(ivtString);
svObj.ValueSubType(istChar8859);
svObj.DPInfo("Liste der aktuellen Servicemeldungen");
svObj.ValueUnit("");
svObj.State("");
svObj.Internal(false);
svObj.Visible(true);
svObjects.Add(svObj.ID());
dom.RTUpdate(true);
}
object svIDs = dom.GetObject(ID_SERVICES);
if (svIDs) {
string svID;
string result = "";
foreach(svID, svIDs.EnumIDs()){
object svObj = dom.GetObject(svID);
if (svObj) {
if (svObj.IsTypeOf(OT_ALARMDP) && (svObj.AlState() == asOncoming)) {
var trigDP = dom.GetObject(svObj.AlTriggerDP());
var ch = dom.GetObject(trigDP.Channel());
var sdev = dom.GetObject(ch.Device());
var sdesc = trigDP.AlDestMapDP().Name().StrValueByIndex(".", 2);
integer created = svObj.AlOccurrenceTime().ToInteger();
integer updated = svObj.LastTriggerTime().ToInteger();
if (result <> "") {
result = result # ",";
}
result = result # "{\"address\":\"" # sdev.Address() # "\",\"name\":\"" # sdev.Name() # "\",\"error\":\"" # sdesc # "\",\"created\":" # created # ",\"updated\":" # updated # "}";
}
}
}
integer tstamp = system.Date("%F %X").ToTime().ToInteger();
result = "{\"tstamp\":" # tstamp # ",\"messages\":[" # result # "]}";
dom.GetObject(ID_SYSTEM_VARIABLES).Get(svVarName).State(result);
}
Die auslösende Systemvariable Servicemeldungen gibt es anscheinend immer in einer HM-Installation (ich nutze Raspberrymatic), ist aber u.U. als intern gekennzeichnet und wird daher nicht angezeigt.
Zum Test macht es Sinn, auch mal eine Servicemeldung zu erzwingen (zB ein Batteriefach öffnen => „Sabotage“)
auf der IPS-Seite muss [Modul] Homematic Extended von @Nall-chan installiert sein, um die Systemvariablen abzurufen.
Das Script Servicemeldungen auslesen sieht so aus
<?php
$src_varID = xxxxx; // HM-Systemvariable "Servicemeldungen-Liste"
$dst_varID = yyyyy; // Variable vom Typ "String" und dem Variablenprofil "~HTMLBox"
$sdata = GetValueString($src_varID);
$jdata = json_decode(utf8_encode($sdata), true);
if ($jdata == false) {
echo 'sdata="' . $sdata . '", json_error=' . json_last_error_msg() . PHP_EOL;
}
$addr2id = [];
$ids = IPS_GetInstanceListByModuleID('{EE4A81C6-5C90-4DB7-AD2F-F6BBD521412E}');
foreach ($ids as $id) {
$addr = explode(':', IPS_GetProperty($id, 'Address'));
if (isset($addr[0]) == false) {
continue;
}
if (IPS_GetObject($id)['ObjectIsHidden']) {
continue;
}
$addr = $addr[0];
if (isset($addr2id[$addr]) == false) {
$addr2id[$addr] = $id;
}
}
$map_error = [
'CONFIG_PENDING' => 'Konfigurationsdaten stehen zur Übertragung an',
'LOWBAT' => 'Batterieladezustand gering',
'LOW_BAT' => 'Batterieladezustand gering',
'UNREACH' => 'Gerätekommunikation aktuell gestört',
'STICKY_UNREACH' => 'Gerätekommunikation war gestört',
'SABOTAGE' => 'Sabotage',
'DEVICE_IN_BOOTLOADER' => 'Gerät startet',
'UPDATE_PENDING' => 'Update verfuegbar',
];
$html = '';
$html .= '<style>' . PHP_EOL;
$html .= 'body { margin: 1; padding: 0; font-family: "Open Sans", sans-serif; font-size: 20px; }' . PHP_EOL;
$html .= 'table { border-collapse: collapse; border: 0px solid; margin: 0.5em;}' . PHP_EOL;
$html .= 'th, td { padding: 1; }' . PHP_EOL;
$html .= '#spalte_name { width: 300px; }' . PHP_EOL;
$html .= '#spalte_address { width: 150px; }' . PHP_EOL;
$html .= '#spalte_updated { width: 150px; }' . PHP_EOL;
$html .= '#spalte_error { width: 400px; }' . PHP_EOL;
$html .= '</style>' . PHP_EOL;
if (isset($jdata['messages']) && count($jdata['messages'])) {
$html .= '<table>' . PHP_EOL;
$html .= '<colgroup><col id="spalte_name"></colgroup>' . PHP_EOL;
$html .= '<colgroup><col id="spalte_address"></colgroup>' . PHP_EOL;
$html .= '<colgroup><col id="spalte_updated"></colgroup>' . PHP_EOL;
$html .= '<colgroup><col id="spalte_error"></colgroup>' . PHP_EOL;
$html .= '<tr>' . PHP_EOL;
$html .= '<td>Gerätname</td>' . PHP_EOL;
$html .= '<td>Seriennummer</td>' . PHP_EOL;
$html .= '<td>letzte Änderung</td>' . PHP_EOL;
$html .= '<td>Meldung</td>' . PHP_EOL;
$html .= '</tr>' . PHP_EOL;
foreach ($jdata['messages'] as $message) {
$error = $message['error'];
if (isset($map_error[$error])) {
$error = $map_error[$error];
}
$addr = $message['address'];
if (isset($addr2id[$addr])) {
$name = IPS_GetLocation($addr2id[$addr]);
$name = preg_replace('/ \(:[0-9]*\)$/', '', $name);
} else {
$name = $message['name'];
}
$updated = date('d.m.y H:i:s', $message['updated']);
$html .= '<tr>' . PHP_EOL;
$html .= '<td>' . $name . '</td>' . PHP_EOL;
$html .= '<td>' . $addr . '</td>' . PHP_EOL;
$html .= '<td>' . $updated . '</td>' . PHP_EOL;
$html .= '<td>' . $error . '</td>' . PHP_EOL;
$html .= '</tr>' . PHP_EOL;
}
$html .= '</tdata>' . PHP_EOL;
$html .= '</table>' . PHP_EOL;
} else {
$html .= 'Keine Servicemeldungen';
}
SetValueString($dst_varID, $html);
das Script sollte dann natürlich an die eigenen Bedürfnisse angepasst werden, insbesondere wie der Name im IPS gesucht wird; man kann auch den von der CCU in $message['name']
bereitgestellten Namen verwenden, das ist dann halt die Bezeichnung auf der CCU.
Es wird aufgerufen durch ein Ereignis durch Änderung der Variable Systemmeldungen-Liste
Das Modul zum Abrufe der Systemvariablen wird ja entweder zyklisch abgerufen (da muss man nix machen) oder getigert werden durch die CCU.
Da ich die Erklärung von @Nall-chan auch nicht 100% verstanden hatte, eine Hilfestellung für andere mit dem gleichen Problem
- virtueller Taser auf der CCU
kann von dem „Gerät“ HmIP-RCV-50 oder HM-RCV-50 sein - das ich das umbenannt habe in IPS-Trigger ist nur zur Übersichtlichkeit.
und mit einem Programme auf der CCU ausgelöst
Es müssen hier alle Systemvariablen eingebunden sein, bei denen eine direkte Aktualisierung wünschenswert ist.
Dazu passend wird dieses Gerät auf der IPS-Seite angelegt
und als Trigger im Modul eingetragen
Wie gesagt, ich bin HM-seitig auch nur mit Try&Error unterwegs …