Windy is a collection of Python scripts for automating an ASCOM-compatible telescope, camera, and filter wheel while correlating exposures with environmental telemetry. The toolkit can:
- connect to observatory hardware through the ASCOM COM interfaces
- execute manual or scripted exposure sequences
- record wind and pointing error telemetry alongside each exposure
- inspect saved FITS frames to extract basic star shape metrics
- visualize recent telemetry for quick situational awareness
The code base is geared toward Windows-based acquisition workstations where ASCOM and vendor drivers are available.
- Python 3.10+ (tested with CPython)
- Windows with ASCOM Platform installed – the automation layer depends on
pywin32/win32comto communicate with telescope, camera, and filter wheel drivers - Vendor-specific ASCOM drivers for your hardware
Optional but recommended:
- Access to a network or SQLite wind telemetry source that matches the formats consumed by
wind_database.py - A telemetry CSV exported from PlaneWave PWI4 (matching the column layout used by
TeleCsv)
-
(Optional) create and activate a virtual environment.
-
Install Python dependencies:
pip install -r requirements.txt
Note:
pywin32is only available on Windows. Installation will fail on other platforms. -
Confirm that the ASCOM chooser can discover your devices by running
python find_drivers.py(the script prompts you to select drivers and returns their ProgIDs).
The primary entry point for a full session is pipeline.py. It orchestrates hardware connections, captures telemetry, and logs each observation.
-
Update the module-level constants near the top of
pipeline.pywith your telemetry CSV path, Weatherman host/port, and desired output filename pattern. -
Start the pipeline:
python pipeline.py
-
When prompted, choose whether to:
- run a randomized series of pointings and logs, or
- provide manual coordinates (altitude, azimuth, filter index, exposure duration, whether to expose, and optional repeat count).
For each request the pipeline will:
- slew the telescope to the requested alt/az coordinates
- change the filter wheel position (if available)
- either take an exposure or simply wait for the specified duration
- query both wind and mount telemetry during the exposure window
- append a row to the CSV log that includes the exposure metadata and telemetry statistics
All connections are closed automatically when the script exits or if an exception occurs.
.
├── controller.py # Core ASCOM wrapper for telescope, camera, and filter wheel
├── exposure.py # FITS loader & star-shape analysis utilities
├── find_drivers.py # Helper that uses the ASCOM chooser to look up ProgIDs
├── pipeline.py # Interactive acquisition loop with telemetry logging
├── plot.py # Telemetry plotting utilities (static & animated)
├── tele_csv.py # PlaneWave telemetry CSV reader and slicer
├── wind_database.py # Interfaces to SQLite or HTTP wind telemetry sources
├── data/
│ ├── Telemetry.csv # Example PlaneWave telemetry export
│ ├── image1.fit # Sample FITS frame for analysis experiments
│ └── weatherman.sqlite # Example local wind database
├── generate_targets.py # Utility that creates a JSON list of random targets
├── simulation.py # Legacy random exposure driver (uses older Controller API)
├── main.py # Early prototype of a scripted run (requires update)
└── requirements.txt # Python dependencies
The repository also contains experimental scripts (chatgpt.py, tele_test.py, etc.) that demonstrate alternative workflows or legacy APIs. Review their docstrings before use—some still expect the older zero-argument Controller() constructor and will need driver ProgIDs supplied manually.
wind_database.pycan pull wind speed/direction samples from either a local SQLite database or a remote “weatherman” HTTP endpoint. Thewind_columnslist defines the expected schema, and the module returns aligned arrays of timestamps and values.tele_csv.pyreads the PlaneWave telemetry export format. Given a start and end time it returns mount RA/Dec RMS errors and their combined magnitude. These values are paired with wind data in the pipeline’s CSV log.plot.pycombines the data sources above to produce static figures or a live-updating plot window for recent telemetry windows.
exposure.py contains a lightweight Exposure class that opens a FITS file and computes simple star metrics (average source footprint and roundness) using astropy/photutils. You can experiment with the provided sample in data/image1.fit or integrate the class into the acquisition pipeline if you decide to persist FITS frames with Controller.take_exposure(..., save_image=True).
The data/ directory holds representative inputs that make it easier to test the telemetry and analysis utilities without connecting to real hardware. Update the file paths in your scripts if you relocate these files.
- Hardware calls are synchronous and can block while the telescope slews or the camera exposes. Consider running long sessions inside
try/exceptblocks (as shown inpipeline.py) to guarantee clean disconnects. - Some scripts (such as
main.pyandsimulation.py) pre-date the currentControllerconstructor signature. Pass explicit ProgIDs or refactor them to import and usefind_drivers.choose_driverbefore running. - When saving FITS files, ensure the destination directory exists (
controller.pywrites to animage/subdirectory relative to the repo root).
Feel free to adapt the modules to your observatory’s workflow—for example, by adding automatic weather aborts, integrating guiding metrics, or expanding the exposure analysis tools.