Mit Scheduler für echte 5min
This commit is contained in:
@@ -11,6 +11,7 @@ RUN pip install --no-cache-dir -r requirements.txt
|
|||||||
# Kopiere den Anwendungscode
|
# Kopiere den Anwendungscode
|
||||||
COPY main.py .
|
COPY main.py .
|
||||||
COPY monitor.py .
|
COPY monitor.py .
|
||||||
|
COPY scheduler.py .
|
||||||
|
|
||||||
# Erstelle Verzeichnis für Videospeicher
|
# Erstelle Verzeichnis für Videospeicher
|
||||||
RUN mkdir -p /app/videospeicher
|
RUN mkdir -p /app/videospeicher
|
||||||
|
|||||||
@@ -16,11 +16,8 @@ services:
|
|||||||
- EMAIL_PASS=${EMAIL_PASS}
|
- EMAIL_PASS=${EMAIL_PASS}
|
||||||
- SAVE_DIR=${SAVE_DIR}
|
- SAVE_DIR=${SAVE_DIR}
|
||||||
- HEARTBEAT_FILE=/app/heartbeat.txt
|
- HEARTBEAT_FILE=/app/heartbeat.txt
|
||||||
# Führe das Skript alle 5 Minuten aus
|
# Führe das Skript zur exakten 5-Minuten-Grenze aus
|
||||||
command: >
|
command: python scheduler.py
|
||||||
sh -c "while true; do
|
|
||||||
python main.py && echo \"CameraSave ausgeführt um \$$(date)\" && sleep 300;
|
|
||||||
done"
|
|
||||||
|
|
||||||
monitor:
|
monitor:
|
||||||
build: .
|
build: .
|
||||||
|
|||||||
92
scheduler.py
Normal file
92
scheduler.py
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Scheduler für CameraSave - läuft zur exakten 5-Minuten-Grenze
|
||||||
|
"""
|
||||||
|
import time
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
INTERVAL_MINUTES = 5
|
||||||
|
|
||||||
|
def seconds_until_next_interval():
|
||||||
|
"""Berechnet die Sekunden bis zur nächsten 5-Minuten-Grenze."""
|
||||||
|
now = datetime.now()
|
||||||
|
current_minute = now.minute
|
||||||
|
current_second = now.second
|
||||||
|
current_microsecond = now.microsecond
|
||||||
|
|
||||||
|
# Nächste 5-Minuten-Grenze berechnen
|
||||||
|
next_minute = ((current_minute // INTERVAL_MINUTES) + 1) * INTERVAL_MINUTES
|
||||||
|
|
||||||
|
# Minuten bis zur nächsten Grenze
|
||||||
|
minutes_to_wait = next_minute - current_minute
|
||||||
|
if minutes_to_wait <= 0:
|
||||||
|
minutes_to_wait += INTERVAL_MINUTES
|
||||||
|
|
||||||
|
# In Sekunden umrechnen und aktuelle Sekunden abziehen
|
||||||
|
seconds = (minutes_to_wait * 60) - current_second - (current_microsecond / 1_000_000)
|
||||||
|
|
||||||
|
return max(1, int(seconds)) # Mindestens 1 Sekunde warten
|
||||||
|
|
||||||
|
def run_main():
|
||||||
|
"""Führt main.py aus."""
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
[sys.executable, "main.py"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True
|
||||||
|
)
|
||||||
|
print(result.stdout, end='')
|
||||||
|
if result.stderr:
|
||||||
|
print(result.stderr, end='', file=sys.stderr)
|
||||||
|
return result.returncode
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Fehler beim Ausführen von main.py: {e}", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Hauptschleife - wartet auf 5-Minuten-Grenzen."""
|
||||||
|
print(f"🕐 CameraSave Scheduler gestartet (Intervall: {INTERVAL_MINUTES} Minuten)")
|
||||||
|
print(f" Läuft zur exakten {INTERVAL_MINUTES}-Minuten-Grenze der Uhrzeit")
|
||||||
|
print()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
# Warte bis zur nächsten 5-Minuten-Grenze
|
||||||
|
wait_seconds = seconds_until_next_interval()
|
||||||
|
now = datetime.now()
|
||||||
|
|
||||||
|
# Berechne die nächste Ausführungszeit
|
||||||
|
next_minute = ((now.minute // INTERVAL_MINUTES) + 1) * INTERVAL_MINUTES
|
||||||
|
if next_minute >= 60:
|
||||||
|
# Überlauf zur nächsten Stunde
|
||||||
|
next_run = now.replace(hour=(now.hour + 1) % 24, minute=next_minute % 60, second=0, microsecond=0)
|
||||||
|
if now.hour == 23 and next_minute >= 60:
|
||||||
|
# Überlauf zum nächsten Tag
|
||||||
|
next_run = (now + timedelta(days=1)).replace(hour=0, minute=0, second=0, microsecond=0)
|
||||||
|
else:
|
||||||
|
next_run = now.replace(minute=next_minute, second=0, microsecond=0)
|
||||||
|
|
||||||
|
print(f"⏰ Warte {wait_seconds}s bis {next_run.strftime('%H:%M:%S')}")
|
||||||
|
time.sleep(wait_seconds)
|
||||||
|
|
||||||
|
# Führe main.py aus
|
||||||
|
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
print(f"\n▶️ [{timestamp}] CameraSave wird ausgeführt...")
|
||||||
|
returncode = run_main()
|
||||||
|
|
||||||
|
if returncode == 0:
|
||||||
|
print(f"✅ [{timestamp}] Erfolgreich abgeschlossen\n")
|
||||||
|
else:
|
||||||
|
print(f"⚠️ [{timestamp}] Beendet mit Code {returncode}\n", file=sys.stderr)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n🛑 Scheduler gestoppt")
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Unerwarteter Fehler: {e}", file=sys.stderr)
|
||||||
|
time.sleep(60) # Bei Fehler 1 Minute warten
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user