diff --git a/app/routers/repeaters.py b/app/routers/repeaters.py index e9ee9c9..7e5c6eb 100644 --- a/app/routers/repeaters.py +++ b/app/routers/repeaters.py @@ -153,6 +153,17 @@ async def repeater_status(public_key: str) -> RepeaterStatusResponse: return response +@router.get("/{public_key}/repeater/telemetry-history") +async def repeater_telemetry_history(public_key: str) -> list[TelemetryHistoryEntry]: + """Return stored telemetry history for a repeater (no radio command needed).""" + contact = await _resolve_contact_or_404(public_key) + _require_repeater(contact) + + since = int(time.time()) - 30 * 86400 + rows = await RepeaterTelemetryRepository.get_history(contact.public_key, since) + return [TelemetryHistoryEntry(**row) for row in rows] + + @router.post("/{public_key}/repeater/lpp-telemetry", response_model=RepeaterLppTelemetryResponse) async def repeater_lpp_telemetry(public_key: str) -> RepeaterLppTelemetryResponse: """Fetch CayenneLPP sensor telemetry from a repeater (single attempt, 10s timeout).""" diff --git a/frontend/src/api.ts b/frontend/src/api.ts index 8872cff..7394ca4 100644 --- a/frontend/src/api.ts +++ b/frontend/src/api.ts @@ -35,6 +35,7 @@ import type { RepeaterRadioSettingsResponse, RepeaterStatusResponse, StatisticsResponse, + TelemetryHistoryEntry, TraceResponse, UnreadCounts, } from './types'; @@ -374,6 +375,8 @@ export const api = { fetchJson(`/contacts/${publicKey}/repeater/status`, { method: 'POST', }), + repeaterTelemetryHistory: (publicKey: string) => + fetchJson(`/contacts/${publicKey}/repeater/telemetry-history`), repeaterNeighbors: (publicKey: string) => fetchJson(`/contacts/${publicKey}/repeater/neighbors`, { method: 'POST', diff --git a/frontend/src/test/repeaterDashboard.test.tsx b/frontend/src/test/repeaterDashboard.test.tsx index 8bd4f4c..160b589 100644 --- a/frontend/src/test/repeaterDashboard.test.tsx +++ b/frontend/src/test/repeaterDashboard.test.tsx @@ -51,10 +51,11 @@ vi.mock('../hooks/useRepeaterDashboard', () => ({ useRepeaterDashboard: () => mockHook, })); -// Mock api module (used by routing override tests) +// Mock api module (used by routing override tests + telemetry history fetch on mount) vi.mock('../api', () => ({ api: { setContactRoutingOverride: vi.fn().mockResolvedValue({ status: 'ok' }), + repeaterTelemetryHistory: vi.fn().mockResolvedValue([]), }, }));