added generator mode

This commit is contained in:
Ayzen
2026-04-01 13:00:01 +03:00
parent 43d1c226a1
commit 4abc95c372
16 changed files with 936 additions and 0 deletions
@@ -1,9 +1,11 @@
"""Public controller classes."""
from .config import ConfigController
from .generator import GeneratorController
from .vna import VNAController
__all__ = [
"ConfigController",
"GeneratorController",
"VNAController",
]
@@ -0,0 +1,65 @@
"""Signal-generator controller for direct protocol packets."""
from __future__ import annotations
import logging
import time
from ..enums import PacketType
from ..exceptions import TimeoutError
from ..models import DeviceStatus, GeneratorSettings, Packet
from ..session import LibreVNASession
logger = logging.getLogger(__name__)
class GeneratorController:
"""Signal-generator operations built on direct packet protocol."""
def __init__(self, session: LibreVNASession) -> None:
"""Bind generator controller to active session."""
self._session = session
self._settings: GeneratorSettings | None = None
def configure(self, settings: GeneratorSettings, *, timeout_s: float = 1.0) -> None:
"""Configure generator mode and active CW output."""
self._settings = settings
self._session.send(Packet(PacketType.GENERATOR, settings), require_ack=True, timeout_s=timeout_s)
logger.info(
"Generator configured: freq=%.3fHz power=%.2fdBm port=%d correction=%s",
settings.frequency_hz,
settings.power_dbm,
settings.active_port,
settings.apply_amplitude_correction,
)
def set_idle(self, *, timeout_s: float = 1.0) -> None:
"""Return device to idle mode and stop generator output."""
logger.info("Setting LibreVNA idle mode")
self._session.send(Packet(PacketType.SET_IDLE), require_ack=True, timeout_s=timeout_s)
def wait_until_ready(
self,
*,
timeout_s: float,
poll_interval_s: float,
) -> DeviceStatus:
"""Wait until available lock flags report the generator is ready."""
deadline = time.monotonic() + timeout_s
while True:
status = self._session.get_device_status(timeout_s=min(timeout_s, 1.0))
lock_values = [value for value in (status.source_locked, status.lo_locked) if value is not None]
if lock_values:
if all(lock_values):
return status
else:
raise RuntimeError(
f"Generator lock telemetry is unavailable for hardware family {status.family.name}"
)
remaining = deadline - time.monotonic()
if remaining <= 0:
raise TimeoutError("Timed out waiting for LibreVNA generator lock")
time.sleep(min(poll_interval_s, remaining))