TheDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/skyrobot804/node_v1/llms.txt
Use this file to discover all available pages before exploring further.
ImageWatcher monitors a directory for new FITS files written by the Seestar S50 and triggers the photometry pipeline automatically when one arrives. Rather than polling the filesystem on a timer, it uses OS-native filesystem events — FSEvents on macOS, inotify on Linux, and kqueue on BSD — via the watchdog library, making detection near-instantaneous with no CPU overhead. Both freshly created files and atomically-renamed temporaries (the pattern the Seestar firmware uses) are detected correctly.
Configuration
Setimage_watcher.enabled: true in config.yaml and point watch_path at the mounted Seestar SMB share.
config.yaml
Start the ImageWatcher daemon thread when
dashboard.py launches. Set to true once the SMB share is mounted and reachable.Absolute path to the directory being watched. The watcher monitors this directory non-recursively — subdirectories are ignored. The path must exist at startup; if it does not, the watcher logs an error and does not start.
Number of seconds to wait after a filesystem event before reading the file and firing the callback. This protects against triggering on a partially-written file or on the intermediate events generated during an atomic rename. Increase this value on slow or high-latency SMB mounts.
Mounting the Seestar SMB Share
The Seestar S50 exposes its internal storage as a guest SMB share namedSeestar. Mount it so that watch_path resolves to the directory where new FITS files appear.
- macOS
- Linux
/etc/fstab or use a Login Item that runs the mount_smbfs command.Callback Event
When a new FITS file is detected and stable, the watcher calls the registered callback with a single dict argument:| Key | Type | Description |
|---|---|---|
path | str | Absolute path to the new FITS file. |
header | dict | FITS primary header as a flat dict (key → value). COMMENT, HISTORY, and blank keywords are stripped. If the header cannot be read, an empty dict is returned and the error is logged at WARNING level. |
size_kb | float | File size in kilobytes at the time the callback fires. |
.fits or .fit extension (case-insensitive) trigger the callback. All other files — JPEG previews, metadata files, thumbnails — are silently ignored.
Debounce
Thedebounce_delay setting (default 2.0 seconds) controls how long the watcher waits after detecting a filesystem event before it reads the file and fires the callback. The timer is reset each time a new event arrives for the same path, so a file that takes several seconds to write will not trigger until it has been completely quiet for debounce_delay seconds.
This protects against two failure modes:
- Partial writes: Reading a FITS file mid-write produces a truncated or corrupted header. The delay ensures the Seestar firmware has finished writing before the callback runs.
- Atomic renames: The Seestar writes FITS files by first writing to a temporary path and then renaming. Watchdog emits both a
createdevent (for the temp file) and amovedevent (for the final path). The watcher listens for both and debounces each path independently, so only the final stable path fires the callback.
3.0 or 4.0.
Programmatic Use
You can instantiateImageWatcher directly in your own scripts without running the full dashboard.py stack:
image_watcher.py
stop() cancels any pending debounce timers and joins the watchdog observer thread cleanly. It is safe to call stop() even if start() was never called or failed (e.g., because the watch path did not exist).