Abend zusammen,
hier noch ein zweites überarbeitetes Skript. Hier haben wir meinen Heizungswächter. Dieser sammelt sich selbst alle 30 Minuten alle Heizungen ("enum.functions.heating") und Fenster-/Türkontakte("enum.functions.window_door_sensor") per enum-Funktion zusammen. Anschließend frägt das Skript ab, ob einer der Kontakte geöffnet/geschlossen wurde.
Wird ein Fenster/Tür geöffnet, werden alle Thermostate im Raum (per enum-Raum ermittelt) auf 5 Grad gestellt und ihre letzte Temperatur in einem State gespeichert. Werden Türen/Fenster wieder geschlossen, prüft das Skript, ob alle Kontakte im Raum geschlossen sind. Ist das der Fall, werden alle Thermostate wieder auf ihre ursprüngliche Temperatur gestellt.
Heizungswächter
//State initalisieren
if(getState("javascript.0.lastValueThermostate").notExist)
{
createState("lastValueThermostate", {type: "object"});
}
var lastValues = getState("javascript.0.lastValueThermostate").val;
if(lastValues == null)
{
lastValues = {};
}
//Thermostate und Kontakte initalisieren
var heatingEnums;
var thermostate;
var contact;
var contactRoom;
getHeatingsAndContacts();
//OnChange Events
on({id: contact, val: true}, function (obj) {
var value = obj.state.val;
var oldValue= obj.oldState.val;
if (value == oldValue)
return;
var raum = getObject(obj.id, 'rooms').enumIds[0];
var raumName = getObject(obj.id, 'rooms').enumNames[0].de;
var devices = thermostate[raum];
if(devices.length < 1)
return;
for(let i = 0; i < devices.length; i++) {
var device = devices[i];
if(!getState(device + '.heating_setpnt_current').notExist)
{
if(getState(device + '.heating_setpnt_current').val > 5)
{
log ("Tür/Fenster geöffnet. Temperatur im " + raumName + " auf 5 Grad gestellt.");
lastValues = getState("javascript.0.lastValueThermostate").val;
lastValues[device] = getState(device + '.heating_setpnt_current').val;
setState("javascript.0.lastValueThermostate", {val: lastValues});
setState(device + '.heating_setpnt_current', 5);
}
else
{
log ("2. Tür/Fenster geöffnet. Temperatur im " + raumName + " ist bereits auf 5 Grad gestellt.");
}
}
else
{
if(getState(device + '.target_temperature').val > 5)
{
log ("Tür/Fenster geöffnet. Temperatur im " + raumName + " auf 5 Grad gestellt.");
lastValues = getState("javascript.0.lastValueThermostate").val;
lastValues[device] = getState(device + '.target_temperature').val;
setState("javascript.0.lastValueThermostate", {val: lastValues});
setState(device + '.target_temperature', 5);
}
else
{
log ("2. Tür/Fenster geöffnet. Temperatur im " + raumName + " ist bereits auf 5 Grad gestellt.");
}
}
}
});
on({id: contact, val: false}, function (obj) {
var value = obj.state.val;
var oldValue= obj.oldState.val;
if (value == oldValue)
return;
var raum = getObject(obj.id, 'rooms').enumIds[0];
var raumName = getObject(obj.id, 'rooms').enumNames[0].de;
var devices = thermostate[raum];
if(devices < 1)
return;
var tempOpen = false;
var tempContacts = contactRoom[raum];
for(let i = 0; i < tempContacts.length; i++) {
if(getState(tempContacts[i] + ".opened").val)
tempOpen = true;
}
if(!tempOpen)
{
for(let i = 0; i < devices.length; i++) {
var device = devices[i];
log ("Tür/Fenster geschlossen. Temperatur im " + raumName + " auf " + lastValues[device] + " Grad gestellt.");
if(!getState(device + '.heating_setpnt_current').notExist)
{
setState(device + '.heating_setpnt_current', lastValues[device]);
}
else
{
setState(device + '.target_temperature', lastValues[device]);
}
}
}
else
{
log ("Ein weiteres Tür/Fenster ist noch geöffnet. Temperatur im " + raumName + " bleibt unverändert.");
}
});
//Schedule für neue Geräte alle 30 Minuten
schedule("*/30 * * * *", function()
{
getHeatingsAndContacts();
});
//Functions
function getHeatingsAndContacts()
{
heatingEnums = getObject("enum.functions.heating").common.members;
thermostate = {};
for(let i = 0; i < heatingEnums.length; i++) {
if(thermostate[getObject(heatingEnums[i], 'rooms').enumIds[0]] == null)
{
thermostate[getObject(heatingEnums[i], 'rooms').enumIds[0]] = [];
}
thermostate[getObject(heatingEnums[i], 'rooms').enumIds[0]].push(heatingEnums[i]);
}
contact = getObject("enum.functions.window_door_sensor").common.members;
contactRoom = {};
for(let i = 0; i < contact.length; i++) {
if(contactRoom[getObject(contact[i], 'rooms').enumIds[0]] == null)
{
contactRoom[getObject(contact[i], 'rooms').enumIds[0]] = [];
}
contactRoom[getObject(contact[i], 'rooms').enumIds[0]].push(contact[i]);
contact[i] = contact[i] + ".opened";
}
}
Da ich zuvor für jeden Raum ein eigenes Skript hatte, ist der Vorteil für ich hier, die Übersichtlichkeit des einen Skripts. Dadurch, dass der Schedule variabel die neuen Geräte hinzugefügt werden, ist natürlich auch schön, dass man nichts weiter tun muss als sie in Zigbee zu adden. In meinem Fall benutze ich ein Tuya TS0601 und vier Spirit SPZB0001. Entsprechend ist das Skirpt für deren States eingestellt. Per Anpassung des else if Blocks lassen sich theoretisch allerdings noch andere Thermostate ergänzen.