# Changelog All notable changes to **Series 3 Watcher** will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). --- ## [1.4.2] - 2026-03-17 ### Changed - Tray icon color now reflects watcher + API health rather than unit ages — green=API OK, amber=API disabled, red=API failing, purple=watcher error. - Status menu text updated to show `Running — API OK | N unit(s) | scan Xm ago`. - Units submenu removed from tray — status tracking for individual units is handled by terra-view, not the watcher. - Unit list still logged to console and log file for debugging, but no OK/Pending/Missing judgement applied. - `watcher_status` field added to heartbeat payload so terra-view receives accurate watcher health data. ## [1.4.1] - 2026-03-17 ### Fixed - `config.ini` now saves to `AppData\Local\Series3Watcher\` instead of `Program Files` — fixes permission denied error on first-run wizard save. - Config path resolution in both `series3_tray.py` and `series3_watcher.py` updated to use `sys.frozen` + `LOCALAPPDATA` when running as a PyInstaller `.exe`. - Status menu item now uses a callable so it updates every time the menu opens — was showing stale "Starting..." while tooltip correctly showed current status. - Settings dialog now opens in its own thread — fixes unresponsive tabs and text fields while the watcher loop is running. - Tray icon reverted to plain colored dot — custom icon graphic was unreadable at 16px tray size. `.ico` file is still used for the `.exe` file icon. ### Changed - Terra-View URL field in settings wizard now accepts base URL only (e.g. `http://192.168.x.x:8000`) — `/api/series3/heartbeat` endpoint appended automatically. - Test Connection button now hits `/health` endpoint instead of posting a fake heartbeat — no database side effects. - "terra-view URL" label capitalized to "Terra-View URL". - Default log path updated to `AppData\Local\Series3Watcher\agent_logs\series3_watcher.log`. - Installer now creates `agent_logs\` folder on install. - `BUILDING.md` added — step-by-step guide for building, releasing, and updating. ## [1.4.0] - 2026-03-12 ### Added - `series3_tray.py` — system tray launcher using `pystray` + `Pillow`. Color-coded icon (green=OK, amber=Pending, red=Missing, purple=Error, grey=Starting). Right-click menu shows live status, unit count, last scan age, Open Log Folder, and Exit. - `run_watcher(state, stop_event)` in `series3_watcher.py` for background thread use by the tray. Shared `state` dict updated on every scan cycle with status, unit list, last scan time, and last error. - Interruptible sleep in watcher loop — tray exit is immediate, no waiting out the full scan interval. ### Changed - `main()` now calls `run_watcher()` — standalone behavior unchanged. - `requirements.txt` updated to document tray dependencies (`pystray`, `Pillow`); watcher itself remains stdlib-only. --- ## [1.3.0] - 2026-03-12 ### Changed - Renamed program to "series3-watcher" and main script to `series3_watcher.py` — better reflects what it does (watches for activity) rather than implying active data emission. - Default `SOURCE_TYPE` updated to `series3_watcher`. - Default log filename updated to `series3_watcher.log`. --- ## [1.2.1] - 2026-03-03 ### Changed - Changed the name of the program to "series3-agent", this was done to align with the s4/thor agent and because it represents the program's functionality better. - All instances of "emitter" changed to agent. - config.ini added to .gitignore, replaced with a template example file. - README.md updated to reflect changes. --- ## [1.2.0] - 2025-12-04 ### Changed - Removed roster CSV dependency and all Dropbox refresh/hot-reload logic; heartbeat now only enumerates `.MLG` files. - Added `MAX_EVENT_AGE_DAYS` filter to ignore stale events and log when no recent activity exists. - Simplified heartbeat output/logging to show detected units only; logging hardened to never crash the agent. --- ## [1.1.1] - 2025-12-02 ### Added - Example `config.ini` now ships with API heartbeat settings enabled (`API_ENABLED`, `API_URL`, `API_INTERVAL_SECONDS`, `SOURCE_ID`, `SOURCE_TYPE`). --- ## [1.1.0] - 2025-12-01 ### Added - Standardized SFM telemetry payload builder and periodic HTTP heartbeat POST via `urllib`. - Config support for API heartbeat (`API_ENABLED`, `API_URL`, `API_INTERVAL_SECONDS`, `SOURCE_ID`, `SOURCE_TYPE`); payload includes file path/size metadata. ### Changed - Refactored scanner to retain file paths and header sniff cache; reformatted logging/ANSI handling. --- ## [1.0.1] - 2025-11-20 ### Added - `API_URL` config key and `report_to_server` per-unit POST hook (adds `requests` dependency). ### Changed - Example `config.ini` roster URL updated; merged into `main`. --- ## [1.0.0] - 2025-11-17 ### Added - **Automatic roster refresh** from Dropbox at a configurable interval (`ROSTER_REFRESH_MIN_SECONDS`). - **Hot-reload** of roster file without restarting the script. - **Failsafe reload:** if the new roster is missing or invalid, the previous good roster is retained. - **Atomic roster downloads** (temp file in-place replace) to avoid partial/corrupted CSVs. - **Startup config echo** printing WATCH_PATH, ROSTER_FILE, and ROSTER_URL visibility. - **Active / Bench / Ignored** unit categories for clearer fleet status mapping. ### Fixed - Removed stray `note=note_suffix` bug in the Unexpected Units section. - Removed duplicate `import time`. - Removed duplicate roster load during startup (roster now loads once). - Cleaned indentation for Python 3.8 compatibility. ### Changed - Reset versioning from legacy `v5.9 beta` to **v1.0.0** (clean semver baseline). - Main script normalized as `series3_emitter.py` (later renamed to `series3_agent.py` in v1.2.1). --- [Unreleased]: https://example.com/compare/v1.2.0...HEAD [1.2.0]: https://example.com/releases/v1.2.0 [1.1.1]: https://example.com/releases/v1.1.1 [1.1.0]: https://example.com/releases/v1.1.0 [1.0.1]: https://example.com/releases/v1.0.1 [1.0.0]: https://example.com/releases/v1.0.0