Add signal strength data model for trace paths#15
Conversation
This feature extracts signal strength (SNR) measurements from TRACE_DATA events and stores them with fully resolved 64-character public keys. Changes: - Add SignalStrength database model with source/destination public keys and SNR - Add API endpoint GET /api/v1/signal-strength with filtering options - Modify event handler to create SignalStrength records when processing trace data - Resolve 2-char prefixes to full public keys using most recent node by last_seen The API only supports full 64-character public keys as required.
There was a problem hiding this comment.
Pull request overview
This PR adds signal strength (SNR) tracking functionality by extracting measurements from TRACE_DATA events and storing them with fully resolved 64-character public keys. The feature enables querying signal strength data between node pairs, supporting network analysis and optimization.
Key Changes
- Database model for storing signal strength measurements with source/destination pairs
- API endpoint for querying signal strength data with filtering capabilities
- Event handler logic to extract and persist SNR data from trace paths with prefix resolution
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/meshcore_api/database/models.py | Adds SignalStrength model with indexed public key pairs and SNR measurements |
| src/meshcore_api/api/schemas.py | Defines response and filter schemas for signal strength API with 64-char key validation |
| src/meshcore_api/api/routes/signal_strength.py | Implements GET endpoint with public key and date range filtering |
| src/meshcore_api/api/app.py | Registers signal-strength router and adds API tag metadata |
| src/meshcore_api/subscriber/event_handler.py | Adds prefix resolution logic and creates SignalStrength records from trace data |
| recorded_at: Mapped[datetime] = mapped_column(DateTime, default=func.now(), index=True) | ||
|
|
||
| __table_args__ = ( | ||
| Index("idx_signal_strength_source_dest", "source_public_key", "destination_public_key"), | ||
| Index("idx_signal_strength_recorded", "recorded_at"), |
There was a problem hiding this comment.
The recorded_at field has index=True on line 153 and is also explicitly indexed in __table_args__ on line 157. This creates a duplicate index. Remove either the index=True parameter from the mapped_column or the explicit Index definition in __table_args__.
| class SignalStrengthResponse(BaseModel): | ||
| """Response model for a signal strength measurement.""" | ||
|
|
||
| id: int | ||
| source_public_key: str | ||
| destination_public_key: str | ||
| snr: float | ||
| trace_path_id: Optional[int] = None | ||
| recorded_at: datetime | ||
|
|
||
| class Config: | ||
| from_attributes = True | ||
|
|
||
|
|
||
| class SignalStrengthListResponse(BaseModel): | ||
| """Response model for signal strength list.""" | ||
|
|
||
| signal_strengths: List[SignalStrengthResponse] | ||
| total: int | ||
| limit: int | ||
| offset: int | ||
|
|
||
|
|
||
| class SignalStrengthFilters(BaseModel): | ||
| """Query filters for signal strength measurements.""" | ||
|
|
||
| source_public_key: Optional[str] = Field( | ||
| None, | ||
| min_length=64, | ||
| max_length=64, | ||
| description="Filter by source node public key (full 64 hex characters)", | ||
| ) | ||
| destination_public_key: Optional[str] = Field( | ||
| None, | ||
| min_length=64, | ||
| max_length=64, | ||
| description="Filter by destination node public key (full 64 hex characters)", | ||
| ) | ||
| start_date: Optional[datetime] = Field( | ||
| None, description="Filter signal strength records after this date" | ||
| ) | ||
| end_date: Optional[datetime] = Field( | ||
| None, description="Filter signal strength records before this date" | ||
| ) | ||
|
|
There was a problem hiding this comment.
The new SignalStrengthResponse, SignalStrengthListResponse, and SignalStrengthFilters schemas lack test coverage. Based on the existing test patterns in tests/unit/test_api_schemas.py, these schemas should have corresponding unit tests similar to TestTelemetryFilters, TestTracePathFilters, etc. to validate field constraints (e.g., min_length/max_length for public keys) and proper instantiation.
Tests cover: - SignalStrength database model (CRUD operations, queries) - API schemas (SignalStrengthResponse, SignalStrengthListResponse, SignalStrengthFilters) - Event handler prefix resolution logic (single/multiple matches, most recent selection) - Signal strength record creation from trace path data
This feature extracts signal strength (SNR) measurements from TRACE_DATA events and stores them with fully resolved 64-character public keys.
Changes:
The API only supports full 64-character public keys as required.