79 lines
2.9 KiB
Python
79 lines
2.9 KiB
Python
"""Standalone laser temperature checker process.
|
|
|
|
Reads the target setpoints frozen at variation start and tails the JSONL readings
|
|
channel produced by the monitor. For every reading it validates both lasers and
|
|
prints a console warning whenever a measured temperature drifts from its target by
|
|
more than the tolerance (default 0.03 °C). Never touches the serial port, so it is
|
|
fully independent of the monitor and can be started/stopped at any time.
|
|
|
|
Example::
|
|
|
|
python -m python_app.scripts.laser_temp_checker
|
|
python -m python_app.scripts.laser_temp_checker --session s.json --readings r.jsonl
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import logging
|
|
import signal
|
|
import threading
|
|
from pathlib import Path
|
|
|
|
from python_app.hardware_full.laser_control.monitoring import (
|
|
DEFAULT_READINGS_PATH,
|
|
DEFAULT_SESSION_PATH,
|
|
LaserTemperatureChecker,
|
|
LaserVariationSession,
|
|
ReadingReader,
|
|
)
|
|
|
|
logger = logging.getLogger("laser_temp_checker")
|
|
|
|
_POLL_INTERVAL_S = 0.2
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description="Validate laser temperature against setpoints")
|
|
parser.add_argument("--session", type=Path, default=DEFAULT_SESSION_PATH,
|
|
help="Session snapshot with target setpoints + tolerance")
|
|
parser.add_argument("--readings", type=Path, default=DEFAULT_READINGS_PATH,
|
|
help="JSONL readings channel to tail")
|
|
parser.add_argument("--tolerance", type=float, default=None,
|
|
help="Override tolerance in °C (default: from session)")
|
|
parser.add_argument("--reminder-every", type=int, default=0,
|
|
help="Repeat a warning every N readings while off target (0=off)")
|
|
parser.add_argument("--from-start", action="store_true",
|
|
help="Validate the whole readings file, not just new lines")
|
|
args = parser.parse_args()
|
|
|
|
logging.basicConfig(level=logging.INFO, format="%(levelname)s %(name)s: %(message)s")
|
|
|
|
session = LaserVariationSession.load(args.session)
|
|
if args.tolerance is not None:
|
|
session.tolerance_c = args.tolerance
|
|
checker = LaserTemperatureChecker.from_session(session, reminder_every=args.reminder_every)
|
|
logger.info(
|
|
"Checking against T1=%.3f T2=%.3f °C, tolerance ±%.3f °C (%s)",
|
|
session.target_temp1, session.target_temp2, session.tolerance_c, session.variation_type,
|
|
)
|
|
|
|
reader = ReadingReader(args.readings, from_start=args.from_start)
|
|
stop_event = threading.Event()
|
|
|
|
def request_stop(_signum: int, _frame: object) -> None:
|
|
stop_event.set()
|
|
|
|
signal.signal(signal.SIGINT, request_stop)
|
|
signal.signal(signal.SIGTERM, request_stop)
|
|
|
|
while not stop_event.is_set():
|
|
for reading in reader.poll():
|
|
checker.process(reading)
|
|
stop_event.wait(_POLL_INTERVAL_S)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|