Viewer: teccam loop + viewer.ini paths + download() defaults
- viewer.ini: consistent paths (fits/scicam.fits, fits/teccamN.fits);
add device= key to teccam sections for loop device resolution
- devices.ini + devices/__init__.py: set _viewer_key on instances
so download() defaults to the correct viewer.ini path
- constants.py: add viewer_fits_path() helper
- stx/atik/mako download(): default filepath via viewer_fits_path()
- stx Camera: add matrix property (in-memory FITS fetch, no disk write)
- fits_image.py: teccam acquisition loop endpoint (POST/GET /loop);
_run_loop broadcasts frames via streamer._broadcast_preview() without
touching the filesystem — STX triggers exposure + polls ready,
Mako grabs current frame + sleeps
- viewer.html + web/__init__.py: loop controls (exp input, Start/Stop)
shown for cameras with a device= entry in viewer.ini
Co-Authored-By:
Claude Sonnet 4.6 <noreply@anthropic.com>