Wenn dies dein erster Besuch hier ist, lies bitte zuerst die Hilfe - Häufig gestellte Fragen durch. Du musst dich vermutlich registrieren, bevor du Beiträge verfassen kannst. Klicke oben auf 'Registrieren', um den Registrierungsprozess zu starten. Du kannst auch jetzt schon Beiträge lesen. Suche dir einfach das Forum aus, das dich am meisten interessiert.
Ankündigung
Einklappen
Keine Ankündigung bisher.
Logik für Zirkulationspumpe - meine erste Logik in SmartHome.py
crontab ist keine Zeiteinschränkung, sondern eine zeitbasierte Aktion. So wie Du das verwendest, bringt das nichts.
Abend,
danke Waldemar, das crontab für mein Vorhaben nicht so geeignet ist, das hab ich mir schon gedacht. Schade... Dann müsste ich wohl doch in Richtung Logik gehen.
Nun ich schau mal das ich mich in python einlese wenn ich Zeit dazu finde....
Das habe ich nicht gesagt! Du verwendest crontab nur nicht richtig.
Ich habe Dir doch die Lösung geschrieben? So kannst Du es direkt verwenden...
Gruß, Waldemar
Hallo Waldemar, Hallo Foren Gemeinschaft,
mumpf leider bekomme ich die Lösung wie von dir geschrieben nicht umgesetzt.
Nun da ich Urlaub habe, hab ich mich aber nochmal mit dem Thema Beschäftigt und versuche das ganze nun via Logik abzubilden.
Aktuell hab ich das ganze mal für meine Umgebung daheim geschrieben um dies einfach testen zu können.
Wenn Flur Licht unten angeht, dann schalte auch Flur Licht oben an und nach 5 Sekunden wieder aus.
Hierzu habe ich folgenden Code in der \etc\logic.yaml:
und folgendes Pyhton Skript erstellt \logics\zirkulation.py
Code:
#!/usr/bin/env python3
# zirkulation.py
if sh.Lampen.Flur_unten.Deckenlampe.schalten():
sh.Lampen.Flur_oben.Deckenlampe.schalten('on')
time.sleep(5)
sh.Lampen.Flur_oben.Deckenlampe.schalten('off')
Bis dahin funktioniert auch alles wie es soll.
Nun zur Einschränkung das dies nur zwischen zwei definierten Zeiten passiert:
Code:
#!/usr/bin/env python3
# zirkulation.py
import time
if sh.Lampen.Flur_unten.Deckenlampe.schalten():
while(True):
now = time.strftime("%H:%M:%S")
timewindow1_ok = ("06:00:00") <= now < ("13:00:00")
if timewindow1_ok:
sh.Lampen.Flur_oben.Deckenlampe.schalten('on')
time.sleep(180)
sh.Lampen.Flur_oben.Deckenlampe.schalten('off')
sleep(2)
Auch dies scheint nach ersten Tests jetzt zu funktionieren.
Als nächstes dann noch die Bedingung das die Aktion pro Tag nur einmal ausgeführt werden kann. Wenn der Lichtschalter das zweite mal angeht, dann soll der Code nicht ausgeführt werden.
Ich werde berichten, wenn ich es zum laufen bekomme, und mich dann mal an ein Tutorial setzen.
Viele Grüße & allen schon mal schöne Feiertage Jannis
Damit machst Du eine Endlosschleife auf, die nie beendet wird. Anders gesagt: Nach dem ersten betätigen des Schalters wird Dein Licht immer zwischen 6 und 13 Uhr für 3 Minuten eingeschaltet, dann ist es 2 Sekunden aus und dann wieder an etc.
Ferner wird mit jedem Einschalten am Schalter ein neuer Thread aufgemacht, der nie beendet wird. Beides willst Du nicht!
Das mit merken, dass es schon an war, ist ganz einfach. Du machst Dir ein Item, dass sich das Einschalten merkt und das (z.B. per crontab) um Mitternacht zurückgesetzt wird. Sobald Du einschaltest, merkst Du Dir das im Item. Bevor Du einschaltest, fragst Du das Item ab.
:-( Weil ich Anfänger bin in Dingen python, aber hab mich eben schon in die Schleifen Thematik eingelesen, und gesehen das dies nicht ganz so intelligent war...
Wie auch immer ich würde das ganze gerne in ein IF ELSE statement nun packen um auch noch eine Unterscheidung zu bekommen ob es Wochenende ist oder nicht.
Dazu folgender Code:
Code:
#!/usr/bin/env python3
# zirkulation_test.py
import time
import datetime
now = time.strftime("%H:%M:%S")
day = time.strftime("%a")
if not any([char == day for char in ["Mon","Tue","Wed","Thu","Fri"]]):
print ("Es ist Wochenende")
else:
print (day)
print (now)
if sh.Lampen.Flur_unten.Deckenlampe.schalten():
now = time.strftime("%H:%M:%S")
timewindow1_ok = ("06:00:00") <= now < ("16:00:00")
if timewindow1_ok:
sh.Lampen.Flur_oben.Deckenlampe.schalten('on')
time.sleep(5)
sh.Lampen.Flur_oben.Deckenlampe.schalten('off')
time.sleep(2)
Bis zum print (now) Befehl wird es auf der Konsole wieder sauber ausgeführt. Aber leider wird Lampen.Flur_oben.Deckenlampe.schalten wohl nicht mehr ausgeführt...
Vielleicht brauch ich erst mal ne Pause.
Das Licht ist übrigens nicht wieder nach den 2sec. Pause angegangen.
Kannst du mir aber erklären, was es mit den Threads auf sich hat? Der Raspi wurde deutlich langsamer mit der Zeit...
Das Licht ist übrigens nicht wieder nach den 2sec. Pause angegangen.
In dem "While"-Beispiel oben kann das sein, weil da statt "time.sleep(2)" nur "sleep(2)" steht. Das gab dann einen Syntaxfehler und die Schleife wurde nicht erneut ausgeführt.
Kannst du mir aber erklären, was es mit den Threads auf sich hat?
Ein Automatisierungssystem wie shNG.py sollte immer laufen, auch wenn die User Logiken und Plugins programmieren und da vielleicht was falsch machen, z.B. durch Syntaxfehler. Wäre ja blöd, wenn dann das gesamte Programm abbrechen würde.
Also werden Logiken (und auch Plugins) in gesonderten "Laufzeitumgebungen" laufen gelassen, die Threads genannt werden. Wenn hier ein Fehler passiert, dann wird der Thread beendet, aber das Hauptprogramm läuft weiter.
Wenn man einen Thread mit time.sleep() anhält, hat das auch (glücklicherweise) keine Auswirkungen auf das Hauptprogramm. Der Thread "lebt" aber so lange im Speicher, bis der sleep vorbei ist.
Wenn man aber in einen Thread eine Endlosschleife einbaut, dann wird der Thread (und damit der benutzte Speicher) nie freigegeben. Ferner belastet die Endlosschleife den Prozessor (sie läuft ja ewig weiter). Deswegen ist das schlecht...
Wenn man es dann so macht wie Du, dass bei einem Tastendruck ein neuer Thread mit Endlosschleife gestartet wird, führt das zwangsläufig dazu, dass irgendwann der RasPi nicht mehr reagiert. Deswegen sagte ich, dass Du das nicht willst
Wenn was nicht läuft, schaust Du dann ins Log? Da sollte eigentlich drin stehen, wenn was nicht läuft.
Und nochmal Danke, ich vergesse es doch immer wieder das es ja LogFiles gibt die einem Helfen den Fehler zu suchen.
Also hab ich gleich mal nachgesehen was dort so steht:
Code:
2018-12-19 08:15:17 ERROR logics.zirkulation Logic: logics.zirkulation, File: /usr/local/smarthome/logics/zirkulation_test.py, Line: 10, Method: <listcomp>, Exception: name 'day' is not defined
Traceback (most recent call last):
File "/usr/local/smarthome/lib/scheduler.py", line 493, in _task
exec(obj.bytecode)
File "/usr/local/smarthome/logics/zirkulation_test.py", line 10, in <module>
if not any([char == day for char in ["Mon","Tue","Wed","Thu","Fri"]]):
File "/usr/local/smarthome/logics/zirkulation_test.py", line 10, in <listcomp>
if not any([char == day for char in ["Mon","Tue","Wed","Thu","Fri"]]):
NameError: name 'day' is not defined
Jedoch irritiert mich die Fehlermeldung jetzt doch sehr. Weil genau das was hier angemeckert wird funktioniert eigentlich in meinen Augen und das die Variable day nicht definiert ist sehe ich auch nicht so. Lasse ich das Skript über die Konsole laufen bekomme ich ja folgende Ausgabe:
Code:
[pi@SmartHomeNG ../local/smarthome/logics]$ python3 zirkulation_test.py
Wed
09:19:54
Traceback (most recent call last):
File "zirkulation_test.py", line 15, in <module>
if sh.Lampen.Flur_unten.Deckenlampe.schalten():
NameError: name 'sh' is not defined
Verändere ich nun in der Abfrage den Wert Wed für Mittwoch auf XXX
Code:
if not any([char == day for char in ["Mon","Tue","XXX","Thu","Fri"]]):
Und lasse es dann durch die Konsole laufen bekomme ich auch sauber die Antwort das wir Wochenende hätten:
Code:
[pi@SmartHomeNG ../local/smarthome/logics]$ python3 zirkulation_test.py
Es ist Wochenende
Mhm, jetzt hab ich erstmal was zum grübeln, der Fehler ist wohl hier https://bugs.python.org/issue21161 beschrieben und wird nicht gefixt. Wie ich den nun aber rausbekomme, sehe ich noch nicht...
Grüße Jannis
if not any([char == day for char in ["Mon","Tue","Wed","Thu","Fri"]]):
print ("Es ist Wochenende")
nicht einfach so:
Code:
if not (day in ["Mon","Tue","Wed","Thu","Fri"]):
print ("Es ist Wochenende")
?
Msinn - Danke, die Antwort ist wohl weil ich es nicht besser weiß. Dein Code sieht aber deutlich besser aus, werde ich so verwenden, vor allem benötige ich dann auch die Zeile nicht
Code:
globals().update(locals())
. Die Logfile weißt nun keinen Fehler mehr auf. Aber das Licht im Flur oben bleibt weiterhin aus...
danke für all eure Hilfe, nützlichen Hinweise und eure Geduld. Letztendlich hab ich nun einen funktionierende Logik, wo nur noch die letzte Bedingung fehlt (nur einmal am Tag einschalten) - aber das schieb ich jetzt erstmal hinten an.
#!/usr/bin/env python3
# zirkulation_test.py
from datetime import datetime as DateTime, time as Time
from time import sleep
now = DateTime.now()
print(now)
if now.isoweekday() in [6, 7]: # 6=Samstag, 7=Sonntag - definiert das an diesen Tagen nicht der ELSE Teil ausgeführt wird, sondern nur der IF Teil
exit
else:
if sh.Lampen.Flur_unten.Deckenlampe.schalten():
if Time(5, 45) <= now.time() < Time(13, 59): # definiert den Zeitraum - Startzeit / Endzeit
sh.Lampen.Flur_oben.Deckenlampe.schalten('on')
sleep(5)
sh.Lampen.Flur_oben.Deckenlampe.schalten('off')
Viele Grüße
Jannis
P.S.: Wenn ich ein Tutorial schreibe - wie und wo speicher ich dieses?
Um nur einmal am Tag zu schalten, kannst Du den Tag in eine persistente Variable schreiben (die behält den Wert zwischen Logik Läufen, nicht jedoch über einen shNG Neustart). Beim Aufruf der Logik kannst Du dann diese Variable testen, ob der Tag noch der gleiche ist und nur schalten, falls das nicht so ist.
So, nun ist auch die letzte Bedingung gelöst... jetzt kann ich mich die Tage mal an das Tutorial machen.
Wenn jemand Verbesserungsvorschläge hatt, gerne her damit, ich vermute mal es wäre auch ohne die Wiederholung im ELIF Teil gegangen...
Code:
#!/usr/bin/env python3
# zirkulation_test.py
from datetime import datetime as DateTime, time as Time
from time import sleep
import time
now = DateTime.now()
day = time.strftime("%d")
f = open("/usr/local/smarthome/logics/today_zirkulation.txt", "r")
today_s = f.read()
f.close()
if day < today_s:
if now.isoweekday() in [6, 7]:
exit()
else:
if sh.Lampen.Bad_Deckenlampe():
if Time(5, 45) <= now.time() < Time(7, 45): # definiert den Zeitraum - Startzeit / Endzeit
sh.Aktor_SiKa_Keller.Zirkulationspumpe('on')
sleep(180)
sh.Aktor_SiKa_Keller.Zirkulationspumpe('off')
today_w = time.strftime("%d")
f = open("/home/smarthome/today_zirkulation.txt", "w")
f.write(today_w)
f.close()
exit()
elif day > today_s:
if now.isoweekday() in [6, 7]:
exit()
else:
if sh.Lampen.Bad_Deckenlampe():
if Time(5, 45) <= now.time() < Time(7, 45): # definiert den Zeitraum - Startzeit / Endzeit
sh.Aktor_SiKa_Keller.Zirkulationspumpe('on')
sleep(180)
sh.Aktor_SiKa_Keller.Zirkulationspumpe('off')
today_w = time.strftime("%d")
f = open("/usr/local/smarthome/logics/today_zirkulation.txt", "w")
f.write(today_w)
f.close()
exit()
else:
exit()
Wir verarbeiten personenbezogene Daten über die Nutzer unserer Website mithilfe von Cookies und anderen Technologien, um unsere Dienste bereitzustellen. Weitere Informationen findest Du in unserer Datenschutzerklärung.
Indem Du unten auf "ICH stimme zu" klickst, stimmst Du unserer Datenschutzerklärung und unseren persönlichen Datenverarbeitungs- und Cookie-Praktiken zu, wie darin beschrieben. Du erkennst außerdem an, dass dieses Forum möglicherweise außerhalb Deines Landes gehostet wird und bist damit einverstanden, dass Deine Daten in dem Land, in dem dieses Forum gehostet wird, gesammelt, gespeichert und verarbeitet werden.
Kommentar