USB Relay Module

This page documents the low-level relay control module in hid_usb_relay.

The module provides:

  • RelayRuntime — executable discovery and command execution
  • USBRelayDevice — control a specific relay device
  • RelayService — service layer for relay operations
  • enumerate_devices() — list connected HID USB relay boards
  • RelayState, RelayError, and validation helpers

Core domain and process layer for HID USB relay control.

This module provides a small object model around the vendor CLI binary and normalizes command execution, relay validation, and output parsing.

RelayCommand

Bases: Enum

CLI actions exposed by the vendor executable.

RelayCommandError

Bases: RelayError

Raised when command execution fails.

RelayConfig(default_timeout=5.0, max_relay_count=8, relay_cmd=None) dataclass

Shared runtime constants for relay interactions.

RelayError

Bases: Exception

Base relay exception.

RelayResult(relay_state) dataclass

Service return payload for relay operations.

RelayRuntime(base_path=None, timeout=CONFIG.default_timeout)

Encapsulates executable discovery and subprocess execution.

Source code in src\hid_usb_relay\usb_relay.py
79
80
81
def __init__(self, base_path: Optional[Union[str, Path]] = None, timeout: float = CONFIG.default_timeout) -> None:
    self.base_path = Path(base_path) if base_path else Path(__file__).parent
    self.timeout = timeout

RelayService

Application service used by API/CLI/GUI layers.

RelayState

Bases: Enum

Supported relay state transitions.

RelayValidationError

Bases: RelayError

Raised when relay input values are invalid.

USBRelayDevice(device_id=None, runtime=RUNTIME)

Device wrapper used for state reads and writes.

Source code in src\hid_usb_relay\usb_relay.py
186
187
188
def __init__(self, device_id: Optional[str] = None, runtime: RelayRuntime = RUNTIME) -> None:
    self.device_id = device_id
    self.runtime = runtime

enumerate_devices()

Enumerate connected relay devices and their current states.

Source code in src\hid_usb_relay\usb_relay.py
160
161
162
163
164
165
166
167
168
169
170
171
172
173
def enumerate_devices() -> List[Dict[str, str]]:
    """Enumerate connected relay devices and their current states."""

    output = RUNTIME.run([RUNTIME.executable_path, RelayCommand.ENUM.value])
    devices: List[Dict[str, str]] = []
    for line in output.splitlines():
        board = re.search(r'Board ID=\[([^\]]+)\]', line, re.IGNORECASE)
        if not board:
            continue
        try:
            devices.append({'device_id': board.group(1), **_parse_relay_states(line)})
        except RelayError as exc:
            logger.warning('%s', exc)
    return devices

get_bin_directory(base_path=None)

Return the binary directory for a given package base path.

Source code in src\hid_usb_relay\usb_relay.py
125
126
127
128
def get_bin_directory(base_path: Optional[Union[str, Path]] = None) -> Path:
    """Return the binary directory for a given package base path."""

    return RelayRuntime(base_path=base_path).bin_directory

get_executable_path(base_path=None)

Return the platform-specific relay executable path.

Source code in src\hid_usb_relay\usb_relay.py
131
132
133
134
def get_executable_path(base_path: Optional[Union[str, Path]] = None) -> Path:
    """Return the platform-specific relay executable path."""

    return RelayRuntime(base_path=base_path).executable_path

get_platform_info()

Return normalized host platform metadata.

Source code in src\hid_usb_relay\usb_relay.py
137
138
139
140
def get_platform_info() -> Dict[str, str]:
    """Return normalized host platform metadata."""

    return RUNTIME.platform_info