Bidirectional JSON-RPC agent for LED autoresearch testing.
| 113 | |
| 114 | |
| 115 | class AutoResearchAgent: |
| 116 | """Bidirectional JSON-RPC agent for LED autoresearch testing.""" |
| 117 | |
| 118 | REMOTE_PREFIX = "REMOTE: " |
| 119 | |
| 120 | def __init__(self, port: str, baudrate: int = 115200, timeout: float = 30.0): |
| 121 | """Initialize autoresearch agent. |
| 122 | |
| 123 | Args: |
| 124 | port: Serial port path (e.g., "/dev/ttyUSB0", "COM3") |
| 125 | baudrate: Serial baud rate (default: 115200) |
| 126 | timeout: RPC response timeout in seconds (default: 30.0) |
| 127 | """ |
| 128 | self._monitor = SerialMonitor( |
| 129 | port=port, |
| 130 | baud_rate=baudrate, |
| 131 | auto_reconnect=True, |
| 132 | verbose=False, |
| 133 | ) |
| 134 | self._monitor.__enter__() # Manual context manager entry |
| 135 | self.timeout = timeout |
| 136 | |
| 137 | def send_rpc(self, function: str, args: list[Any] | None = None) -> dict[str, Any]: |
| 138 | """Send JSON-RPC command and wait for response. |
| 139 | |
| 140 | Args: |
| 141 | function: RPC function name (e.g., "configure", "runTest") |
| 142 | args: Function arguments as list (default: []) |
| 143 | |
| 144 | Returns: |
| 145 | JSON response dict from device |
| 146 | |
| 147 | Raises: |
| 148 | TimeoutError: If no response received within timeout |
| 149 | """ |
| 150 | cmd = {"method": function, "params": args or []} |
| 151 | cmd_str = json.dumps(cmd, separators=(",", ":")) |
| 152 | |
| 153 | # Send command (no manual buffer clearing needed with SerialMonitor) |
| 154 | self._monitor.write(cmd_str + "\n") |
| 155 | |
| 156 | # Wait for REMOTE: prefixed response |
| 157 | return self._wait_for_response() |
| 158 | |
| 159 | def _wait_for_response(self) -> dict[str, Any]: |
| 160 | """Wait for and parse JSON-RPC response. |
| 161 | |
| 162 | Returns: |
| 163 | Parsed JSON response dict |
| 164 | |
| 165 | Raises: |
| 166 | TimeoutError: If no response received within timeout |
| 167 | """ |
| 168 | start = time.time() |
| 169 | |
| 170 | while time.time() - start < self.timeout: |
| 171 | # Use read_lines() iterator with short timeout |
| 172 | for line in self._monitor.read_lines(timeout=0.05): |
no outgoing calls
no test coverage detected