Mock¶
Simulate an OSECHI detector without real hardware for testing and development.
MockDevice provides a drop-in replacement for PortDevice, while MockGenerator creates simulated detection events with configurable timing and data sources.
Architecture¶
Class Diagram¶
classDiagram
class DeviceProtocol {
<<interface>>
+send_command(command: str) bool
+receive_response(field_type: str) DeviceResponse
+query(command: str) DeviceResponse
+close() None
+__enter__() Self
+__exit__() None
}
class MockDevice {
-port: str
-is_open: bool
-generator: MockGenerator | None
-events: list[dict]
-event_index: int
-events_path: Path
+send_command(command: str) bool
+receive_response(field_type: str) DeviceResponse
+query(command: str) DeviceResponse
+close() None
-_get_events() dict | None
-_get_response(command: str) dict
}
class MockGenerator {
-events: list[dict]
-index: int
-jitter: float
-speed: float
-seed: int | None
+from_file(path: str) MockGenerator
+from_random(count: int, seed: int | None) MockGenerator
+set_jitter(jitter: float) MockGenerator
+set_speed(speed: float) MockGenerator
+get_next_event() dict | None
+reset() None
}
DeviceProtocol <|.. MockDevice: implements
MockDevice --> MockGenerator: uses (optional)
Event Priority System¶
When MockDevice.receive_response(field_type="event") is called:
flowchart TD
A["receive_response(field_type='event')"] --> B{MockGenerator<br/>provided?}
B -->|Yes| C["Return event from<br/>MockGenerator"]
B -->|No| D{Loaded events<br/>available?}
D -->|Yes| E["Return event from<br/>data/events/events.jsonl"]
D -->|No| F{Command<br/>response cached?}
F -->|Yes| G["Return command<br/>response"]
F -->|No| H["Return default<br/>STATUS response"]
C --> I["type = 'mock'<br/>received_us = timestamp"]
E --> I
G --> I
H --> I
MockDevice¶
::: kazunoko.mock.MockDevice options: show_root_heading: true show_source: true
MockGenerator¶
::: kazunoko.mock.MockGenerator options: show_root_heading: true show_source: true