From 27f7c5544d0b9ad44ce3fa8a023621da1b2592cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20X=2E=20F=C3=BCrst?= Date: Fri, 19 Dec 2025 17:38:00 +0000 Subject: [PATCH] =?UTF-8?q?Mit=20Scheduler=20f=C3=BCr=20echte=205min?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + docker-compose.yml | 7 +--- scheduler.py | 92 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 scheduler.py diff --git a/Dockerfile b/Dockerfile index e5c24cf..92670f1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,6 +11,7 @@ RUN pip install --no-cache-dir -r requirements.txt # Kopiere den Anwendungscode COPY main.py . COPY monitor.py . +COPY scheduler.py . # Erstelle Verzeichnis für Videospeicher RUN mkdir -p /app/videospeicher diff --git a/docker-compose.yml b/docker-compose.yml index 89d0df0..953a5de 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,11 +16,8 @@ services: - EMAIL_PASS=${EMAIL_PASS} - SAVE_DIR=${SAVE_DIR} - HEARTBEAT_FILE=/app/heartbeat.txt - # Führe das Skript alle 5 Minuten aus - command: > - sh -c "while true; do - python main.py && echo \"CameraSave ausgeführt um \$$(date)\" && sleep 300; - done" + # Führe das Skript zur exakten 5-Minuten-Grenze aus + command: python scheduler.py monitor: build: . diff --git a/scheduler.py b/scheduler.py new file mode 100644 index 0000000..b37ac3c --- /dev/null +++ b/scheduler.py @@ -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()