#!/usr/bin/env python3 """ watchdog.py - Vahtikoira BatteryMon_3.py:lle """ import sys import time import subprocess import logging from datetime import datetime from pathlib import Path from typing import Optional from logging.handlers import RotatingFileHandler # ── Asetukset ──────────────────────────────────────────────────────────────── STATUS_FILE = "/var/www/html/Data/Status.csv" CONTROL_FILE = "/var/www/html/Data/Control.csv" TARGET_SCRIPT = "BatteryMon_3.py" MAX_AGE_MIN = 4 CHECK_INTERVAL = 300 INITIAL_WAIT = 300 #should be 300 MAX_RESTARTS = 3 LOG_FILE = "watchdog.log" # ───────────────────────────────────────────────────────────────────────────── logging.basicConfig( format="%(asctime)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S", handlers=[ logging.StreamHandler(sys.stdout), RotatingFileHandler(LOG_FILE, maxBytes=1_000_000, backupCount=2, encoding="utf-8"), ], ) log = logging.getLogger() log.setLevel(logging.INFO) restart_count = 0 def file_age_minutes() -> Optional[float]: p = Path(STATUS_FILE) if not p.exists(): return None return (datetime.now() - datetime.fromtimestamp(p.stat().st_mtime)).total_seconds() / 60 def is_stopped() -> bool: p = Path(CONTROL_FILE) if not p.exists(): return False return p.read_text().strip() == "Stop" def restart(): global restart_count if restart_count >= MAX_RESTARTS: log.info("Uudelleenkäynnistysraja täynnä – tarkista käsin!") sys.exit(1) restart_count += 1 subprocess.call(["pkill", "-f", TARGET_SCRIPT]) time.sleep(2) subprocess.Popen( [sys.executable, TARGET_SCRIPT], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) log.info(f"Käynnistetty ({restart_count}/{MAX_RESTARTS})") def main(): global restart_count log.info("Vahtikoira käynnistetty") time.sleep(INITIAL_WAIT) while True: age = file_age_minutes() if age is not None and age <= MAX_AGE_MIN: restart_count = 0 elif is_stopped(): log.info("Stop") else: log.info(f"Käynnistetään – {STATUS_FILE} ikä {age:.0f} min" if age else f"Käynnistetään – {STATUS_FILE} puuttuu") restart() time.sleep(CHECK_INTERVAL) if __name__ == "__main__": main()