improved logging

This commit is contained in:
Ayzen
2026-06-06 00:52:52 +03:00
parent af6005d68f
commit aea49f6128
65 changed files with 1206 additions and 240 deletions
+30 -2
View File
@@ -110,14 +110,18 @@ class KamilAdcTtyReader:
daemon=True,
)
self._thread.start()
logger.info("Kamil ADC TTY reader started on %s", self.tty_path)
def close(self) -> None:
"""Stop the reader thread and close the TTY descriptor."""
logger.debug("Stopping Kamil ADC TTY reader on %s", self.tty_path)
self._stop_event.set()
with self._mailbox_cv:
self._mailbox_cv.notify_all()
if self._thread is not None:
self._thread.join(timeout=1.0)
if self._thread.is_alive():
logger.warning("Kamil ADC reader thread did not stop within 1.0s")
self._thread = None
if self._fd is not None:
try:
@@ -180,7 +184,11 @@ class KamilAdcTtyReader:
# ------------------------------------------------------------------
def _reader_loop(self) -> None:
"""Drain TTY parse frames publish completed sweeps until stop."""
"""Drain the TTY, parse frames, and publish completed sweeps until stop.
Runs on the background reader thread. Any exception is logged and stored
so the next :meth:`read_sweep` re-raises it on the consumer thread.
"""
buffer = bytearray()
try:
if not self._skip_to_first_start_marker(buffer):
@@ -191,6 +199,7 @@ class KamilAdcTtyReader:
return
self._publish_sweep(sweep)
except Exception as exc: # noqa: BLE001 — surfaced to the consumer via read_sweep
logger.exception("Kamil ADC reader thread failed on %s", self.tty_path)
self._publish_error(exc)
def _skip_to_first_start_marker(self, buffer: bytearray) -> bool:
@@ -335,12 +344,15 @@ class KamilAdcService:
reader = KamilAdcTtyReader(self.config.radar.kamil_adc.tty_path)
reader.open()
self._reader = reader
logger.info("Kamil ADC service opened")
except Exception:
logger.exception("Kamil ADC service failed to open; cleaning up")
self.close()
raise
def close(self) -> None:
"""Stop the TTY reader and the external collector process."""
logger.debug("Closing Kamil ADC service")
if self._reader is not None:
with suppress(Exception):
self._reader.close()
@@ -352,6 +364,9 @@ class KamilAdcService:
self._validate_sweep(sweep)
self._settings = sweep
self._frequency_hz = None
logger.debug(
"Kamil ADC configured: frequency axis %s-%s Hz", sweep.start_hz, sweep.stop_hz
)
def read_device_limits(self) -> dict[str, float | int]:
"""Kamil ADC has no runtime-readable sweep limit API."""
@@ -374,6 +389,7 @@ class KamilAdcService:
)
points = int(s21.size)
if self._frequency_hz is None or self._frequency_hz.size != points:
logger.debug("Building Kamil ADC frequency axis for %d points", points)
self._frequency_hz = self._build_frequency_axis(points)
return SweepResult(
x=self._frequency_hz.copy(),
@@ -409,6 +425,7 @@ class KamilAdcService:
self._process = None
if process is None or process.poll() is not None:
return
logger.info("Stopping Kamil ADC collector (pid=%d)", process.pid)
with suppress(ProcessLookupError):
os.killpg(process.pid, signal.SIGTERM)
try:
@@ -416,6 +433,9 @@ class KamilAdcService:
return
except subprocess.TimeoutExpired:
pass
logger.warning(
"Kamil ADC collector (pid=%d) ignored SIGTERM; sending SIGKILL", process.pid
)
with suppress(ProcessLookupError):
os.killpg(process.pid, signal.SIGKILL)
process.wait(timeout=1.0)
@@ -533,9 +553,16 @@ def _prepare_tty_path_for_collector(path: str) -> tuple[object, ...] | None:
def apply_kamil_adc_laser_control(config: RunConfigModel) -> bool:
"""Apply Kamil ADC laser settings exactly through the legacy device_main command sequence."""
"""Apply the configured laser settings through the legacy device_main command sequence.
Connects to the laser controller, resets it, and applies either manual or
variation mode per ``radar.laser_control``. Returns `True` when settings were
applied, `False` when laser control is disabled. The controller is always
disconnected before returning.
"""
laser = config.radar.laser_control
if not laser.enabled:
logger.debug("Kamil ADC laser control disabled; skipping")
return False
_validate_laser_control_config(config)
@@ -554,6 +581,7 @@ def apply_kamil_adc_laser_control(config: RunConfigModel) -> bool:
controller.connect()
controller.reset()
mode = laser.mode.strip().lower()
logger.info("Applying Kamil ADC laser control in %s mode", mode)
if mode == "manual":
manual = laser.manual
controller.set_manual_mode(