Hey,
Ich habe ein LUA-Script geschrieben, welches die anwesenheit in einem Raum (mit einer Tür) recht zuverlässig erfasst. Es setzt Dazu eine Globale Variable, welche 4 Zustände haben kann:
0 - Abwesend
1 - Zur Tür eingetreten (comming home)
2 - Im Raum, nicht sicher
3 - Im Raum, sicher
Wie es funktioniert:
2 Scripts laufen parallel. Das 1. Entscheidet größtenteils über die Zustände 0-2 das 2. löst immer aus, wenn Zustand 3 sicher ist. Das ist der Fall, wenn man im Zimmer und die Tür geschlossen ist (Außer man klettert durchs Fenster, ist man dann solange im Raum, bis die tür wieder auf geht).
Einstellung:
Die Einstellungen sind alle im Kopf beschrieben. Eine globale Variable “Zimmer” wird benötigt.
Script1
--[[
%% properties
9 value
49 value
%% globals
--]]
-- VARIABLEN Konfiguration (Bewegungsmelder & Türsensor muss oben unter %% properties aufgeführt sein) löst die szene aus
-----------------------------------------------------------------------------------------------------------------------------------------
local scene = 6-- ID dieser Szene
local motion = 49 -- ID des Bewegungssensors
local motiontime = 30 -- Timeout des Motion Sensors (Par. 22)
local door = 9 -- türsensor ID
local starttimer = 180 --timeout für status 2 (answesend, tür offen)
-----------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------
---------------------Script-----------------
fibaro:debug("--");
if fibaro:countScenes() > 1 then
fibaro:debug("stop scene");
fibaro:abort();
end
if tonumber(fibaro:getValue(door, "value")) > 0 and tonumber(fibaro:getValue(motion, "value")) == 0 and tonumber(fibaro:getGlobalValue("Zimmer")) == 0 then
fibaro:debug("zimmer1");
fibaro:setGlobal("Zimmer", "1");
fibaro:abort();
end
if tonumber(fibaro:getValue(door, "value")) > 0 and tonumber(fibaro:getValue(motion, "value")) > 0 then
fibaro:debug("zimmer2");
fibaro:setGlobal("Zimmer", "2");
local timer = os.time();
local move = 0;
while (os.time() - timer < starttimer and tonumber(fibaro:getGlobalValue("Zimmer")) == 2) do
if (tonumber(fibaro:getValue(motion, "value"))) > 0 then
timer = os.time();
end
if tonumber(fibaro:getValue(door, "value")) == 0 and tonumber(fibaro:getValue(motion, "value")) > 0 then
move = move+1;
if move > (motiontime + 3) then
fibaro:debug("Zimmer3");
fibaro:setGlobal("Zimmer", "3");
fibaro:abort();
end
else
move = 0;
end
fibaro:sleep(1000);
end
fibaro:debug("timerende");
if tonumber(fibaro:getGlobalValue("Zimmer")) == 2 then
fibaro:setGlobal("Zimmer", "0");
end
fibaro:abort();
end
fibaro:debug("---");
fibaro:killScenes(scene);
Script2
--[[
%% properties
49 value
%% globals
--]]
-- VARIABLEN Konfiguration (Bewegungsmelder muss oben unter %% properties aufgeführt sein, KEIN Türsensor!)
-----------------------------------------------------------------------------------------------------------------------------------------
local scene = 6-- ID dieser Szene
local motion = 49 -- ID des Bewegungssensors
local door = 9 -- türsensor ID
------------------------------------------------------
-- sicher anwesend
fibaro:debug("--")
if (fibaro:countScenes()>1) or tonumber(fibaro:getGlobalValue("Zimmer")) > 2 then
fibaro:debug("stop scene")
fibaro:abort()
end
if tonumber(fibaro:getValue(door, "value")) == 0 and tonumber(fibaro:getValue(motion, "value")) > 0 then
fibaro:setGlobal("Zimmer", "3")
fibaro:debug("zimmer3")
fibaro:abort()
end
fibaro:debug("---")
fibaro:killScenes(scene)
Wie einfach dann eine komplette Lichtsteuerung für den Raum aussieht, zeige ich noch einmal hier. Das LED Licht wird beim öffnen der Tür eingeschaltet. Beim eintreten kommt das Hauptlicht dazu. Wenn das Script auf anwesend springt, bleibt das Hauptlicht an und die LEDs gehen aus. Das Licht bleibt dann auch an, wenn man sich im Raum nicht bewegt.
--[[
%% properties
%% globals
Zimmer
--]]
-- VARIABLEN Konfiguration - Variablenänderung löst die szene aus
-----------------------------------------------------------------------------------------------------------------------------------------
local scene = 1-- ID dieser Szene
local licht = 51 -- ID Lichtsensor
local switch = 83 -- ID der LED Leiste
local nachtstart = 1700 --22:00 = 2200
local nachtende = 0500 -- 07:00 = 0700
local lichtwert = -1 -- grenze zum nachtmodus (nur ausführen, wenn licht größer als)
Zimmer = fibaro:getGlobalValue("Zimmer")
-----------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------
---------------------Script-----------------
fibaro:debug("start1")
if (fibaro:countScenes()>1) then
fibaro:debug("stop scene")
fibaro:abort()
end
-- SCHALTE LICHT EIN & AUS (wenn nicht nacht)
if tonumber(Zimmer) > 0 and tonumber(fibaro:getValue(licht, "value")) > lichtwert and ((tonumber(os.date("%H%M"))) >= nachtstart or (tonumber(os.date("%H%M"))) <= nachtende) then -- hier fehlt noch "und schalter aus"
fibaro:debug("ausgelöst")
if tonumber(Zimmer) < 3 then
fibaro:call(switch, "setColor", "255", "235", "170", "0")
fibaro:debug("stat1")
if tonumber(Zimmer) == 2 then
fibaro:call(17, "pressButton", "1") --lampe an
fibaro:debug("stat2")
end
fibaro:abort()
end
if tonumber(Zimmer) == 3 then
fibaro:call(switch, "turnOff")
fibaro:call(17, "pressButton", "1") --lampe an
fibaro:debug("stat3")
fibaro:abort()
end
end
fibaro:call(switch, "turnOff")
fibaro:call(17, "pressButton", "2") --lampe aus
fibaro:killScenes(scene)
dein Script finde ich sehr interrsant. Ich möchte dieses Script bei mir im Wohnzimmer anwenden.
Gibt es die Möglichkeit das, wenn man im Raum ist, die Fibaro Schaltersteckdose freigeschaltet wird. Und wenn keine Anwesenheit realisiert wird…das die Schaltersteckdose den Strom nimmt. Das somit alle Gerät vom Standby genommen werden.
Könntest du dir das Vorstellen das man das realisieren könnte?
Was genau meinst du mit freigeschaltet? Willst du einfach stat licht die Schaltsteckdose steuern? Das geht relativ easy mit diesen Variablen. Wenn es das ist, schreibe ich dir fix das Script. Sollten wir gerade aneinander vorbei reden, dann schrei
Genau… ich möchte wenn ich im Raum bin das die Steckdose Strom liefert und alle Geräte mit Strom versorgt sind. Und wenn keiner im Raum ist…das alles Stromlos ist und keine Standby - Kosten entstehen.
Hallo,
wenn du das Script nutzt, reichen dir ja 2 Zustände: Entweder größer als 0, dann alles einschalten oder = 0 dann alles außschalten
als Trigger nimmst du die globale Variable.
Das sieht von der Struktur etwa so aus, wenn du nicht noch zusätzliche Faktoren mit einfließen lassen willst:
--[[
%% properties
%% globals
Zimmer
--]]
local switch = 99 -- ID Schalter
Zimmer = fibaro:getGlobalValue("Zimmer")
---------------------Script-----------------
fibaro:debug("start1")
if (fibaro:countScenes()>2) then
fibaro:debug("stop scene")
fibaro:abort()
end
-- SCHALTE EIN & AUS
if tonumber(Zimmer) > 0 then
fibaro:call(switch, "turnOn")
--kommando für einschalten
else
fibaro:call(switch, "turnOff")
--kommando für ausschalten
end
abort()
das ist ein geniales Skript! Danke für die Idee und Umsetzung nebst Zustandsübergangsdiagramm.
Ich habe das Skript zur generellen Anwesenheitssteuerung in der Wohnung genutzt - funktioniert perfekt.
Redaktionell: der Motion-Timeout wird über Parameter 6 gesteuert, oder?
Danke! Schön, dass es klappt. Ich habe das Script mittlerweile etwas geändert, kann ich bei Gelegenheit hier posten. Und ja, beim Fibaro Auge ist Par. 6 genau der gesuchte wert.
Also CPU sollte das Script eig nicht fressen, es wird ja nur bei Interaktion gestartet. Maximal in einer do-while Schleife kann es bei älteren versionen vielleicht so sein, kann ich aber selbst nicht nachvollziehen. Bei mir mit ca 20 anderen Scripts ist die CPU bei 1-3%, egal welcher Umstand.
Hier mal das Update mir der Idee das Timeout wenn man die Tür schließt und draußen ist herabzusetzen, denn dann will man höchstwahrscheinlich gehen und die Lampen müssen keine 10 minuten (oder je nach timeout) mehr anbleiben…
Der 2. Teil des Scripts bleibt gleich.
--[[
%% properties
134 value
156 value
%% globals
--]]
-- VARIABLEN Konfiguration (Bewegungsmelder & Türsensor muss oben unter %% properties aufgeführt sein) löst die szene aus
-----------------------------------------------------------------------------------------------------------------------------------------
local scene = 9-- ID dieser Szene
local motion = 156 -- ID des Bewegungssensors
local motiontime = 30 -- Timeout des Motion Sensors (Par. 22)
local door = 134 -- türsensor ID
local starttimer = 600 --timeout für status 2 (answesend, tür offen)
-----------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------
---------------------Script-----------------
fibaro:debug("--");
if fibaro:countScenes() > 1 then
fibaro:debug("---");
fibaro:abort();
end
local move = 0;
local move2 = 0;
if tonumber(fibaro:getValue(motion, "value")) == 0 and tonumber(fibaro:getGlobalValue("Zimmer")) == 0 then
fibaro:debug("zimmer1");
fibaro:setGlobal("Zimmer", "1");
while move < motiontime and (tonumber(fibaro:getValue(motion, "value")) == 0) do
move = move+1;
fibaro:sleep(1000);
end
if move >= motiontime then
fibaro:debug("zimmer0");
fibaro:setGlobal("Zimmer", "0");
move = 0;
fibaro:abort();
end
end
if tonumber(fibaro:getValue(door, "value")) > 0 and (tonumber(fibaro:getGlobalValue("Zimmer")) == 3 or tonumber(fibaro:getValue(motion, "value")) > 0) then
fibaro:debug("zimmer2");
fibaro:setGlobal("Zimmer", "2");
local timer = os.time();
move = 0;
move2 = 0;
while (os.time() - timer < starttimer and tonumber(fibaro:getGlobalValue("Zimmer")) == 2) do
if (tonumber(fibaro:getValue(motion, "value"))) > 0 then
timer = os.time();
end
if tonumber(fibaro:getValue(door, "value")) == 0 and tonumber(fibaro:getValue(motion, "value")) > 0 then
move = move+1;
else
move = 0;
if tonumber(fibaro:getValue(motion, "value")) == 0 and tonumber(fibaro:getValue(door, "value")) == 0 then
move2 = move2+1;
else
move2 = 0;
end
end
fibaro:sleep(1000);
if move > (motiontime + 3) then
fibaro:debug("Zimmer3");
fibaro:setGlobal("Zimmer", "3");
fibaro:abort();
end
if move2 > (starttimer/10) then
fibaro:debug("Zimmer0f");
fibaro:setGlobal("Zimmer", "0");
fibaro:abort();
end
end
fibaro:debug("timerende");
if tonumber(fibaro:getGlobalValue("Zimmer")) == 2 then
fibaro:debug("Zimmer0");
fibaro:setGlobal("Zimmer", "0");
end
fibaro:abort();
end
fibaro:debug("---");
fibaro:killScenes(scene);
ich finde das Script auch super. Ich überlege es auch in meinem Badezimmer einzusetzen. Nun habe ich aber noch eine Frage.
Wenn ich im Bad unter der Dusche stehe und die Tür zu ist (Die Dusche ist nicht im Bereich des Bewegungsmelders) würde ja trotzdem da Licht eingeschaltet bleiben. So soll es ja auch sein.
Nun kommt jemand ins Bad schließt die Tür und verlässt es kurz darauf wieder. Ich stehe immer noch unter der Dusche, ohne das der Bewegungsmelder mich registriert.
ja du hast recht, das Licht geht dann aus. An sich ist das aber nicht wirklich ein fehler bzw. mir fällt auch keine Lösung ohne zusätzliche Parameter ein. Wenn die Tür zu ist und deine Bewegung erkannt wird, wäre die Variable wieder auf 3 und anwesend. Wenn nicht, würde das Licht sogar schneller ausgehen, denn jmd. hat den Raum gerade verlassen und hinter sich die Tür geschlossen (meist kein licht mehr nötig).
Komplizierte Lösungsansätze wären mehrere Sensoren am Eingang, welche die Personen zählen. Bluetooth-Zellen, welche die genaue Positionierung ermöglichen.
Einfacher wäre noch zusätzlich einen Schalter einzubauen, welcher das Script ausser kraft setzt, wenn du ihn drückst. Quasi ein Wechsel zum klassischen licht, wie man es kennt.
Aber das ist genau die Situation, wo das Smart Home auch an Grenzen stößt. Ist denke ich gar nicht so schlecht das hier mal zu diskutieren!
danke für dein Antwort. Deine Szene ist schon perfekt für das was sie soll und ich werde sie für meine Zwecke vermutlich auch trotzdem verwenden.
Das mit dem Schalter habe ich mir auch schon überlegt, ist vermutlich am einfachsten. Die einzige sinnvolle Alternative wäre wohl einen zweiten spritzwassergeschützten Bewegungsmelder über die Dusche anzubringen. Alles andere ist dann wirklich mit Kanonen auf Spatzen schießen und würde in keinem vernünftigen Aufwand/Nutzenverhältnis stehen.
Gibt es einen LUA Befehl zum de- bzw. aktiven von Szenen? Wie ich die Szene mit dem Schalter abschieße ist mir klar, allerdings müsste ich doch die Szene auch deaktivieren (damit sie nicht wieder neu getriggert wird) und nach dem Duschen mit dem Schalter wieder aktivieren? Sie nur schlafen zu legen finde ich hier nicht so elegant.
Oder würdest du das über eine weitere Variable (Duschen = deaktiv/aktiv) schalten? Reicht ein:
if ( fibaro:getGlobalValue(“Duschen”) == “aktiv” ) then
fibaro:debug(“Duschen_aktiv”);
fibaro:abort();
end
in Zeile 26 deines ersten Scriptes um die Szene nicht durchlaufen zu lassen, wenn die Variable mit dem Schalter gesetzt wurde?
Also zum ansatz mit der dusche:
Von der Logik her ist der Zustand solange 3, wie die dusche aktiv ist. wenn die dusche wieder aus geht dann entweder zu 2, wenn tür auf oder bei 3 bleiben und dann erst wieder zu 2 wenn tür auf. denn solange das wasser läuft, bist du ja hoffentlich im raum
1000 Dank für das wirklich tolle Script das man erstmal verstehen muss
Eine Frage haette ich aber, wäre toll wenn mir die jemand beantworten könnte.
Ich möchte dieses Script nutzen jedoch anstelle des Türsensors meine Alarmanlage setzen (Zustand der Alarmanlage kommt über einen Binary Sensor zu Fibaro).
Problem hier ist, ich schalte die Alarmanlage scharf (Türe zu in deinem Script) und habe dann noch 20 Sekunden Zeit den Raum zu verlassen.
In dieser Zeit haben mich aber dann schon wieder zwei Motion Sensoren erfasst die den Zustand auf 3 setzen.
Gibt es hier eine Möglichkeit eine Verzögerung einzubauen oder etwas anderes um dieses Problem zulösen?