@apollon77 Done!
NEWS
Best posts made by LevyKo
-
RE: [Gelöst] Adapter Smartmeter per ser2net und socat
Das Problem ist gelöst!Dies ist das Device oder besser gesagt der Symlink, welcher von "socat" angelegt wird:
lrwxrwxrwx 1 root root 10 Sep 1 14:53 ttyVSP0 -> /dev/pts/1
Folgt man dem Symlink, kommt das dabei heraus:
crw--w---- 1 root tty 136, 1 Sep 1 14:53 1
Da ioBroker unter dem Benutzer iobroker läuft, hat der Smartmeter-Adapter also gar keine Möglichkeit, das serielle Device anzusprechen.
Gegenprobe: Auf der Konsole als root (oder per sudo) den folgenden Befehl ausführen. Dieser sollte den Smartmeter-Adapter starten, die Datenpunkte im ioBroker anlegen und natürlich auch die Werte aktualisieren.
node smartmeter.js --force --logs
Um die Berechtigungen dahingehend anzupassen, dass auch ioBroker auf das Device zugreifen darf, kann sollte man direkt ein chmod auf /dev/pts/1 ausführen und danach die Datei /etc/fstab anpassen. Nach Anpassung der Datei werden die entsprechenden Recht direkt bei Systemstart eingetragen bzw. die Devices werden direkt mit den richtigen Rechten angelegt.Von nun an funktioniert der Smartmeter-Adapter einwandfrei.Viele Grüße
Levy
Latest posts made by LevyKo
-
RE: Test Adapter myPorsche v0.0.x
Hallo zusammen,
da der Adapter leider mittlerweile nach kurzer Laufzeit nur Fehler produziert und immer wieder neu startet und letztendlich dann durch den ioBroker Server gestoppt wird (Restart-Loop), ist er leider unbrauchbar geworden.
Wenn ich so auf Github schaue, dürfte die Weiterentwicklung dieses Adapters auch tot sein. Schade...
Viele Grüße
Levy -
RE: In einer Funktion auf Änderung eines Datenpunkts warten
@paul53
Danke für die Überarbeitung. Das sieht doch wesentlich kompakter ausJa, toLog() ist eine globale Funktion, die mir eine Aktivitätsliste füllt und gleichzeitig einen Log-Eintrag erstellt.
Da neben der Steuerung des Tors in dem eigentlichen Script noch die Regelung eines Lüfters drin ist, hier mal der aktuelle Stand des gesamten Scripts:
/* ** ** Steuerung Garage ** */ var cronVal = '*/15 * * * *'; var numMinDuration = 30; var dpAussenTemperatur = 'hm-rpc.0.00XXXXXXXXXXEF.1.ACTUAL_TEMPERATURE'; var dpAussenFeuchtigkeit = 'hm-rpc.0.00XXXXXXXXXXEF.1.HUMIDITY'; var dpGarageFeuchtigkeit = 'hm-rpc.0.00XXXXXXXXXX5F.1.HUMIDITY'; var dpGarageLuefter = 'hm-rpc.0.00XXXXXXXXXX9D.3.STATE'; const dpGarageDoorOpen = '0_userdata.0.Trigger.TriggerGarageDoorOpen'; const dpGarageDoorClose = '0_userdata.0.Trigger.TriggerGarageDoorClose'; const dpGarageDoorStatus = '0_userdata.0.Trigger.TriggerGarageDoorStatus'; const dpGarageDoorState = 'hm-rpc.0.00XXXXXXXXXXF7.1.DOOR_STATE'; const dpGarageDoorCommand = 'hm-rpc.0.00XXXXXXXXXXF7.1.DOOR_COMMAND'; var doorState = getState(dpGarageDoorState).val; /* ** Create Datapoints */ createState(dpGarageDoorOpen, false, { name: 'TriggerGarageDoorOpen', desc: 'TriggerGarageDoorOpen', type: 'boolean', role: 'state' }); createState(dpGarageDoorClose, false, { name: 'TriggerGarageDoorClose', desc: 'TriggerGarageDoorClose', type: 'boolean', role: 'state' }); createState(dpGarageDoorStatus, '-', { name: 'TriggerGarageDoorStatus', desc: 'TriggerGarageDoorStatus', type: 'string', role: 'value' }); /* ** Subscriptions */ schedule(cronVal, function() { if(getState(dpGarageLuefter).val === false) { if(getState(dpGarageFeuchtigkeit).val > getState(dpAussenFeuchtigkeit).val) { if(getState(dpAussenTemperatur).val > 5) { if(getState(dpAussenTemperatur).val < 20) { var numMilSecsDur = numMinDuration * 60000; var endTime = Date.now() + numMilSecsDur; setState(dpGarageLuefter, true); toLog('Garagenbelüftung eingeschaltet (Dauer: ' + numMinDuration + ' - Lf: ' + getState(dpGarageFeuchtigkeit).val + '%)'); var sHandler = schedule(endTime, function () { setState(dpGarageLuefter, false); toLog('Garagenbelüftung ausgeschaltet (Lf: ' + getState(dpGarageFeuchtigkeit).val + '%)'); clearSchedule(sHandler); }); } } } } }); on ({id: dpGarageDoorOpen, change: 'ne', val: true}, function () { if(doorState != 1) { setState(dpGarageDoorCommand, 1); setState(dpGarageDoorStatus, 'wird geöffnet', true); } setState(dpGarageDoorOpen, false, true); }); on ({id: dpGarageDoorClose, change: 'ne', val: true }, function () { if(doorState > 0) { setState(dpGarageDoorCommand, 3); setState(dpGarageDoorStatus, 'wird geschlossen', true); } setState(dpGarageDoorClose, false, true); }); on (dpGarageDoorState, function (dp) { doorState = dp.state.val; let msg = ''; if(doorState === 0) { msg = 'geschlossen'; } else if(doorState === 1) { msg = 'offen'; } if(msg) { setState(dpGarageDoorStatus, msg, true); toLog('Das Garagentor ist ' + msg); } });
Vielleicht kann der eine oder andere davon etwas gebrauchen.
Viele Grüße
Levy -
RE: In einer Funktion auf Änderung eines Datenpunkts warten
Erst einmal vielen Dank für die Antworten und Denkanstöße. Ich habe es jetzt, wie von Euch vorgeschlagen, mit vier on()'s realisiert. Hier mal das komplette Script:
var dpGarageDoorOpen = '0_userdata.0.Trigger.TriggerGarageDoorOpen'; var dpGarageDoorClose = '0_userdata.0.Trigger.TriggerGarageDoorClose'; var dpGarageDoorStatus = '0_userdata.0.Trigger.TriggerGarageDoorStatus'; var dpGarageDoorState = 'hm-rpc.0.00XXXXXXXXXXF7.1.DOOR_STATE'; var dpGarageDoorCommand = 'hm-rpc.0.00XXXXXXXXXXF7.1.DOOR_COMMAND'; var dpGarageDoorProcess = 'hm-rpc.0.00XXXXXXXXXXF7.1.PROCESS'; on ({ id: dpGarageDoorOpen, change: 'ne', val: true }, function () { if(getState(dpGarageDoorState).val === 0 || getState(dpGarageDoorState).val === 2 || getState(dpGarageDoorState).val === 3) { setState(dpGarageDoorCommand, 1); } else { setState(dpGarageDoorOpen, false); setState(dpGarageDoorClose, false); } }); on ({ id: dpGarageDoorClose, change: 'ne', val: true }, function () { if(getState(dpGarageDoorState).val === 1 || getState(dpGarageDoorState).val === 2 || getState(dpGarageDoorState).val === 3) { setState(dpGarageDoorCommand, 3); } else { setState(dpGarageDoorOpen, false); setState(dpGarageDoorClose, false); } }); on ({ id: dpGarageDoorProcess, change: 'ne' }, function () { if(getState(dpGarageDoorOpen).val == true) { if(getState(dpGarageDoorProcess).val === 1) setState(dpGarageDoorStatus, 'wird geöffnet'); } if(getState(dpGarageDoorClose).val == true) { if(getState(dpGarageDoorProcess).val === 1) setState(dpGarageDoorStatus, 'wird geschlossen'); } }); on ({ id: dpGarageDoorState, change: 'ne' }, function () { if(getState(dpGarageDoorState).val === 0) { setState(dpGarageDoorStatus, 'geschlossen'); setState(dpGarageDoorOpen, false); setState(dpGarageDoorClose, false); toLog('Das Garagentor wurde geschlossen'); } if(getState(dpGarageDoorState).val === 1) { setState(dpGarageDoorStatus, 'offen'); setState(dpGarageDoorOpen, false); setState(dpGarageDoorClose, false); toLog('Das Garagentor wurde geöffnet'); } });
Da kann ich sicherlich noch einiges optimieren, aber so läuft es jetzt ersteinmal. Rein muss für den normalen Betrieb noch die Abfrage nach Blockade und Drücken von Stop.
Hintergrund ist, dass bisher für VIS einfach direkt auf die Datenpunkte des HmIP-MOD-HO gegangen bin. Das funktionierte soweit auch. Nun wird die Garage aber als separate Zone in unsere Alarmanlage integriert und ich muss ein "versehentliches" Öffnen durch VIS bei Scharfschaltung verhindern. Das kann ich über das Script alles abfangen. Zusätzlich kann ich nun über Alexa vom Auto aus (nennt sich bei Audi "integrated Alexa" oder so) das Tor auf- und zufahren. Daher die beiden Trigger-Datenpunkte.
Viele Grüße
Levy -
In einer Funktion auf Änderung eines Datenpunkts warten
Hallo zusammen,
ich stehe gerade auf dem Schlauch: Innerhalb einer Funktion, die über on() getriggert wird, nutze ich ein setState(), um einen Aktor zu starten. Als nächstes soll ein Datenpunkt überwacht werden und erst, wenn dieser auf einen bestimmten Wert geht, soll die Funktion weiter abgearbeitet werden. Ist sowas überhaupt möglich?
Das mit dem while() im folgenden Code ist Quatsch, aber vielleicht ist das verständlicher :
function garageDoorOpen() { if(getState(dpGarageDoorState).val == 0 || getState(dpGarageDoorState).val == 2) { setState(dpGarageDoorCommand, 1); setState(dpInstanz + dpGarageDoorStatus, txtGarageDoorOpen); while(getState(dpGarageDoorProcess).val === 1) { // An dieser Stelle soll die Funktion solange warten, // bis "getState(dpGarageDoorProcess).val === 1" ist } setState(dpInstanz + dpGarageDoorStatus, txtGarageDoorIsOpened); setState(dpInstanz + dpGarageDoorOpen, false); } } on ({ id: dpInstanz + dpGarageDoorOpen, change: 'any', val: true }, function () { garageDoorOpen(); });
Viele Grüße
Levy -
RE: [Gelöst] Adapter Smartmeter per ser2net und socat
@arteck
Aaaaarggghhh... die Lösung ist so nah! Bitte vergiss socat. Das braucht man mittlerweile nicht mehr. Auf der einen Seite ser2net ist korrekt und dann im smartmeter-Adapter einfach die Konfiguration in der Zeile "Datenübertragung" auf "Netzwerk/TCP-Daten werden nur gelesen" setzen.Dann kann man im mittleren Bereich unter "TCP Server" und "TCP Port" die Daten von ser2net eintragen und es läuft.
Vielen Dank @apollon77 für dieses Feature!!! Muss socat trotzdem installiert bleiben, weil der Adapter diesen Dienst lokal nutzt oder kann das weg?
-
RE: [Gelöst] Adapter Smartmeter per ser2net und socat
@arteck
An dieser Problematik sitze ich jetzt auch schon eine Weile. ser2net läuft ziemlich stabil, aber socat verliert ab und zu die Verbindung. Leider habe ich bisher noch keinen Weg gefunden, dies zu überwachen und im Fall der Fälle einen Reload bzw. Restart auszuführen. Ich hatte es mal mit der Dienstüberwachung probiert (auch per externem Script), aber leider zeigt socat ein "Alles in Ordnung" an, obwohl die Verbindung nicht da ist. Per Status oder PID fällt somit eine Überwachung weg.Am Optimalsten wäre es immer noch, wenn der smartmeter-Adapter selbst eine socat-Anbindung anbieten könnte. Der Adapter "sieht" ja, wenn keine Daten kommen und könnte den Dienst neu starten.
-
RE: ioBroker richtig aufräumen (bereits gelöschte Adapter)
@thomas-braun
Ah, ok, das war mir tatsächlich nicht bewußt. Ich ging davon aus, dass npm zwar userabhängige configs im home anlegt, aber ansonsten verzeichnisabhängig arbeitet.Ich fahre hier ein gehärtetes Debian Buster mit Zertifikatslogin, bei dem einige Systemdateien auch vor Sudoern geschützt sind. Daher komme ich z. B. mit sudo vi nicht an /lib/systemd/system/socat-service ran. Da hilft nur ein sudo -s oder su - mit cert-auth. Das ist leider das Resultat, wenn man ein Installations-Image aus dem RZ verwendet. Unsere Server laufen dort mit dieser gehärteten Debian Variante. Ich setze das System, wie gesagt, einmal komplett neu mit dem normalen Bullseye auf. Dann habe ich das gehampel mit den Sudoern und Zertifikaten nicht mehr.
Viele Grüße
Levy -
RE: ioBroker richtig aufräumen (bereits gelöschte Adapter)
Ich passe parallel gerade ein paar confs für den systemd an, daher war ich "mal eben" per sudo -s als root drin. Den ganzen Rest mache ich natürlich nicht mit root, sondern mit meinem eigenen Benutzer oder halt normalem sudo. Da es keinen Unterschied macht, ob ich npm prune bzw. npm ls als root, iobroker-user oder unter meinem eigenen login-user ausführe (da npm unabhängig von iobroker installiert ist), habe ich jetzt nicht kurz ein exit reingetippt. War mir nicht bewusst, dass dies jetzt nun so ein Akt ist... Mea culpa...
Aber egal, ich setze morgen eine neue VM auf und installiere den ioBroker neu. Ist wahrscheinlich die sauberste Methode.
Viele Grüße
Levy -
RE: ioBroker richtig aufräumen (bereits gelöschte Adapter)
Das hier sind die aktuellen und genutzten Adapter bzw. Module:
root@iobroker:/opt/iobroker/node_modules# ls -al | grep iobroker.* grep: iobroker.backitup: Ist ein Verzeichnis grep: iobroker.daswetter: Ist ein Verzeichnis grep: iobroker.devices: Ist ein Verzeichnis grep: iobroker.discovery: Ist ein Verzeichnis grep: iobroker.dwd: Ist ein Verzeichnis grep: iobroker.hm-rega: Ist ein Verzeichnis grep: iobroker.hm-rpc: Ist ein Verzeichnis grep: iobroker.hue: Ist ein Verzeichnis grep: iobroker.ical: Ist ein Verzeichnis grep: iobroker.influxdb: Ist ein Verzeichnis grep: iobroker.info: Ist ein Verzeichnis grep: iobroker.iot: Ist ein Verzeichnis grep: iobroker.javascript: Ist ein Verzeichnis grep: iobroker.js-controller: Ist ein Verzeichnis grep: iobroker.modbus: Ist ein Verzeichnis grep: iobroker.ping: Ist ein Verzeichnis grep: iobroker.pushover: Ist ein Verzeichnis grep: iobroker.scenes: Ist ein Verzeichnis grep: iobroker.simple-api: Ist ein Verzeichnis grep: iobroker.smartmeter: Ist ein Verzeichnis grep: iobroker.viessmannapi: Ist ein Verzeichnis grep: iobroker.vis: Ist ein Verzeichnis grep: iobroker.vis-google-fonts: Ist ein Verzeichnis grep: iobroker.vis-icontwo: Ist ein Verzeichnis grep: iobroker.vis-inventwo: Ist ein Verzeichnis grep: iobroker.vis-map: Ist ein Verzeichnis grep: iobroker.vis-timeandweather: Ist ein Verzeichnis grep: iobroker.vw-connect: Ist ein Verzeichnis grep: iobroker.web: Ist ein Verzeichnis grep: iobroker.wled: Ist ein Verzeichnis grep: iobroker.ws: Ist ein Verzeichnis grep: iobroker.ws.server: Ist ein Verzeichnis grep: iobroker.yahka: Ist ein Verzeichnis root@iobroker:/opt/iobroker/node_modules#
-
RE: ioBroker richtig aufräumen (bereits gelöschte Adapter)
Die Ausgabe von 'npm prune':
root@iobroker:/opt/iobroker# npm prune npm WARN crc@4.1.1 requires a peer of buffer@>=6.0.3 but none is installed. You must install peer dependencies yourself. npm WARN retry-axios@2.6.0 requires a peer of axios@* but none is installed. You must install peer dependencies yourself. removed 545 packages in 81.656s 141 packages are looking for funding run `npm fund` for details
und dieser Rattenschwanz bei 'npm ls':
root@iobroker:/opt/iobroker# npm ls iobroker.inst@1.1.2 /opt/iobroker ├─┬ canvas@2.8.0 │ ├─┬ @mapbox/node-pre-gyp@1.0.5 │ │ ├── detect-libc@1.0.3 │ │ ├─┬ https-proxy-agent@5.0.0 │ │ │ ├─┬ agent-base@6.0.2 ----- ├── UNMET DEPENDENCY iobroker.hue-extended@^2.0.0 ├── UNMET DEPENDENCY iobroker.hyperion_ng@github:felixganzer/ioBroker.hyperion_ng#eb2814e60d4ee5f51b49f6c4f93b00e65bf5a280 ├─┬ iobroker.ical@1.13.1 │ ├─┬ @iobroker/adapter-core@2.6.0 │ │ └─┬ @types/iobroker@4.0.4 │ │ └── @types/node@12.7.2 deduped │ ├─┬ axios@0.27.2 │ │ ├── follow-redirects@1.14.9 deduped │ │ └─┬ form-data@4.0.0 │ │ ├── asynckit@0.4.0 deduped │ │ ├── combined-stream@1.0.8 deduped │ │ └── mime-types@2.1.24 deduped │ ├── cloneextend@0.0.3 │ ├── json-schema@0.4.0 │ ├─┬ node-ical@0.15.1 ----- │ ├─┬ call-bind@1.0.2 │ │ ├── function-bind@1.1.1 deduped │ │ └── get-intrinsic@1.0.2 deduped │ ├── es-abstract@1.19.1 deduped │ ├── foreach@2.0.5 deduped │ ├── has-tostringtag@1.0.0 deduped │ └── is-typed-array@1.1.8 deduped └── UNMET DEPENDENCY iobroker.zigbee@^1.4.2 npm ERR! missing: iobroker.alexa2@^3.9.3, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.cameras@^0.1.3, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.flot@^1.10.2, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.hue-extended@^2.0.0, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.hyperion_ng@github:felixganzer/ioBroker.hyperion_ng#eb2814e60d4ee5f51b49f6c4f93b00e65bf5a280, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.icons-material-png@^0.1.0, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.icons-material-svg@^0.1.0, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.icons-mfd-svg@^1.0.2, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.luftdaten@0.0.6, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.mqtt@^2.1.7, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.onvif@^0.4.4, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.parser@^1.0.7, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.robonect@https://github.com/braindead1/ioBroker.robonect/tarball/master, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.shelly@6.0.0, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.socketio@^2.1.1, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.sonoff@^2.4.0, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.sonos@^2.1.0, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.sony-bravia@^1.0.1, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.sql@^1.15.2, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.synology@^1.0.0, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.tankerkoenig@^2.1.1, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.text2command@^1.2.5, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.tr-064@^0.4.18, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.type-detector@file:node_modules/iobroker.type-detector, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.unifi@^0.3.1, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.viessmann@^1.2.4, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.vis-bars@^0.1.4, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.vis-canvas-gauges@^0.1.5, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.vis-jqui-mfd@^1.0.12, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.vis-keyboard@https://github.com/ioBroker/ioBroker.vis-keyboard/tarball/master, required by iobroker.inst@1.1.2 npm ERR! missing: iobroker.zigbee@^1.4.2, required by iobroker.inst@1.1.2 npm ERR! peer dep missing: buffer@>=6.0.3, required by crc@4.1.1 npm ERR! peer dep missing: axios@*, required by retry-axios@2.6.0
Da, wo ich die ----- hingesetzt habe stehen alle möglichen Module, so dass mir die Seite hier ein "Payload too large" rausschmeißt. Daher gekürzt. Die "UNMET DEPENDENCY" Meldungen stehen bei den "Altlasten".
Bei den aufgeführten "npm ERR! missing:"-Meldungen handelt es sich ausschließlich um die Adapter, die ich gelöscht hatte und nicht mehr benutzt werden.
Viele Grüße
Levy