diff --git a/river_monitor.py b/river_monitor.py index 01f971b..1730b3c 100644 --- a/river_monitor.py +++ b/river_monitor.py @@ -437,7 +437,7 @@ def load_or_create_config(args: argparse.Namespace, session: requests.Session) - # Main # -------------------------------------------------------------------------- -def poll_once(cfg: dict, session: requests.Session, verbose: bool = True, backfill_days: int = 0) -> None: +def poll_once(cfg: dict, session: requests.Session, verbose: bool = True, backfill_days: int = 0, no_html: bool = False) -> None: stations = fetch_level_stations(session, cfg["lat"], cfg["lon"], cfg["radius_km"]) conn = init_db(Path(cfg["db"])) if backfill_days: @@ -447,13 +447,15 @@ def poll_once(cfg: dict, session: requests.Session, verbose: bool = True, backfi else: readings = extract_readings(stations) new_rows = store_readings(conn, readings) - build_dashboard(conn, Path(cfg["output"])) + if not no_html: + build_dashboard(conn, Path(cfg["output"])) conn.close() if verbose: ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + suffix = "" if no_html else f" -> {cfg['output']}" print( f"[{ts}] {len(readings)} readings from {len(stations)} stations " - f"({new_rows} new) -> {cfg['output']}" + f"({new_rows} new){suffix}" ) @@ -470,6 +472,7 @@ def main() -> None: parser.add_argument("--interval", type=int, default=900, help="Seconds between polls in --daemon mode (default: 900)") parser.add_argument("--backfill", action="store_true", help="Fetch full history (up to --backfill-days) for all stations, then exit") parser.add_argument("--backfill-days", type=int, default=28, dest="backfill_days", help="How many days of history to backfill (default: 28, max: 28)") + parser.add_argument("--no-html", action="store_true", dest="no_html", help="Skip HTML dashboard generation (use when a web page reads the DB directly)") args = parser.parse_args() session = requests.Session() @@ -485,7 +488,7 @@ def main() -> None: if args.backfill: try: - poll_once(cfg, session, backfill_days=min(args.backfill_days, 28)) + poll_once(cfg, session, backfill_days=min(args.backfill_days, 28), no_html=args.no_html) except requests.RequestException as exc: print(f"Backfill failed: {exc}", file=sys.stderr) sys.exit(1) @@ -493,13 +496,13 @@ def main() -> None: print(f"Running as daemon, polling every {args.interval}s. Ctrl+C to stop.") while True: try: - poll_once(cfg, session) + poll_once(cfg, session, no_html=args.no_html) except requests.RequestException as exc: print(f"Poll failed: {exc}", file=sys.stderr) time.sleep(args.interval) else: try: - poll_once(cfg, session) + poll_once(cfg, session, no_html=args.no_html) except requests.RequestException as exc: print(f"Poll failed: {exc}", file=sys.stderr) sys.exit(1) diff --git a/synology-task.sh b/synology-task.sh new file mode 100644 index 0000000..dcde735 --- /dev/null +++ b/synology-task.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# River monitor poller — run this via Synology Task Scheduler every 15 minutes. +# +# Setup: +# 1. Copy river_monitor.py to your Synology (e.g. /volume1/homes/simon/river_monitor.py) +# 2. Set WEB_DATA_DIR below to the data/ folder inside your web repo on the Synology +# 3. In DSM: Control Panel → Task Scheduler → Create → Scheduled Task → User-defined script +# - User: your DSM user (needs write access to WEB_DATA_DIR) +# - Schedule: every 15 minutes +# - Task: sh /volume1/homes/simon/synology-task.sh +# 4. Run once manually with --backfill to populate history, then let the schedule take over + +SCRIPT=/volume1/homes/simon/river_monitor.py +WEB_DATA_DIR=/volume1/web/data +DB=$WEB_DATA_DIR/river_levels.db +LOG=$WEB_DATA_DIR/river-monitor.log + +/usr/bin/python3 "$SCRIPT" \ + --db "$DB" \ + --no-html \ + >> "$LOG" 2>&1