"Zeitschaltuhr"
@juntiedt: zu 1) schau Dir doch mal das Attribut relay_states an, zu 2) die willst etwas erweitern, dann schau erst einmal, woher die Beschränkung auf einen Zeitabschnitt kommt und was man an der Datenstruktur ändern müßte, damit man mehrere davon haben kann. Dann überlegst Du Dir, wie man den Code ändern müßte, damit die geänderte Datenstruktur auch richtig verarbeitet wird.
Hallo Sirius3,
ich hab Deinen Vorschlag in mein Programm eingebaut und es funktioniert super. Eigentlich schalte ich nicht direkt ein Relais sondern Funktionen in denen irgendetwas zeitgesteuert gemacht wird - u.a. auch auf dem Raspi geschaltet.
Bei der Erweiterung der Schaltprogramme tue ich mir noch etwas schwer. Ich habe RELAYS auf 6 Zeitpaare erweitert. Ist das so richtig? Wie erweitere ich jetzt am besten die init- und die update-Funktion, damit ich durch die 6 Zeitpaare parse? Sitze irgenwie auf dem Schlauch
ich hab Deinen Vorschlag in mein Programm eingebaut und es funktioniert super. Eigentlich schalte ich nicht direkt ein Relais sondern Funktionen in denen irgendetwas zeitgesteuert gemacht wird - u.a. auch auf dem Raspi geschaltet.
Bei der Erweiterung der Schaltprogramme tue ich mir noch etwas schwer. Ich habe RELAYS auf 6 Zeitpaare erweitert. Ist das so richtig? Wie erweitere ich jetzt am besten die init- und die update-Funktion, damit ich durch die 6 Zeitpaare parse? Sitze irgenwie auf dem Schlauch

Code: Alles auswählen
#!/usr/bin/python
import threading
import time
from datetime import datetime as DateTime
RELAYS = [
('Relay 1', ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00')),
('Relay 2', ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00')),
('Relay 3', ('06:45:00', '22:30:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00')),
('Relay 4', ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00')),
('Relay 5', ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00')),
('Relay 6', ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00')),
('Relay 7', ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00')),
('Relay 8', ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00'), ('00:00:00', '00:00:00')),
]
def parse_time(time):
return DateTime.strptime(time, "%H:%M:%S").time()
class Zeitschaltuhr(object):
def __init__(self, relays):
self.relays = [
(relay, parse_time(start), parse_time(end))
for relay, (start, end) in relays
]
self.relay_states = {}
self.update()
self._zsu_thread = threading.Thread(target=self._run_uhr)
self._zsu_thread.daemon = True # Don't let this thread block exiting.
self._zsu_thread.start()
def update(self):
states = {}
now = DateTime.now().time()
for relay, start, end in self.relays:
states[relay] = start <= now < end
self.relay_states = states
def _run_uhr(self):
while True:
self.update()
time.sleep(1)
zeitschaltuhr = Zeitschaltuhr(RELAYS)
while True:
for relay, state in sorted(zeitschaltuhr.relay_states.items()):
print("{} {}".format(relay, "an" if state else "aus"))
if zeitschaltuhr.relay_states["Relay 3"] == True:
print("Relay 3 an")
time.sleep(10)
@juntiedt: am besten gibst Du gar keine feste Anzahl an Zeitabschnitten an, sondern benutzt eine Liste
wobei Du dann in __init__ eine doppelte Schleife für self.relays brauchst (also am besten die Listcomprehension in zwei normale Schleifen umwandeln).
Code: Alles auswählen
RELAYS = [
('Relay 1', [],
('Relay 2', [(06:30:00', '12:00:00'), ('18:00:00', '20:00:00')],
]
Hallo,
ich habe meine Zeitschaltuhr in eine Wochenschaltuhr umgemodelt. Jetzt habe ich folgendes Problem:
bei dem Wochen Programm gebe ich die Liste als Wort (WOCHE) an. (1. Pfeil)
Bei dem Tagesprogramm ermittle ich den Tag (z.B. SONNTAG) um ihn an self.programm zu übergeben.(2. Pfeil). Wie kann ich aus dem String ein Format generieren, das Python wie WOCHE versteht, also quasi Programmtext und kein String?
ich habe meine Zeitschaltuhr in eine Wochenschaltuhr umgemodelt. Jetzt habe ich folgendes Problem:
bei dem Wochen Programm gebe ich die Liste als Wort (WOCHE) an. (1. Pfeil)
Bei dem Tagesprogramm ermittle ich den Tag (z.B. SONNTAG) um ihn an self.programm zu übergeben.(2. Pfeil). Wie kann ich aus dem String ein Format generieren, das Python wie WOCHE versteht, also quasi Programmtext und kein String?
Code: Alles auswählen
SONNTAG = [
('Prog 1', ('00:00:00', '00:00:00')),
('Prog 2', ('00:00:00', '00:00:00')),
('Prog 3', ('00:00:00', '00:00:00')),
('Prog 4', ('00:00:00', '00:00:00')),
('Prog 5', ('00:00:00', '00:00:00')),
('Prog 6', ('00:00:00', '00:00:00')),
('Prog 7', ('00:00:00', '00:00:00')),
('Prog 8', ('00:00:00', '00:00:00')),
]
WOCHE = [
('Prog 1', ('06:45:00', '09:59:00')),
('Prog 2', ('10:00:00', '12:29:00')),
('Prog 3', ('12:30:00', '14:29:00')),
('Prog 4', ('14:30:00', '17:59:00')),
('Prog 5', ('18:00:00', '19:59:00')),
('Prog 6', ('20:00:00', '23:00:00')),
('Prog 7', ('00:00:00', '00:00:00')),
('Prog 8', ('00:00:00', '00:00:00')),
]
#
#--------------------------------------------------------------------------------
#
def parse_time(time):
return DateTime.strptime(time, "%H:%M:%S").time()
def get_dow_n():
return Date.today().weekday()
def get_dow_a():
return ("MONTAG", "DIENSTAG", "MITTWOCH", "DONNERSTAG", "FREITAG", "SAMSTAG", "SONNTAG")[get_dow_n()]
#
#--------------------------------------------------------------------------------
#
class Zeitschaltuhr(object):
def __init__(self, ProgType):
self.dow = get_dow_n()
self.programm = []
self.progs = []
self.progs_states = {}
if ProgType == "Woche":
self.programm = WOCHE <--------------------------------------------------------------
self._initialize()
self._update()
self._zsu_thread = threading.Thread(target=self._run_uhr_woche)
if ProgType == "Tag":
self.programm = get_dow_a() <---------------------------------------------------------------------------------
self._initialize()
self._update()
self._zsu_thread = threading.Thread(target=self._run_uhr_tag)
@juntiedt: was ist denn der Unterschied zwischen »_run_uhr_woche« und »_run_uhr_tag«? Und was passiert, wenn sich der Tag ändert? Zum Problem: man benutzt die passende Datenstruktur, also entweder eine Liste mit 7 Einträge, für jeden Wochentag einen, oder ein Wörterbuch mit den Wochentagen als Schlüssel.
Code: Alles auswählen
#!/usr/bin/python
import threading
import time
from datetime import datetime as DateTime
from datetime import date as Date
MONTAG = [
('Prog 1', ('00:00:00', '00:00:00')),
('Prog 2', ('00:00:00', '00:00:00')),
('Prog 3', ('00:00:00', '00:00:00')),
('Prog 4', ('00:00:00', '00:00:00')),
('Prog 5', ('00:00:00', '00:00:00')),
('Prog 6', ('00:00:00', '00:00:00')),
('Prog 7', ('00:00:00', '00:00:00')),
('Prog 8', ('00:00:00', '00:00:00')),
('Prog 9', ('00:00:00', '00:00:00')),
('Prog 10', ('00:00:00', '00:00:00'))
]
DIENSTAG = [
('Prog 1', ('00:00:00', '00:00:00')),
('Prog 2', ('00:00:00', '00:00:00')),
('Prog 3', ('14:00:00', '17:48:00')),
('Prog 4', ('00:00:00', '00:00:00')),
('Prog 5', ('00:00:00', '00:00:00')),
('Prog 6', ('00:00:00', '00:00:00')),
('Prog 7', ('00:00:00', '00:00:00')),
('Prog 8', ('00:00:00', '00:00:00')),
('Prog 9', ('00:00:00', '00:00:00')),
('Prog 10', ('00:00:00', '00:00:00'))
]
MITTWOCH = [
('Prog 1', ('10:00:00', '11:00:00')),
('Prog 2', ('00:00:00', '00:00:00')),
('Prog 3', ('00:00:00', '00:00:00')),
('Prog 4', ('00:00:00', '00:00:00')),
('Prog 5', ('00:00:00', '00:00:00')),
('Prog 6', ('00:00:00', '00:00:00')),
('Prog 7', ('00:00:00', '00:00:00')),
('Prog 8', ('00:00:00', '00:00:00')),
('Prog 9', ('00:00:00', '00:00:00')),
('Prog 10', ('00:00:00', '00:00:00'))
]
DONNERSTAG = [
('Prog 1', ('00:00:00', '00:00:00')),
('Prog 2', ('00:00:00', '00:00:00')),
('Prog 3', ('00:00:00', '00:00:00')),
('Prog 4', ('00:00:00', '00:00:00')),
('Prog 5', ('00:00:00', '00:00:00')),
('Prog 6', ('00:00:00', '00:00:00')),
('Prog 7', ('00:00:00', '00:00:00')),
('Prog 8', ('00:00:00', '00:00:00')),
('Prog 9', ('00:00:00', '00:00:00')),
('Prog 10', ('00:00:00', '00:00:00'))
]
FREITAG = [
('Prog 1', ('00:00:00', '00:00:00')),
('Prog 2', ('00:00:00', '00:00:00')),
('Prog 3', ('00:00:00', '00:00:00')),
('Prog 4', ('00:00:00', '00:00:00')),
('Prog 5', ('00:00:00', '00:00:00')),
('Prog 6', ('00:00:00', '00:00:00')),
('Prog 7', ('00:00:00', '00:00:00')),
('Prog 8', ('00:00:00', '00:00:00')),
('Prog 9', ('00:00:00', '00:00:00')),
('Prog 10', ('00:00:00', '00:00:00'))
]
SAMSTAG = [
('Prog 1', ('00:00:00', '00:00:00')),
('Prog 2', ('00:00:00', '00:00:00')),
('Prog 3', ('00:00:00', '00:00:00')),
('Prog 4', ('00:00:00', '00:00:00')),
('Prog 5', ('00:00:00', '00:00:00')),
('Prog 6', ('00:00:00', '00:00:00')),
('Prog 7', ('00:00:00', '00:00:00')),
('Prog 8', ('00:00:00', '00:00:00')),
('Prog 9', ('00:00:00', '00:00:00')),
('Prog 10', ('00:00:00', '00:00:00'))
]
SONNTAG = [
('Prog 1', ('00:00:00', '00:00:00')),
('Prog 2', ('00:00:00', '00:00:00')),
('Prog 3', ('00:00:00', '00:00:00')),
('Prog 4', ('00:00:00', '00:00:00')),
('Prog 5', ('00:00:00', '00:00:00')),
('Prog 6', ('00:00:00', '00:00:00')),
('Prog 7', ('00:00:00', '00:00:00')),
('Prog 8', ('00:00:00', '00:00:00')),
('Prog 9', ('00:00:00', '00:00:00')),
('Prog 10', ('00:00:00', '00:00:00'))
]
WOCHE = [
('Prog 1', ('07:00:00', '09:00:00')),
('Prog 2', ('10:00:00', '10:15:00')),
('Prog 3', ('11:00:00', '11:15:00')),
('Prog 4', ('12:30:00', '14:00:00')),
('Prog 5', ('15:00:00', '15:15:00')),
('Prog 6', ('16:00:00', '16:15:00')),
('Prog 7', ('17:00:00', '17:15:00')),
('Prog 8', ('18:00:00', '20:00:00')),
('Prog 9', ('21:30:00', '23:00:00')),
('Prog 10', ('00:00:00', '00:00:00'))
]
#
#--------------------------------------------------------------------------------
#
def parse_time(time):
return DateTime.strptime(time, "%H:%M:%S").time()
def get_dow_n():
return Date.today().weekday()
def get_dow_a():
return ("Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag")[get_dow_n()]
#
#--------------------------------------------------------------------------------
#
class Zeitschaltuhr(object):
def __init__(self, ProgType):
self.dow = get_dow_n()
self.programm = []
self.progs = []
self.progs_states = {}
if ProgType == "Woche":
self.programm = WOCHE
self._initialize()
self._update()
self._zsu_thread = threading.Thread(target=self._run_uhr_woche)
if ProgType == "Tag":
self._get_tages_programm()
self._initialize()
self._update()
self._zsu_thread = threading.Thread(target=self._run_uhr_tag)
self._zsu_thread.daemon = True # Don't let this thread block exiting.
self._zsu_thread.start()
def _initialize(self):
self.progs = [
(prog, parse_time(start), parse_time(end))
for prog, (start, end) in self.programm
]
def _get_tages_programm(self):
if self.dow == 0:
self.programm = MONTAG
elif self.dow == 1:
self.programm = DIENSTAG
elif self.dow == 2:
self.programm = MITTWOCH
elif self.dow == 3:
self.programm = DONNERSTAG
elif self.dow == 4:
self.programm = FREITAG
elif self.dow == 5:
self.programm = SAMSTAG
elif self.dow == 6:
self.programm = SONNTAG
else:
print("falscher Wochentag")
def _update(self):
states = {}
now = DateTime.now().time()
for prog, start, end in self.progs:
#print(prog)
states[prog] = start <= now < end
#print(states[prog])
self.progs_states = states
#print(self.progs_states)
def get_zsu_dow_n(self):
return self.dow
def get_zsu_dow_a(self):
return ("Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag")[self.dow]
def _run_uhr_tag(self):
while True:
while self.dow == get_dow_n():
self._update()
time.sleep(1)
self.dow = get_dow_n()
self._get_tages_programm()
self._initialize()
self._update()
def _run_uhr_woche(self):
while True:
self._update()
time.sleep(1)
#
#--------------------------------------------------------------------------------
#
@juntiedt: Klassen sollten nicht von irgendwoher Daten beziehen. Wie willst Du Deine Zeitschaltuhr mit verschiedenen Programmen laufen lassen? Du hast jetzt einen Parameter ProgType, obwohl die Klasse eigentlich die Zeiten bräuchte. Ich würde intuitiv den ProgType sowieso anders verstehen, "Woche" als ich gebe für jeden Wochentag andere Zeiten an und "Tag" ich gebe für jeden Tag die selben Zeiten vor.
Wie ich schon im letzten Beitrag angemerkt hatte, brauchst Du eine bessere Datenstruktur. Eine Woche ist eine Liste mit 7 Einträgen (Tage). So wie Du die Klasse jetzt geschrieben hast, hast Du eigentlich zwei Klassen ineinandergeschachtelt, die bis auf _update so gut wie keinen gemeinsamen Code haben, eine TagZeitschaltUhr und eine WochenZeitschaltUhr.
Dort könnte man sich jetzt die Frage stellen, ob ein Tagesprogramm nicht einfach ein Wochenprogramm ist, das an jedem Wochentag das selbe tut und so sich eine der Klassen sparen kann.
Wie ich schon im letzten Beitrag angemerkt hatte, brauchst Du eine bessere Datenstruktur. Eine Woche ist eine Liste mit 7 Einträgen (Tage). So wie Du die Klasse jetzt geschrieben hast, hast Du eigentlich zwei Klassen ineinandergeschachtelt, die bis auf _update so gut wie keinen gemeinsamen Code haben, eine TagZeitschaltUhr und eine WochenZeitschaltUhr.
Code: Alles auswählen
def parse_time(time):
return DateTime.strptime(time, "%H:%M:%S").time()
def parse_program(program):
return [
(prog, parse_time(start), parse_time(end))
for prog, (start, end) in program
]
class TagZeitschaltuhr(object):
def __init__(self):
self.dow = get_dow_n()
self.progs = parse_program(WOCHE)
self.progs_states = {}
self._update()
self._zsu_thread = threading.Thread(target=self._run_uhr_woche)
self._zsu_thread.daemon = True # Don't let this thread block exiting.
self._zsu_thread.start()
def _update(self):
states = {}
now = DateTime.now().time()
for prog, start, end in self.progs:
states[prog] = start <= now < end
self.progs_states = states
def _run_uhr_woche(self):
while True:
self._update()
time.sleep(1)
class WochenZeitschaltuhr(object):
def __init__(self):
self.dow = get_dow_n()
self.progs = []
self.progs_states = {}
self._get_tages_programm()
self._update()
self._zsu_thread = threading.Thread(target=self._run_uhr_tag)
self._zsu_thread.daemon = True # Don't let this thread block exiting.
self._zsu_thread.start()
def _get_tages_programm(self):
program = [MONTAG, DIENSTAG, MITTWOCH, DONNERSTAG,
FREITAG, SAMSTAG, SONNTAG][self.dow]
self.progs = parse_program(program)
def _update(self):
states = {}
now = DateTime.now().time()
for prog, start, end in self.progs:
states[prog] = start <= now < end
self.progs_states = states
def _run_uhr_tag(self):
while True:
while self.dow == get_dow_n():
self._update()
time.sleep(1)
self.dow = get_dow_n()
self._get_tages_programm()
self._initialize()
self._update()
Code: Alles auswählen
class WochenZeitschaltuhr(object):
def __init__(self, weekly_program):
self.progs_states = {}
self.progs = [parse_program(program)
for program in weekly_program]
self._update()
self._zsu_thread = threading.Thread(target=self._run_uhr)
self._zsu_thread.daemon = True # Don't let this thread block exiting.
self._zsu_thread.start()
def _update(self):
now = DateTime.now()
weekday = now.weekday()
now = now.time()
states = {}
for prog, start, end in self.progs[weekday]:
states[prog] = start <= now < end
self.progs_states = states
def _run_uhr(self):
while True:
self._update()
time.sleep(1)
class TagZeitschaltuhr(WochenZeitschaltuhr):
def __init__(self, daily_program):
weekly_program = [daily_program] * 7
WochenZeitschaltuhr.__init__(self, weekly_program)
Hallo Sirius 3,
meine Zeitschaltuhr läuft jetzt fast ein Jahr problemlos.
Jetzt möchte ich aber einen Weg finden, die Schaltzeiten im laufenden Betrieb zu ändern. Ich stelle mir vor, die Schaltlisten aus einer Datei einzulesen, falls sich das Datum der Parameterdatei geändert hat. Diese würde ich z.B. alle 60 min prüfen.
Wie macht man so was am effektivsten?
Gruß Hannes
meine Zeitschaltuhr läuft jetzt fast ein Jahr problemlos.
Jetzt möchte ich aber einen Weg finden, die Schaltzeiten im laufenden Betrieb zu ändern. Ich stelle mir vor, die Schaltlisten aus einer Datei einzulesen, falls sich das Datum der Parameterdatei geändert hat. Diese würde ich z.B. alle 60 min prüfen.
Wie macht man so was am effektivsten?
Gruß Hannes