Hardware:
22x Rauchwarnmelder Dual/VdS GIRA 2330 mit Funk-Modul GIRA 2341
1x GIRA 2333 Funk-Diagnosetool für Rauchwarnmelder Dual/VdS mit Funk-Modul (per USB am IPS-PC)
Software:
eine RegisterVariable für die COM7 mit Skript zum Auslesen des Daten in den Puffer (mit Semaphore s.u.)
<?
if ($IPS_SENDER == "RegisterVariable") {
___retry:
if (IPS_SemaphoreEnter("ComPortRWM", 50)) {
$RegVarID = 12454 /*[Variablen global\RWM Diagnosetool Register Variable]*/;
// neuen Daten vom COM-Port hinten an Puffer anhängen
RegVar_SetBuffer($RegVarID, RegVar_GetBuffer($RegVarID) . $IPS_VALUE);
IPS_SemaphoreLeave("ComPortRWM");
}
else { // Daten müssen gespeichert werden, sonst sind sie weg ...
goto ___retry;
}
}
?>
ein Kommunikations-Skript kommuniziert mit dem Diagnosetool und sichert die Ergebnisdaten alle 22 RWM in eine String-Variable dauerhaft (serialisierter array)
ein HTML-Render-Skript, das getriggert wird, wenn sich die o.g. Daten der 22 RWM ändern, erzeugt in eine String-Variable HTML für die Darstellung
während der nächsten Zeit habe ich noch eine Variable, mit der ALLE Datendetails (Zeitticker, Meldungsspeicher, zweiten Temperaturwert, …) angezeigt werden und noch eine String-Varibale, die die gesamte Kommunkation zwischen Sender und Empfänger zur Püfung farblich darstellt
seriell/USB mit Semaphore:
Meiner Meinung nach kann man mit dem in der IPS Doku vorgeschlagenen Kommunikation in einem Skript, welches an dem Ereignis hängt, dass etwas EMPFANGEN wird, keine (fehlerfreie) Kommunikation mit Protokollrahmen und Prüfsummen aufbauen. Die Vorgehensweis ist gut geeignet, wenn ein System eigenständig Daten schickt, die man dann in dem RegVarSkript auch gleich verarbeiten kann.
Vor ca. zehn Jahre habe ich mir mit VBA ein Excel-Makro erstellt, das alle 10 min meine drei Luft-Wärmepumpen (2x LWZ303 und 1x LWZ304) per COM3:/4:/5: ausliest und mir im Fehlerfall eine Email schickt. Das EXCEL-Makro habe ich vor ca. einem Jahr nach IPS konvertiert und konnte die Kommunikation nur mit ips_sleep(100) einigermaßen lösen. Leider klappt die Kommunkation nicht immer zuverlässig. Es war mir damals schon klar, dass da einzelne Bytes verlohren gehen und somit die Checksum nicht stimmt und die Wärmepumpe nicht antwortet.
[14.06.2014] Nun habe ih die Kommunkation mit den LWZ303 und LWZ304 auch über Semaphoren abgesichert. Die Wartezeiten konnten alle entfallen und die Gesamtlaufzeit des Skripts wurde um ~80% gesengt. Wichtiger ist aber die DEUTLICH verbesserte Zuverlässigkeit der Skripte. Bei der Gelegenheit gleich die Protokoll für das Auslesen der Betriebsstunden, des Fehlerspeichers und die Warmwassersolltemperatur ersnifft und in IPS nachgebaut!
Jetzt bei der RWM-Kommunikation habe ich mir das nochmals vorgeknöpft. Die Vermutung war: das RegVarSkript hängt die Daten an den Puffer hinten an. Dazu muss zuerst der aktuelle Pufferinhalt ausgelesen werden. Selbst wenn man das in eine PHP-Zeile schreibt, gibt es einen kurzen Augenblick, in dem das andere, reglemäßig aufgerufene Skript ein Zeichen VORNE aus dem Puffer entnimmt und ebenfalls den Puffer zurückschreibt. Über längere Zeit habe ich die Kommunikation überwacht und genau diesen Fall vorgefunden: das RegVarSkript schreibt hinten an den Puffer mehrere Zeichen daran und einen Augenblick später schreibt die AusleseRoutine den Puffer mit dem entnommenen ersten Zeichen (und eben auch OHNE die hinzugefügten Zeichen) wieder zurück.
Das ist ein klassischer Anwendungsfall für Semaphoren. Die Funktion
IPS_SemaphoreEnter("ComPortRWM", 50)
versucht die (exklusive) Semaphore ComPortRWM zu bekommen. Falls das funktioniert hat, werden die Zeihen an den Puffer ANgehängt und die Semaphore wieder freigegeben
IPS_SemaphoreLeave("ComPortRWM");
Sollte das RegVarSkript beim ersten Versuch nciht erfolgreich sein, weil das andere Skript gerade das vorderste Zeichen entnimmt, wird 50ms gewartet und es automatisch NOCHMAL versucht. ERST DANN wird false zurückgegeben, wenn auch der zweite Versuch misslingt. Das unschöne goto ist zwingend nötig, da keine Zeichen verloren gehen sollten und die Daten aus der RegVar in jedem Falle gesichert werden sollen.
Das Gegenstück liest aus dem Puffer das vorderste Zeichen und entfernt es
////////////////////////////////////////////////////////////////////////////////
function fReadRWM($rvRWM, &$sByte)
// liest (genau) ein Byte/Zeichen aus der RegVar von COMx ein
// true = erfolgreich ein Byte gelesen; ggf. Rest im Buffer belassen
// false = nach timeout abgebrochen
{
global $sAllDataRead;
$iTimeout = 5000;
$i = 0;
// warten, bis etwas im Puffer vorhanden ist, oder eine Zeitüberschreitung eintritt
do {
$sByte = RegVar_GetBuffer($rvRWM);
$i = $i + 1;
} while (($sByte == "") and $i < $iTimeout);
if ($sByte != "") { // das erste Zeichen aus dem Puffer abschneiden und zurückliefern
___retry:
if (IPS_SemaphoreEnter("ComPortRWM", 50)) {
$sByte = RegVar_GetBuffer($rvRWM);// WICHTIG: nochmal lesen NACH semaphore!
RegVar_SetBuffer($rvRWM, (strlen($sByte) > 1) ? substr($sByte, 1) : ""); // restlichen Puffer zurückschreiben
$sByte = substr($sByte,0,1);
$sAllDataRead .= $sByte;
IPS_SemaphoreLeave("ComPortRWM");
}
else { // das Skript der RegVar hängt gerade Zeichen am ENDE des Puffers an: 50 msec warten
$sAllDataRead .= "<font color='#FF0000'>WAITING!!!</font>";
goto ___retry;
}
}
return ($sByte != "");
}
Hier ist dann auch ganz wichtig, dass nach dem anfänglichen Warten, dass überhaupt Bytes im Puffer sind, der Buffer NOCHMAL ausgelesen wird, wenn dieses Skript nun die Semaphore (exklusiv) besitzt! Sonst sind die Zeichen, die das RegVarSkript vielleicht zwischenzeitlich auch erst beim zweiten Versuch an das Pufferende angehängt hat wieder weg!
Mein Leseskript für die drei Wärmepumpen werde ich als nächsten umbauen und so absichern. Damit sammelt das RegVarSkript in aller Ruhe und mit schneller Reaktion die Daten von der Schnittstelle. Und auf der anderen Seite kann das regelmäßige Abfrageskript in aller Ruhe aus dem Puffer auslesen: es wird gewartet, bis überhaupt Daten da sind und ein Zeichen nach dem anderen ausgelesen.
Ich hoffe die kleine Einführung in Semaphore ist einigermassen verständlich. Detailsfragen gerne …