init commit

This commit is contained in:
Ayzen
2026-03-05 14:42:33 +03:00
commit fd4618b20d
964 changed files with 325114 additions and 0 deletions
@@ -0,0 +1,115 @@
"""Main user-facing LibreVNA direct-USB device class."""
from __future__ import annotations
import logging
from types import TracebackType
from .api.config import ConfigController
from .api.vna import VNAController
from .enums import PacketType
from .models import DeviceInfo, DeviceStatus, Packet, USBDeviceDescriptor
from .session import LibreVNASession
logger = logging.getLogger(__name__)
class LibreVNADevice:
"""Main entry point for direct USB control of LibreVNA."""
def __init__(self) -> None:
"""Create device facade with session-backed VNA/config controllers."""
self._session = LibreVNASession()
self.vna = VNAController(self._session)
self.config = ConfigController(self._session)
def __enter__(self) -> LibreVNADevice:
"""Return self to support context-managed lifetime in host applications."""
return self
def __exit__(
self,
exc_type: type[BaseException] | None,
exc: BaseException | None,
tb: TracebackType | None,
) -> None:
"""Always close USB session when leaving context manager block."""
self.disconnect()
@property
def is_connected(self) -> bool:
"""Return connection state of underlying USB session."""
return self._session.is_connected
@property
def connected_serial(self) -> str | None:
"""Return currently connected serial number when available."""
return self._session.connected_serial
@staticmethod
def list_devices() -> list[USBDeviceDescriptor]:
"""Return all currently discoverable LibreVNA USB devices."""
devices = LibreVNASession.list_devices()
logger.debug("Discovered %d LibreVNA USB device(s)", len(devices))
return devices
def connect(
self,
serial: str | None = None,
strict_protocol_version: int = 14,
timeout_s: float = 1.0,
) -> None:
"""Connect to a LibreVNA device by optional serial number."""
logger.info(
"Connecting to LibreVNA (serial=%s, strict_protocol=%d, timeout=%.2fs)",
serial,
strict_protocol_version,
timeout_s,
)
self._session.connect(
serial=serial,
strict_protocol_version=strict_protocol_version,
timeout_s=timeout_s,
)
logger.info("Connected to LibreVNA (serial=%s)", self.connected_serial)
def disconnect(self) -> None:
"""Disconnect USB transport and clear runtime state."""
logger.info("Disconnecting LibreVNA session")
self._session.disconnect()
logger.info("LibreVNA session disconnected")
def send(self, packet: Packet, *, require_ack: bool = True, timeout_s: float = 0.5) -> None:
"""Send low-level protocol packet."""
logger.debug(
"Sending packet %s (require_ack=%s, timeout=%.2fs)",
packet.type.name,
require_ack,
timeout_s,
)
self._session.send(packet, require_ack=require_ack, timeout_s=timeout_s)
def request(
self,
packet_type: PacketType,
response_type: PacketType,
*,
timeout_s: float = 1.0,
) -> Packet:
"""Send no-payload request packet and wait for a response packet."""
logger.debug(
"Request packet=%s response=%s timeout=%.2fs",
packet_type.name,
response_type.name,
timeout_s,
)
return self._session.request(packet_type, response_type, timeout_s=timeout_s)
def get_device_info(self) -> DeviceInfo:
"""Return cached device info from handshake."""
return self._session.get_device_info()
def get_device_status(self, *, timeout_s: float = 1.0) -> DeviceStatus:
"""Query and return current device status."""
return self._session.get_device_status(timeout_s=timeout_s)