OpenTherm în NodeRed
Acest tutorial este transpunerea practică a celor relatate în articolul "Economie de gaz cu OpenTherm".
Se presupune că am configurat modulul OpenTherm iar calea in Tasmota este: %topic%/%prefix%/ adica 'ot/...'.
Vom creea o logică de comandă pentru centrala OpenTherm după cum urmează:
Datele care ne interesează le preluăm din 'ot/tele/SENSOR' (mesaj JSON) cu un nod MQTT in.
Datele obținute sunt prelucrate în nodul funcție denumit 'work' astfel:
var B = msg.payload.OPENTHERM.BTMP.REQ; var W = msg.payload.OPENTHERM.HWTMP.REQ; var CH = msg.payload.OPENTHERM.SLAVE.CH; var DHW = msg.payload.OPENTHERM.SLAVE.DHW; var acm_low = temperatura(0); // temperatura ACM pentru reducere consum var acm_high = temperatura(1); // temperatura ACM pentru baie var ch_low = temperatura(2); // temperatura tur pentru mentinere var ch_high = temperatura(3); // temperatura tur pentru incalzire var incalzire = flow.get('incalzire') || false; // true daca avem necesar de incalzire var iarna = flow.get('iarna') || false; // true daca incalzirea este activa ///////////////////////////////////////////////////////////////////// if (DHW != 1 && W != acm_low) return { topic: 'ot/cmnd/ot_twater', payload: acm_low }; if (DHW == 1 && W != acm_high) return { topic: 'ot/cmnd/ot_twater', payload: acm_high }; ///////////////////////////////////////////////////////////////////// if (incalzire && B != ch_high) return { topic: 'ot/cmnd/ot_tboiler', payload: ch_high }; if (!incalzire && B != ch_low) return { topic: 'ot/cmnd/ot_tboiler', payload: ch_low }; ///////////////////////////////////////////////////////////////////// if (iarna && CH != 1) return { topic: 'ot/cmnd/ot_ch', payload: 1 }; if (!iarna && CH == 1) return { topic: 'cor/opentherm/cmnd/ot_ch', payload: 0 }; ///////////////////////////////////////////////////////////////////// return null; function temperatura(tip) { var afara = flow.get('afara'); // temperatura exterior var pos = parseInt(afara); var col = parseInt(tip); if (pos < -20) pos = -20; if (pos > 20) pos = 20; pos += 20; // coloana 1 = t acm low - uzual // coloana 2 = t acm high - baie // coloana 3 = t tur low - cand nu exista necesar de incalzire // coloana 4 = t tur high - cand avem necesar de incalzire corelare = [ [20,42,46,60], // -20ºC [20,42,45,59], // -19 [20,42,45,59], // -18 [20,42,44,58], // -17 [20,42,44,58], // -16 [20,42,43,57], // -15 [20,42,43,57], // -14 [20,42,42,56], // -13 [20,42,42,56], // -12 [20,42,41,55], // -11 [20,42,41,55], // -10 [20,42,40,54], // -9 [20,42,40,54], // -8 [20,42,39,53], // -7 [20,42,39,53], // -6 [20,42,38,52], // -5 [20,42,38,52], // -4 [20,42,37,51], // -3 [20,42,37,51], // -2 [20,42,36,51], // -1 [20,42,36,40], // 0ºC [20,42,35,39], // 1 [20,42,35,39], // 2 [20,42,34,38], // 3 [20,42,34,38], // 4 [20,42,33,37], // 5 [20,42,33,37], // 6 [20,42,32,36], // 7 [20,42,32,36], // 8 [20,42,31,35], // 9 [20,42,30,34], // 10 [20,42,29,33], // 11 [20,42,28,32], // 12 [20,42,27,31], // 13 [20,42,26,30], // 14 [20,42,25,29], // 15 [20,42,24,28], // 16 [20,42,23,28], // 17 [20,42,22,28], // 18 [20,42,21,28], // 19 [20,42,20,28] // 20ºC ]; return corelare[pos][col]; }
Nu rămâne decât să transmitem rezultatul prin MQTT cu un not MQTT out fără reținere:
Pe lângă cele de mai sus avem nevoie de temperatura exterioară, variabila 'iarna' și variabila 'incalzire'.
Să le luăm pe rând, mai întâi temperatura exterioară:
pe care o preluam de la un senzor de temperatura bluetooth - termohigrometrul LYWSD03MMC - cu un nod MQTT in configurat astfel
în nodul funcție nu facem altceva decât să salvăm în flow valoarea temperaturii exterioare
flow.set('afara', msg.payload.Temperature); /* senzorul are următorul tip de mesaj: { "Time": "2024-01-13T14:58:46", "mac": "a4c138000000", "Temperature": 3.2, "Humidity": 64, "DewPoint": -3.2, "Battery": 67, "RSSI": -90, "TempUnit": "C" } */
Variabila iarna
o preluăm cu un nod MQTT in
și o salvăm în flow cu un nod funcție
flow.set('iarna', msg.payload);
Variabila 'incalzire' o automatizăm cu un termostat.
Pentru această automatizare avem nevoie de
node-red-contrib-ramp-thermostat node-red-contrib-timeout
iar rezultatul final o să arate așa:
cu nodul MQTT in "t living" preluăm temperatura de la un senzor de temperatura bluetooth - termohigrometrul LYWSD03MMC
Nodul timeout numit siguranță îl configurăm astfel
Datele senzorului de temperatură le prelucrăm într-un nod funcție așa
var iarna = flow.get('iarna'); msg.topic = 'setCurrent'; msg.payload = msg.payload.Temperature; if (!iarna) msg.payload = 90; return msg;
A doua intrare a nodului termostat este temperatura țintă pe care o preluăm cu un nod MQTT in
iar apoi cu un nod funcție îi modificăm topicul și transmitem mai departe mesajul
msg.topic = 'setTarget'; return msg;
Nodul ramp-termostat are nevoie de mai multă atenție. Deschidem nodul...
adăugăm un profil nou pe care îl numim living, cu 21ºC toată ziua (00:00 - 23:59)
apoi salvăm și nodul termostat va arăta așa:
Pe prima ieșire a nodului termostat avem necesarul de căldură pe care îl salvăm în flow cu un nod funcție:
if (msg.payload) flow.set('incalzire',true); else flow.set('incalzire',false);
iar pe ieșirea 3 avem temperatura țintă curentă pe care o salvam cu un nod MQTT out în topicul 'setari/living'
În momentul acesta avem toate elementele gata și putem salva și activa automatizarea.