Commit ce0f410e authored by vertighel's avatar vertighel
Browse files

refactor: stream.py — image_loop e broadcast keyed su cam_id



image_loop riceve lista di cam_id string.
_check_and_broadcast, broadcast_preview_now, _broadcast_preview tutti su cam_id.
Payload WS: {cam_id, png} invece di {station, camera, png}.

Co-Authored-By: default avatarClaude Sonnet 4.6 <noreply@anthropic.com>
parent 3a80b973
Loading
Loading
Loading
Loading
+16 −19
Original line number Diff line number Diff line
@@ -276,10 +276,10 @@ class StreamManager:
            await asyncio.sleep(0.5)

    async def image_loop(self, cameras):
        last_mtimes = {key: 0 for key in cameras}
        last_mtimes = {cam_id: 0 for cam_id in cameras}
        while True:
            for station, camera in cameras:
                await self._check_and_broadcast(station, camera, last_mtimes)
            for cam_id in cameras:
                await self._check_and_broadcast(cam_id, last_mtimes)
            await asyncio.sleep(1)

    async def webcam_loop(self):
@@ -311,41 +311,38 @@ class StreamManager:
                    pass
            await asyncio.sleep(1.0)

    async def _check_and_broadcast(self, station, camera, last_mtimes):
    async def _check_and_broadcast(self, cam_id, last_mtimes):
        """Broadcast a preview only when the FITS file has changed on disk."""
        key = (station, camera)
        try:
            path = _fits_path(station, camera)
            path = _fits_path(cam_id)
            if path is None or not path.exists():
                return

            curr_mtime = os.path.getmtime(path)
            if curr_mtime <= last_mtimes[key]:
            if curr_mtime <= last_mtimes[cam_id]:
                return  # file unchanged since last broadcast

            last_mtimes[key] = curr_mtime
            # get_cached_data will reload from disk now that mtime advanced,
            # then cache the array for tile-request handlers to reuse.
            data = get_cached_data(station, camera)
            last_mtimes[cam_id] = curr_mtime
            data = get_cached_data(cam_id)
            if data is not None:
                await self._broadcast_preview(station, camera, data)
                await self._broadcast_preview(cam_id, data)

        except Exception as e:
            log.warning(f"Stream: preview error {station}/{camera}: {e}")
            log.warning(f"Stream: preview error {cam_id}: {e}")

    async def broadcast_preview_now(self, station, camera):
    async def broadcast_preview_now(self, cam_id):
        """Broadcast an immediate one-shot preview (e.g. on a 'refresh' WS request)."""
        try:
            data = get_cached_data(station, camera)
            data = get_cached_data(cam_id)
            if data is not None:
                await self._broadcast_preview(station, camera, data)
                await self._broadcast_preview(cam_id, data)
        except Exception as e:
            log.warning(f"Stream: on-demand preview error {station}/{camera}: {e}")
            log.warning(f"Stream: on-demand preview error {cam_id}: {e}")

    async def _broadcast_preview(self, station, camera, data):
    async def _broadcast_preview(self, cam_id, data):
        png = fits_to_png(data, thumbnail_size=_PREVIEW_PX)
        encoded = base64.b64encode(png).decode('utf-8')
        await self.broadcaster.broadcast(
            "fits-preview",
            {"station": station, "camera": camera, "png": encoded},
            {"cam_id": cam_id, "png": encoded},
        )