NEWS
Leckagesensor SYR Safe-T Connect - how to get it smart
-
Hi,
ich hab einen Leckagesensor SYR Safe-T Connect (https://www.syr.de/de/Produkte/DF262290-60DA-4785-858F-3A155324CA68/Safe-T-Connect) in der Hauptwasserleitung im Haus. Das Teil heißt Connect, da es über Netzwerkkabel ins Heimnetz verbunden wird und dann nach Hause telefoniert. Leider ist die 'Connect'-Funktion ein proprietäre Lösung, bei dem der Safe-T nur mit dem Server von SYR redet. Wenn der SYR-Server mal down ist oder von SYR abgeschaltet wird, dann funktioniert nur noch die Steuerung am Gerät selber. Die Parameter nur im Heimnetz auslesen und ansteuern funktioniert nur mit älteren Firmwares und dem etwas aufwändigeren Abfangen der Netzwerkpackete. Bei neueren Firmwares sind die Pakete verschlüsselt und man sieht leider nix mehr, sodass der Weg für unseren Leckagesensor nicht funktionierte. Der Leckagesensor sendet alle paar Sekunden ein Paket zum Server, die Datenmenge liegt bei ca. 500 MB pro Monat.
Viele Informationen dazu findet man unter https://www.msxfaq.de/sonst/iot/syr_safe-t_connect.htm . An dieser Stelle ein Herzlichen Dank für das Zusammentragen der Informationen an den Autor dieser Seite! Es hat mich erst dazu inspiriert mich mit dem lokalen Auslesen vom Leckagesensor weiter auseinander zu setzen.
Die diversen Schnittstellen sind auf der Seite von MSXFAQ erläutert. Aber dieser Service-Eingang nicht.... Ich hab mich mit dem Oszilloskop dran gehängt und siehe da: Es läuft RS485 auf den mittleren beiden Pinnen des RJ10-Steckers (4P4C). Also flux einen USB auf RS485-Adapter gekauft, ein Telefonhörerkabel mit RJ10 geopfert und das ganze an einen Raspberry Pi gehängt.
Schritt 1:
Der Port erscheint bei mir unter /dev/ttyUSB1. Mit dem Oszi noch die Geschwindigkeit gemessen: Es läuft auf 19200 Baud. Polarität ... tjo... try&error... es kann eigentlich nichts kaputt gehen und es gibt nur zwei Möglichkeiten (A-A & B-B oder A-B & B-A).Mit cat -v /dev/ttyUSB1 & wird alles auf dem Port auf die Kommandozeile ausgegeben. Ist die Polarität richtig, dann sieht man eine Ausgabe - andernfalls muss man die Polarität der beiden Adern drehen.
Man sieht dort die Kommunikation zwischen dem LAN-Modul, welches die diversen Parameter abfragt, und dem Steuer-Mikrokontroller selber, der auf die Abfragen antwortet. Das LAN-Modul fragt jedoch nur regelmäßig die Parameter ab, wenn es mit einem Netzwerk verbunden ist. Andernfalls kommt nur alle paar Minuten eine kurze Abfrage des Gerätetyps.
Schritt 2:
Jetzt wollen wir natürlich die Daten selber abfragen und der SYR soll nicht mehr im Internet hängen. Aus den Ausgaben von Schritt 1 und der MSXFAQ-Seite sieht man, dass immer ein clrADM:, dann ein setADM(2)f gesendet wird und darauf dann die unterschiedlichen Parameter mit z.b. getAVO für die aktuelle Zapfmenge in Milliliter kommt.Von der Kommandozeile senden wir die aus Schritt 1 aufgezeichneten und interpretierten Hex-Werte - und lassen dabei den cat oben dank dem &-Zeichen im Hintergrund weiterlaufen:
echo -en "\x0D\x0A\x1B\x31\x3a\x63\x6C\x72\x41\x44\x4d\x0d\x0a" > /dev/ttyUSB1; sleep 0.3; echo -en "\x0d\x0a\x1b\x31\x3a\x73\x65\x74\x41\x44\x4d\x28\x32\x29\x66\x0d\x0a" > /dev/ttyUSB1; sleep 0.3; echo -en "\x0d\x0a\x1b\x31\x3agetAVO\x0d" > /dev/ttyUSB1;
Wie ihr seht ist getAVO nicht in Hex sondern zur besseren Lesbarkeit als ASCII drin.Und wir bekommen zurück:
ADMIN RESET^MFACTORY^M0mL^M [^M ist das ASCII-Zeichen Carriage Return.]-> Jackpot! Damit bekommen wir eine erste simple Lösung hin um Parameter in ioBroker zu bekommen. Der ioBroker läuft zufälliger Weise schon auf dem Raspberry Pi. Jetzt fehlt nur noch etwas Quellcode um den Seriellen Port anzusteuern.
Dafür bietet sich eine Javascript-Instanz an. Wir fügen das Package "serialport" in den Instanzeinstellungen hinzu und nutzen den folgenden Quellcode.
Das Script sendet alle 10 Sekunden die Befehle in der commands-variable in aufsteigender Reihenfolge, die zurück erhaltenen Werte werden parsed und als Objekte in den ioBroker gesendet. Danach wird der nächste Befehl rausgesendet. [Serialport muss auf einer 10.x-Version sein - andernfalls müsst ihr die 'require'-Zeilen anpassen.]
Es kann passieren, dass das LAN-Modul dazwischen funkt - wir betreiben den RS485-Bus ja gerade mit drei Transceivern, wovon zwei (Raspi und LAN-Modul) immer wieder von alleine anfangen zu senden ohne auf den anderen zu hören. Die Kollisionen sind leider unvermeidbar. Um das bestmöglichst abzufangen bricht das Script seine eigene Übertragung ab, wenn es eine Kommunikation vom LAN-Modul mitbekommt. In dem Fall kann es aber dennoch zu fehlerhaften Parameterwerten kommen.
Noch vorhandene TODOs:
- Parameter auf gültigen Wertebereich beschränken. Vermindert die Wahrscheinlichkeit von Lesefehlern durch Bus-Kollisionen
- Unbekannte Werte identifizieren. Die Parameterliste ist lang und bei vielen Parametern habe ich noch nicht verstanden was sie bedeuten.
- Set-Befehle einbauen.... man will ja schließlich eine automatische Umschaltung zwischen Anwesend (große erlaubte Zapfmenge) und Abwesend (kleine erlaubte Zapfmenge) haben sowie auf Knopfdruck den Leckagesensor für eine Zeit deaktivieren um [Blumen gießen, Pool füllen, Teich säubern,... you name it...].
Ich hoffe ich kann mit dem Script jemandem eine Freude machen. Wer möchte kann das Script gerne nutzen. Einfach den Pfad von eurer seriellen Schnittstelle eintragen und ausführen. Wer es ändern möchte darf dies auch gerne tun - es freut aber sicher alle ioBroker-Nutzer wenn ihr Änderungen auch wieder veröffentlicht.
der Kachel
-
Und noch eine kurze Anmerkung: Die Javascript-Instanz lässt beim Beenden/Neustarten vom Script den seriellen Port offen. Entsprechend kann der Port beim nächsten Start nicht mehr geöffnet und genutzt werden. Der Workaround gerade ist: Die komplette Javascript-instanz einmal neu starten. Danach ist der Port wieder freigegeben und man kann das Script wieder starten.
-
@kachel sagte in Leckagesensor SYR Safe-T Connect - how to get it smart:
Die Javascript-Instanz lässt beim Beenden/Neustarten vom Script den seriellen Port offen.
Benutze das onStop Event um auf das beenden des Skripts zu reagieren und schließ darin die Serialport Verbindung.
-
@jey-cee : Top! Danke!
für alle die das Script nutzen wollen bitte folgendes am Ende des Scripts hinzufügen:
// close connection if script stopped
onStop(function (callback) {
if (port.isOpen) {
// close connection
port.close();
}
callback();
}, 2000 /ms/); -
@kachel Danke für die ganze gute Arbeit. Ich setze bisher kein iobroker ein (sondern diverse andere Lösungen). Der Syr Connect ist scheinbar die einzige Lösung, die eine Ansteuerung und Analyse per Kabel ermöglicht (mit Sensor, also kein reines 2-Wege Ventil) - daher überlege ich, mir ebenfalls das Teil anzuschaffen.
Ist die Abfrage stabil? Kommt es oft zu Kollisionen? Kann ich das System auch betreiben und die ausgehenden Netzwerkpakete quasi in ein Routing Loch schicken bzw. es gar nicht einstecken?
Lieben Dank und schönes Wochenende,
dmq -
Hi @Kachel
vielen Dank auch von mir. Du hast sicherlich viel Zeit in die Analyse gesteckt.Ich bin auch am Überlegen einen Safe-T zu installieren. Voraussetzung wäre aber die Integration in mein ioBroker basiertes Smart-Home, damit ich meine Wassermelder zur Ansteuerung des Safe-T nutzen kann.
kannst du kurz berichten, wie zuverlässig deine Lösung arbeitet? Wenn die Kommunikation langsam ist, vielleicht mehrere Sekunden durch Retries wegen einer Kollision braucht, wäre das kein Problem. Wenn aber im Auslösefall ein setState verloren ginge oder einen falschen Zustand auslösen würde wäre das fatal.
Viele Grüße
Andi -
@andreasph
Entschuldige die späte Reaktion - das Forum hat mich nicht auf deine Nachricht hingewiesen.Es funktioniert insgesamt schon recht gut. Die Kollisionen sind etwas nervig. Ich wollte das Script noch anpassen, dass es die Objekte im IObroker erst setzt, wenn auch die letzte Werteabfrage ohne Kollision passiert ist. Alternativ wäre es eine Möglichkeit auf den Bus zu hören, das Ende der Abfrage vom Internetmodul abzuwarten und direkt danach die eigene Abfrage zu starten. Damit müsste die Kollision weg sein.
Werte setzen habe ich bisher noch nicht implementiert. Ist auch auf der Todo-Liste. Sofern die Kollision oben gelöst ist sollte es auch kein Problem sein einen Wert zu setzen. Durch nochmaliges Abfragen vom Wert kann festgestellt werden, ob die Übertragung erfolgreich war.
Grüße,
Kachel
-
@kachel bist Du ggf. dazu gekommen, die set-Befehle zu implementieren? Liegt das Skript auch bspw. in github. Lieben Dank vorab.
-
Genial! Hat denn hier schon jemand weiter gemacht?
-
@knxbroker bei mir ging es leider nicht weiter. Ich stehe aber auch kurz davor, mir die Kombination einzubauen. Mir wäre allerdings wichtig, zu hören, ob es über einen längeren Zeitraum auch "robust" funktioniert, da die Installation schon aufwändiger ist (habe bisher nicht den SYR Universalflansch in der Leitung). Cool wäre halt, wenn dann alles noch gut läuft, wenn das Backend des Herstellers nicht mehr zur Verfügung steht.
-
Ich bin gerade dran eine Lösung mittels NodeRed zu realisieren, allerdings im ersten Schritt parallel zu den Cloud Abfragen. Solange die Cloud aktiv ist, werde ich dies wahrscheinlich auch so belassen. Läuft bisher ganz gut, aber mir fehlen noch ein paar Kommandos bis ich mein Ergebnis veröffentlichen werde.
Bin vor einiger Zeit zu Home Assistant gewechselt und werde dort meine Lösung auch präsentieren, sobald ich fertig bin. Den Link werde ich natürlich hier posten. -
@knxbroker das klingt doch gut - wäre ich natürlich auch sehr interessiert dran (gerade an dem NodeRed-Teil) - danke schon einmal vorab.
-
@knxbroker bist Du ggf. schon weitergekommen? Danke vorab.
-
@dmq nicht wirklich, das Thema hat im Sommer leider keine Prio...
Falls von Interesse, hier schon mal Node Red Code zum Auslesen der Webserver Requests.
Die Einzelabfrage (komplett lokal) gestaltet sich als schwierig, da das interne LAN Modul immer dazwischen quatscht. Ich kann damit vorerst so leben, sollte es eines Tages die Cloud nicht mehr geben, dann werde ich das LAN Modul intern abklemmen.PS: Den Home Assistant spezifischen Teil habe ich in diesem Forum mal weggelassen.
[{"id":"c346de70e5a46098","type":"serial in","z":"7d9d3cbb2597cd82","name":"","serial":"07c6650d2ff49b41","x":190,"y":2340,"wires":[["9d3388838e7f0cb7","94a5d32d473eb13d","d2190ca65994c11d","c499ae1e1b0a14b5","b09321ac134f816a","4ce39c90acf1d1d5"]]},{"id":"7c813e64bee7583b","type":"function","z":"7d9d3cbb2597cd82","name":"getBAR Match","func":"// Get water pressure [bar]\nconst pattern = new RegExp(\"(?<=getbar\\\\r)(\\\\d*)\", \"i\");\nvar found = msg.payload.match(pattern);\nif (Array.isArray(found)) {\n msg.payload = Math.round(found[0].replace(',', '.') / 100) / 10;\n return msg;\n} else {\n return null;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":2640,"wires":[[]]},{"id":"0e3a4af116c977f1","type":"function","z":"7d9d3cbb2597cd82","name":"getVOL Match","func":"// Get total water volume [L]\nconst pattern = new RegExp(\"(?<=Vol\\\[L\\\])(\\\\d*)\", \"i\");\nvar found = msg.payload.match(pattern);\nif (Array.isArray(found)) {\n msg.payload = found[0].replace(',', '.');\n return msg;\n} else {\n return null;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":2700,"wires":[[]]},{"id":"9d3388838e7f0cb7","type":"delay","z":"7d9d3cbb2597cd82","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"minute","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":340,"y":2640,"wires":[["7c813e64bee7583b","0e3a4af116c977f1","1115f0f138466e0c","f424d047f8af2bea"]]},{"id":"1115f0f138466e0c","type":"function","z":"7d9d3cbb2597cd82","name":"getBAR Match","func":"// Get water pressure [Bar]\nconst pattern = new RegExp(\"(?<=getBat\\\\r)(\\\\d*,\\\\d*)\", \"i\");\nvar found = msg.payload.match(pattern);\nif (Array.isArray(found)) {\n msg.payload = Math.round(found[0].replace(',', '.') * 10) / 10;\n return msg;\n} else {\n return null;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":2760,"wires":[[]]},{"id":"f424d047f8af2bea","type":"function","z":"7d9d3cbb2597cd82","name":"getCEL Match","func":"// Get water temperature [°C]\nconst pattern = new RegExp(\"(?<=getCel\\\\r)(\\\\d*)\", \"i\");\nvar found = msg.payload.match(pattern);\nif (Array.isArray(found)) {\n msg.payload = found[0].replace(',', '.') / 10;\n return msg;\n} else {\n return null;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":2820,"wires":[[]]},{"id":"94a5d32d473eb13d","type":"function","z":"7d9d3cbb2597cd82","name":"getAB Match","func":"// Get valve status [1= Open / 2 = Closed]\nconst pattern = new RegExp(\"(?<=getAB\\\\r)(\\\\d*)\", \"i\");\nvar found = msg.payload.match(pattern);\nif (Array.isArray(found)) {\n msg.payload = Math.abs(found[0] - 2); // HA specific adaption\n return msg;\n} else {\n return null;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":590,"y":2460,"wires":[[]]},{"id":"d2190ca65994c11d","type":"function","z":"7d9d3cbb2597cd82","name":"getALA Match","func":"// Get alarms\nconst pattern = new RegExp(\"(?<=getALA\\\\r)(.*)\", \"i\");\nvar found = msg.payload.match(pattern);\nif (Array.isArray(found)) {\n var failure;\n var issue = true;\n switch (found[0]) {\n case \"A1\":\n failure = \"Absperrung defekt\"\n break;\n case \"A2\":\n failure = \"Kein Turbinen-Signal\"\n break;\n case \"A3\":\n failure = \"Anwesenheits-Leckage\"\n break;\n case \"A4\":\n failure = \"Durchfluss-Leckage\"\n break;\n case \"A5\":\n failure = \"Abwesenheits-Leckage\"\n break;\n case \"A6\":\n failure = \"Bodensensor-Leckage\"\n break;\n case \"A7\":\n failure = \"Leckage an Eingang IN2\"\n break;\n case \"FF\":\n failure = \"Keine\";\n issue = false;\n break;\n default:\n failure = \"Unbekannte Störung \" + found;\n }\n msg.payload = failure;\n msg.issue = issue;\n return msg;\n} else {\n return null;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":2520,"wires":[[]]},{"id":"c499ae1e1b0a14b5","type":"function","z":"7d9d3cbb2597cd82","name":"getTMP Match","func":"// Get temporary inactivity time [s]\nconst pattern = new RegExp(\"(?<=getTMP\\\\r)(\\\\d*)\", \"i\");\nvar found = msg.payload.match(pattern);\nif (Array.isArray(found)) {\n msg.payload = found[0];\n return msg;\n} else {\n return null;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":2400,"wires":[[]]},{"id":"b09321ac134f816a","type":"function","z":"7d9d3cbb2597cd82","name":"getUL Match","func":"// Get presense\nconst pattern = new RegExp(\"(?<=getUL\\\\r)(\\\\d*)\", \"i\");\nvar found = msg.payload.match(pattern);\nif (Array.isArray(found)) {\n if (found[0] == 0) {\n msg.payload = true;\n return msg;\n }\n else {\n msg.payload = false;\n return msg;\n }\n} else {\n return null;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":590,"y":2340,"wires":[[]]},{"id":"4ce39c90acf1d1d5","type":"function","z":"7d9d3cbb2597cd82","name":"getLE Match","func":"// Get current water limit [L]\nconst pattern = new RegExp(\"(?<=getLE\\\\r)(\\\\d*)\", \"i\");\nvar found = msg.payload.match(pattern);\nif (Array.isArray(found)) {\n msg.payload = found[0]*50;\n return msg;\n} else {\n return null;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":590,"y":2580,"wires":[[]]},{"id":"d9ef234728f55896","type":"comment","z":"7d9d3cbb2597cd82","name":"Anwesendheit","info":"","x":850,"y":2340,"wires":[]},{"id":"8c0b98a0743a69a4","type":"comment","z":"7d9d3cbb2597cd82","name":"Temporäre Inaktivität","info":"","x":870,"y":2400,"wires":[]},{"id":"f8dd9b2a4b0d85fb","type":"comment","z":"7d9d3cbb2597cd82","name":"Auslesen von WebServer Requests","info":"","x":260,"y":2260,"wires":[]},{"id":"edce790ca722ef59","type":"comment","z":"7d9d3cbb2597cd82","name":"Ventilstatus","info":"","x":850,"y":2460,"wires":[]},{"id":"7e4e1d3dbd0ef890","type":"comment","z":"7d9d3cbb2597cd82","name":"Alarm","info":"","x":830,"y":2520,"wires":[]},{"id":"ef3777ab8741ac8f","type":"comment","z":"7d9d3cbb2597cd82","name":"Wasserlimit","info":"","x":850,"y":2580,"wires":[]},{"id":"8369c6d71aa2f63a","type":"comment","z":"7d9d3cbb2597cd82","name":"Wasserdruck","info":"","x":850,"y":2640,"wires":[]},{"id":"242b89811638941f","type":"comment","z":"7d9d3cbb2597cd82","name":"Volumen Gesamt","info":"","x":860,"y":2700,"wires":[]},{"id":"6cedcffe51a141e9","type":"comment","z":"7d9d3cbb2597cd82","name":"Wasserdruck","info":"","x":850,"y":2760,"wires":[]},{"id":"836ac7537e1cce37","type":"comment","z":"7d9d3cbb2597cd82","name":"Wassertemperatur","info":"","x":870,"y":2820,"wires":[]},{"id":"07c6650d2ff49b41","type":"serial-port","serialport":"/dev/ttyUSB1","serialbaud":"19200","databits":"8","parity":"none","stopbits":"1","waitfor":"","dtr":"none","rts":"none","cts":"none","dsr":"none","newline":"2000","bin":"false","out":"interbyte","addchar":"","responsetimeout":"300"}]
-
@dmq Und hier Node Red Code zur Steuerung, wieder ohne Home Assistant Knoten.
ToDo: Bestätigung von Alarm Meldungen!
Steuerung ist ebenfalls vom WebServer abhängig und somit nicht lokal. Der Code wartet auf die WebServer Abfrage und schickt danacht Befehle los, um eine Kollision zu vermeiden.
[{"id":"d2dddf837a5f48b7","type":"function","z":"7d9d3cbb2597cd82","name":"Wait for msg.release","func":"const messages = context.get('messages') || [];\n\nif(msg.release) {\n context.set('messages', null);\n node.status({text: `Sent: ${messages.length}`});\n return [messages];\n}\n\nmessages.push(msg);\ncontext.set('messages', messages);\nnode.status({text: `Holding: ${messages.length}`});","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":720,"y":2580,"wires":[["9f5e2b7a9f1ee9da"]]},{"id":"850c0728ec1a735c","type":"change","z":"7d9d3cbb2597cd82","name":"","rules":[{"t":"set","p":"release","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":410,"y":2440,"wires":[["d2dddf837a5f48b7"]]},{"id":"2841702637ee5a33","type":"function","z":"7d9d3cbb2597cd82","name":"setAB2","func":"// Close the vavle\nvar cmdstart = Buffer.from(\"0d0a1b313a\", \"hex\");\nvar cmdmiddle = Buffer.from(\"setAB2\");\nvar cmdend = Buffer.from(\"0d0a\", \"hex\"); // cR + LF\nmsg.payload = Buffer.concat([cmdstart, cmdmiddle, cmdend]);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":400,"y":2520,"wires":[["d2dddf837a5f48b7"]]},{"id":"7ec7b7f3b2be5f8b","type":"function","z":"7d9d3cbb2597cd82","name":"setAB1","func":"// Open the vavle\nvar cmdstart = Buffer.from(\"0d0a1b313a\", \"hex\");\nvar cmdmiddle = Buffer.from(\"setAB1\");\nvar cmdend = Buffer.from(\"0d0a\", \"hex\"); // CR + LF\nmsg.payload = Buffer.concat([cmdstart, cmdmiddle, cmdend]);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":400,"y":2580,"wires":[["d2dddf837a5f48b7"]]},{"id":"3bc209160cce93a1","type":"serial in","z":"7d9d3cbb2597cd82","name":"","serial":"07c6650d2ff49b41","x":170,"y":2440,"wires":[["850c0728ec1a735c"]]},{"id":"41ad879c02123e89","type":"function","z":"7d9d3cbb2597cd82","name":"setTmp0","func":"// Set temporary inactivity time to 0s\nvar cmdstart = Buffer.from(\"0d0a1b313a\", \"hex\");\nvar cmdmiddle = Buffer.from(\"setTMP0\");\nvar cmdend = Buffer.from(\"0d\", \"hex\");\nmsg.payload = Buffer.concat([cmdstart, cmdmiddle, cmdend]);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":400,"y":2740,"wires":[["d2dddf837a5f48b7"]]},{"id":"fce9cff1374cce55","type":"function","z":"7d9d3cbb2597cd82","name":"setTmp14400","func":"// Set temporary inactivity time to 4h\nvar cmdstart = Buffer.from(\"0d0a1b313a\", \"hex\");\nvar cmdmiddle = Buffer.from(\"setTMP14400\");\nvar cmdend = Buffer.from(\"0d\", \"hex\");\nmsg.payload = Buffer.concat([cmdstart, cmdmiddle, cmdend]);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":2680,"wires":[["d2dddf837a5f48b7"]]},{"id":"46a371ee6322b0b8","type":"comment","z":"7d9d3cbb2597cd82","name":"SYR Connect - Control ","info":"","x":200,"y":2380,"wires":[]},{"id":"55aa5d6d321d51ec","type":"function","z":"7d9d3cbb2597cd82","name":"setUL0","func":"// Close the vavle\nvar cmdstart = Buffer.from(\"0d0a1b313a\", \"hex\");\nvar cmdmiddle = Buffer.from(\"setUL0\");\nvar cmdend = Buffer.from(\"0d0a\", \"hex\"); // cR + LF\nmsg.payload = Buffer.concat([cmdstart, cmdmiddle, cmdend]);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":400,"y":2820,"wires":[["d2dddf837a5f48b7"]]},{"id":"abef738776e765eb","type":"function","z":"7d9d3cbb2597cd82","name":"setUL3","func":"// Open the vavle\nvar cmdstart = Buffer.from(\"0d0a1b313a\", \"hex\");\nvar cmdmiddle = Buffer.from(\"setUL3\");\nvar cmdend = Buffer.from(\"0d0a\", \"hex\"); // CR + LF\nmsg.payload = Buffer.concat([cmdstart, cmdmiddle, cmdend]);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":400,"y":2880,"wires":[["d2dddf837a5f48b7"]]},{"id":"e3b1591eaec5c765","type":"comment","z":"7d9d3cbb2597cd82","name":"Ventil Zu","info":"","x":160,"y":2520,"wires":[]},{"id":"9a432a6df02f8f39","type":"comment","z":"7d9d3cbb2597cd82","name":"Ventil Auf","info":"","x":160,"y":2580,"wires":[]},{"id":"996ebd2f1e184a87","type":"comment","z":"7d9d3cbb2597cd82","name":"Anwesend","info":"","x":160,"y":2820,"wires":[]},{"id":"95ab097536ee9cf2","type":"comment","z":"7d9d3cbb2597cd82","name":"Abwesend (30L)","info":"","x":180,"y":2880,"wires":[]},{"id":"b25ef65f1a65fc12","type":"comment","z":"7d9d3cbb2597cd82","name":"Inaktiv Timer 4h","info":"","x":180,"y":2680,"wires":[]},{"id":"bc165e6cd206e810","type":"comment","z":"7d9d3cbb2597cd82","name":"Inaktiv Timer Aus","info":"","x":180,"y":2740,"wires":[]},{"id":"344b580893fb384e","type":"serial out","z":"7d9d3cbb2597cd82","name":"","serial":"07c6650d2ff49b41","x":730,"y":2720,"wires":[]},{"id":"9f5e2b7a9f1ee9da","type":"delay","z":"7d9d3cbb2597cd82","name":"","pauseType":"delay","timeout":"300","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":720,"y":2660,"wires":[["f4043b8aa0ba6a4e","344b580893fb384e"]]},{"id":"07c6650d2ff49b41","type":"serial-port","serialport":"/dev/ttyUSB1","serialbaud":"19200","databits":"8","parity":"none","stopbits":"1","waitfor":"","dtr":"none","rts":"none","cts":"none","dsr":"none","newline":"2000","bin":"false","out":"interbyte","addchar":"","responsetimeout":"300"}]
-
@knxbroker besten Dank dafür. Schaue ich mir mal in Ruhe an.
-
Hi @dmq, und alle anderen die daran Interesse haben:
Habe nun auch die Bestätigung von Alarmmeldungen in Node Red Implementiert, ich verweise hier einfach mal auf meinen Post im Home Assistant Forum:
Eine komplette Offline Lösung sollte eigentlich auch nicht so schwer sein zu implementieren, aber für mich erstmal so okay.
-
@knxbroker danke fürs informieren und freigeben. Ich habe die Komponenten hier, aber noch nicht physisch eingebaut (überlege auch noch ob ich es selbst einbaue oder (versuche) einbauen zu lassen. Daran hängt leider mein Fortschritt mich da tiefer einzuarbeiten und hoffentlich auch mal was sinnvolles zurückzugeben
-
-
Die hier gezeigte Loesung waere mein Plan B gewesen, vielen Dank euch allen, die sich hier soviel Arbeit machen und alles und jeden Schritt dokumentieren!
Wer das hier findet, und vielleicht lieber ein Adapter installiert (leider wird zur Zeit noch ein dns-routing und webserver(alternativ iptables) gebraucht. Ist aber kein Hexenwerk zum installieren.
Der Adapter unterstuetzt seit heute auch die SyrLexPlus10SL.
https://github.com/eifel-tech/ioBroker.syrconnect