91 lines
3.2 KiB
Python
91 lines
3.2 KiB
Python
"""Publish LibreVNA single-device, matrix, or simulated collections to SHM."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from contextlib import ExitStack
|
|
import threading
|
|
import time
|
|
|
|
from python_app.hardware_full.matrix_radar_service import MatrixRadarService, create_matrix_radar_service
|
|
from python_app.models.run_config_schema import RunConfigModel
|
|
from python_app.scripts.producer_common import RawPublisher, close_devices, load_producer_config, retry_open
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _open_radar_with_retry(
|
|
config: RunConfigModel,
|
|
previous: MatrixRadarService | None,
|
|
stop_requested: threading.Event,
|
|
) -> MatrixRadarService | None:
|
|
"""Recreate a failed LibreVNA service and wait interruptibly for its return."""
|
|
close_devices(previous)
|
|
|
|
def attempt() -> MatrixRadarService:
|
|
radar = create_matrix_radar_service(config)
|
|
try:
|
|
radar.open()
|
|
radar.configure(config.radar.sweep)
|
|
except Exception:
|
|
close_devices(radar)
|
|
raise
|
|
return radar
|
|
|
|
return retry_open(attempt, stop_requested, "LibreVNA radar")
|
|
|
|
|
|
def main() -> int:
|
|
"""Run producer process until config or signal requests exit."""
|
|
config_path, config, stop_requested = load_producer_config("Publish LibreVNA raw sweeps to SHM rings")
|
|
logger.info(
|
|
"LibreVNA radar raw producer starting: config=%s, model=%s, continuous=%s",
|
|
config_path, config.radar.model, config.runtime.continuous,
|
|
)
|
|
|
|
radar: MatrixRadarService | None = None
|
|
cleanup = ExitStack()
|
|
try:
|
|
publisher = RawPublisher(config.rings, cleanup)
|
|
|
|
radar = _open_radar_with_retry(config, previous=None, stop_requested=stop_requested)
|
|
if radar is None:
|
|
return 0 # asked to stop before a device became available
|
|
collection_id = 1
|
|
while not stop_requested.is_set():
|
|
collection_start = time.monotonic()
|
|
try:
|
|
collection = radar.acquire_collection(collection_id=collection_id)
|
|
except Exception as exc: # noqa: BLE001 — reconnect forever, never give up
|
|
logger.warning(
|
|
"LibreVNA radar acquisition failed; reconnecting and waiting for the device: %s",
|
|
exc,
|
|
exc_info=True,
|
|
)
|
|
radar = _open_radar_with_retry(config, previous=radar, stop_requested=stop_requested)
|
|
if radar is None:
|
|
break # stop requested while waiting to reconnect
|
|
continue
|
|
|
|
publisher.publish(collection)
|
|
if not config.runtime.continuous:
|
|
break
|
|
collection_duration_s = time.monotonic() - collection_start
|
|
if collection_id == 1 or collection_id % 20 == 0 or collection_duration_s > 2.0:
|
|
logger.info(
|
|
"LibreVNA radar collection %d acquired in %.3f s",
|
|
collection_id,
|
|
collection_duration_s,
|
|
)
|
|
collection_id += 1
|
|
finally:
|
|
close_devices(radar)
|
|
cleanup.close()
|
|
|
|
logger.info("LibreVNA radar raw producer stopped")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|