NEWS
[GELÖST] Zwei Geräte in e. Raum zuordnen (Echo - Thermostat)
-
Hi,
ich suche nach einer Möglichkeit in Javascript enum.rooms auszuwerten. Dafür habe ich Echo's und Heizungsthermostate in jeweils einen Raum geworfen. Das Skript soll jetzt herausfinden, welcher Echo den Befehl angenommen hat und anschliessend das im selben Raum befindliche Heizungsthermostat finden (hm-rpc).
Danach soll dann der Boost auf die Heizung ausgeführt werden.
Hat sowas schonmal jemand mit Javascript gemacht?
LG, Mitch
-
@mitch sagte: das im selben Raum befindliche Heizungsthermostat finden (hm-rpc).
HomeMatic hat die Besonderheit, dass Räume den Kanälen zugeordnet sind. Versuche mal diesen Ansatz:
on(idsEcho, function(dp) { let idRoom = getObject(dp.id, 'rooms').enumIds[0]; let members = getObject(idRoom).common.members; for(let id of members) { if(id.startsWith('hm-rpc.') && id.endsWith('.4')) setState(id + '.BOOST_MODE', true); } });
idsEcho
sollte sich per Selektor ermitteln lassen. -
@paul53 Das hat mir schon etwas weitergeholfen. Ich habe folgendes Skript aktuell am laufen, was auf deinem basiert:
on({id: "0_userdata.0.internet.test", change: "any"}, function (obj) { var rooms = getObject("enum.rooms.buero").common.members; setState('0_userdata.0.internet.teststring', rooms); let members = getObject(rooms).common.members; for(let id of members) { if(id.startsWith('hm-rpc.') && id.endsWith('.4')) setState(id + '.BOOST_MODE', true); } });
In teststring steht folgendes drin, was genau enum.rooms.buero entspricht:
"sonoff.0.Sonoff-02", "alexa2.0.Echo-Devices.G090U50784453GL9", "hm-rpc.0.000A1D89B0BFAD"
Aber er möchte das Device nicht schalten.
EDIT: Ich glaube es liegt an: id.endsWith('.4') Aber sicher bin ich nicht.
-
@mitch sagte: Ich glaube es liegt an: id.endsWith('.4')
Ändere es in id.endsWith('.1').
Oder sind die Räume nicht dem Kanal zugeordnet? "hm-rpc.0.000A1D89B0BFAD" ist das Gerät.
Falls die Zuordnung zum Gerät erfolgte, ändere Zeile 7 inif(id.startsWith('hm-rpc.')) setState(id + '.1.BOOST_MODE', true);
-
@paul53 PS: Das Forum sagt heute oft Forbitten...
Ich gebe zu, das ich das mit den Kanälen nicht verstanden habe. Bisher habe ich nur mit Räumen gearbeiten:
Das ist die ID des Datenpunkt:
hm-rpc.0.000A1D89B0BFAD.1.BOOST_MODEDein letzter Vorschlag klang plausibel und nachvollziehbar. Aber ich kriege folgende Fehlermeldung im Log:
javascript.0 2022-11-02 21:35:17.065 info Stop script script.js.common.timer.Boost_Heizung_15_Minuten admin.0 2022-11-02 21:35:11.489 info ==> Connected system.user.admin from ::ffff:192.168.15.152 javascript.0 2022-11-02 21:34:55.337 error at processImmediate (node:internal/timers:466:21) javascript.0 2022-11-02 21:34:55.337 error at Immediate._onImmediate (/opt/iobroker/node_modules/@iobroker/js-controller-adapter/src/lib/adapter/adapter.js:5909:56) javascript.0 2022-11-02 21:34:55.337 error at Object.stateChange (/opt/iobroker/node_modules/iobroker.javascript/main.js:596:29) javascript.0 2022-11-02 21:34:55.336 error at Object.callback (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1214:38) javascript.0 2022-11-02 21:34:55.336 error at Object.<anonymous> (script.js.common.timer.Boost_Heizung_15_Minuten:5:33) javascript.0 2022-11-02 21:34:55.335 error Error in callback: TypeError: Cannot read properties of null (reading 'common') javascript.0 2022-11-02 21:34:55.329 warn script.js.common.timer.Boost_Heizung_15_Minuten: Object "sonoff.0.Sonoff-02,alexa2.0.Echo-Devices.G090U50784453GL9,hm-rpc.0.000A1D89B0BFAD" does not exist javascript.0 2022-11-02 21:34:55.328 warn at processImmediate (node:internal/timers:466:21) javascript.0 2022-11-02 21:34:55.328 warn at Immediate._onImmediate (/opt/iobroker/node_modules/@iobroker/js-controller-adapter/src/lib/adapter/adapter.js:5909:56) javascript.0 2022-11-02 21:34:55.327 warn at Object.stateChange (/opt/iobroker/node_modules/iobroker.javascript/main.js:596:29) javascript.0 2022-11-02 21:34:55.327 warn at Object.callback (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1214:38) javascript.0 2022-11-02 21:34:55.327 warn at Object.<anonymous> (script.js.common.timer.Boost_Heizung_15_Minuten:4:3) javascript.0 2022-11-02 21:34:55.326 warn at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1689:20) javascript.0 2022-11-02 21:34:55.323 warn You are assigning a array to the state "0_userdata.0.internet.teststring" which expects a string. Please fix your code to use a string or change the state type to array. This warning might become an error in future versions.
So sieht das Skript jetzt aus:
on({id: "0_userdata.0.internet.test", change: "any"}, function (obj) { var rooms = getObject("enum.rooms.buero").common.members; setState('0_userdata.0.internet.teststring', rooms); let members = getObject(rooms).common.members; for(let id of members) { if(id.startsWith('hm-rpc.')) setState(id + '.1.BOOST_MODE', true); } });
-
@mitch sagte: You are assigning a array to the state "0_userdata.0.internet.teststring" which expects a string. Please fix your code to use a string or change the state type to array. This warning might become an error in future versions.
Die Warnung resultiert aus Zeile 4:
rooms
enthält ein Array, der Datenpunkt ist aber vom Typ "string". -
@mitch sagte: So sieht das Skript jetzt aus:
Das funktioniert so nicht. Zum Test:
on({id: "0_userdata.0.internet.test", change: "any"}, function () { let members = getObject("enum.rooms.buero").common.members; setState('0_userdata.0.internet.teststring', JSON.stringify(members)); for(let id of members) { if(id.startsWith('hm-rpc.')) setState(id + '.1.BOOST_MODE', true); } });
-
@paul53 sagte in Zwei Geräte in Räumen zuordnen (Echo-Gerät und Thermosthat):
on({id: "0_userdata.0.internet.test", change: "any"}, function () { let members = getObject("enum.rooms.buero").common.members; setState('0_userdata.0.internet.teststring', JSON.stringify(members)); for(let id of members) { if(id.startsWith('hm-rpc.')) setState(id + '.1.BOOST_MODE', true); } });
Vielen Dank, es funktioniert!
-
Hallo,
anbei das Skript was ich mir letztendlich gebaut habe:
on({id: "0_userdata.0.heating.actual_boost", val: true}, function () { var getecho = getState("alexa2.0.History.serialNumber").val; setState('0_userdata.0.heating.dp_echo', 'alexa2.0.Echo-Devices.' + getecho); let roomid = getObject('alexa2.0.Echo-Devices.' + getecho, 'rooms').enumIds[0]; setState('0_userdata.0.heating.dp_room', roomid); let members = getObject(roomid).common.members; for(let id of members) { if(id.startsWith('hm-rpc.')) { setState('0_userdata.0.heating.dp_thermostat', id) setState(id + '.1.BOOST_MODE', true); } setState('0_userdata.0.heating.actual_boost', false); } });
Man braucht vielleicht nicht zwingend so viele Datenpunkte. Ich finde es aber Vorteilhaft, wenn etwas quer läuft, kann ich nachträglich den letzten Boost noch analysieren.
Was mir jetzt noch fehlt und ich noch anpassen werde:
- Meldung per Sprache an betreffendes Echo, dass der Befehl ausgeführt wurde
- Positivliste, welche Zimmer überhaupt Heizungsboost erhalten (z.B. Ausschluss Kinderzimmer)
- Meldung an mich per Telegram
Gruss und Danke nochmal!
-
Neue Version:
on({id: "0_userdata.0.heating.actual_boost", val: true}, function () { var getecho = getState("alexa2.0.History.serialNumber").val; setState('0_userdata.0.heating.dp_echo', 'alexa2.0.Echo-Devices.' + getecho); let roomid = getObject('alexa2.0.Echo-Devices.' + getecho, 'rooms').enumIds[0]; let roomname = getObject('alexa2.0.Echo-Devices.' + getecho, 'rooms').enumNames[0]; setState('0_userdata.0.heating.dp_room', roomid); let members = getObject(roomid).common.members; for(let id of members) { if(id.startsWith('hm-rpc.')) { setState('0_userdata.0.heating.dp_thermostat', id) setState(id + '.1.BOOST_MODE', true); } setState('0_userdata.0.heating.actual_boost', false); } setState('alexa2.0.Echo-Devices.' + getecho + '.Commands.speak', 'Boost Heizung wurde im Raum ' + roomname + ' für 15 Minuten ausgelöst'); var today = new Date(); var bh_day = ("00" + today.getDate()).slice(-2); var bh_mon = today.getMonth() + 1; var bh_mon2 = ("00" + bh_mon).slice(-2); var bh_year = ("0000" + today.getFullYear()).slice(-4); var bh_hour = ("00" + today.getHours()).slice(-2); var bh_min = ("00" + today.getMinutes()).slice(-2); var bh_sec = ("00" + today.getSeconds()).slice(-2); InfoMessage = "[" + bh_year + "/" + bh_mon2 + "/" + bh_day + "-" + bh_hour + ":" + bh_min + ":" + bh_sec + "]>" + "\n" +"Boost Heizung wurde im Raum " + roomname + " für 15 Minuten ausgelöst"; sendTo("telegram", "send", { text: InfoMessage }); });
Jetzt enthalten:
- Meldung per Sprache an betreffendes Echo, dass der Befehl ausgeführt wurde
- Meldung an mich per Telegram
-
Ich bin etwas irritiert. Heute Nachmittag funktionierten die Meldung per Telegramm und Alexa noch. Jetzt meldet er:
[2022/11/04-18:59:42]>
Boost Heizung wurde im Raum [object Object] für 15 Minuten ausgelöstNormalerweise sollte er lt. Skript den Namen des Raums sagen.
-
@mitch sagte: Boost Heizung wurde im Raum [object Object] für 15 Minuten ausgelöst
Hat dieser Raum vielleicht mehrsprachige Namen? Dann ergänze unter Zeile 5:
if(typeof roomname == 'object') roomname = roomname.de;
-
@paul53 sagte in [GELÖST] Zwei Geräte in e. Raum zuordnen (Echo - Thermostat):
if(typeof roomname == 'object') roomname = roomname.de;
Das wars... es ging vorher, aber ich hatte zwischenzeitlich auch den Javascript Adapter geupdated. Vielen Dank!