Feature Specification: Unified Telemetry Hub
Status: Active / Implementing Last Updated: 2026-01-11
1. Executive Summary
The Unified Telemetry Hub is a polymorphic communication and data ingestion layer designed to capture any building infrastructure reading (liquid levels, electrical metrics, environmental status, mechanical flow) through a single, standardized envelope. It abstracts measurement points from physical assets, enabling a "plug-and-play" architecture for both manual logs and automated IoT bridges.
2. Problem Statement
- Current State: Telemetry is currently implemented as "pilot" widgets (e.g., Cistern Level) with specific hardcoded expectations. Data is recorded against an
assetIdwith a genericmetricstring, but lacks semantic definition (Unit, Data Type, Scale). - Impact: Scaling the platform to monitor hundreds of electrical, hydraulic, and environmental points would lead to a fragmented codebase, redundant widgets, and high maintenance costs.
3. Solution Architecture
Core Concepts
- Measurement Point (MP): A metadata-rich definition of a physical or logical sensor.
- Telemetry Ledger: A single, time-ordered collection (
operations_telemetry_readings) that stores all readings in a standardized polymorphic envelope. - IoT Bridge API: A universal endpoint
/api/telemetry/ingestthat accepts standard JSON payloads from external IoT gateways, bypassing the need for per-device integration logic.
Visualization Strategy (Smart Components)
Instead of a CisternWidget, a DynamicTelemetryWidget will:
* Identify the dataType (gauge, binary, counter).
* Map to a visual archetype (Radial Gauge, Status Light, Area Sparkline).
* Apply the defined units and scale automatically.
4. Data Models
4.1. Measurement Point Configuration
Determines how a specific point is interpreted.
export const MetricDataType = z.enum([
'gauge', // Values that float up/down (level, temp)
'counter', // Incrementing values (flow meter, kWh)
'binary', // On/Off, Open/Closed
'state' // Enumerated states (Error, Standby, Running)
]);
export interface MeasurementPoint {
id: string; // e.g., "cistern-1.level"
assetId: string; // e.g., "cistern-1"
displayName: string; // e.g., "Main Tank Level"
dataType: MetricDataType;
unit: string; // "%", "cm", "psi", "gpm", "kWh"
precision: number; // Decimals to show
scale?: { // For translating raw dipstick to %
min: number;
max: number;
}
}
4.2. Standard Telemetry Reading (The Envelope)
The unified record in the database.
export interface TelemetryReading {
id: string; // asset_point_timestamp
assetId: string;
pointId: string; // specific sensor ID
value: number | string | boolean;
timestamp: Timestamp;
source: 'iot' | 'manual' | 'system';
// Semantic Context
unit: string;
metadata?: Record<string, any>; // Extra raw data (e.g. RSSI, battery)
}
5. IoT Bridge API Interface
The bridge will support batch ingestion:
{
"gatewayId": "sd-ops-bridge-01",
"readings": [
{
"pointId": "cistern-1.level",
"value": 85.2,
"ts": "2026-01-10T22:00:00Z"
},
{
"pointId": "pump-2.status",
"value": true,
"ts": "2026-01-10T22:01:00Z"
}
]
}
6. Implementation Plan
Phase 1: Foundation & Ledger Refactor (COMPLETED)
- [x] Polymorphic Data Envelope: Single Firestore collection for all telemetry types.
- [x] Service Migration:
TelemetryServicerefactored for point-based recording. - [x] Registry & Metadata:
MeasurementPointregistry for resolving types/units.
Phase 2: Ingestion Logic (COMPLETED)
- [x] Universal IoT Ingest API: REST endpoint with API Key protection.
- [x] Registry Enrichment: Server-side metadata resolution (assetId, dataType, unit).
- [x] Manual Input Upgrade:
TelemetryRecorderintegrated with registry-based logging.
Phase 3: Smart Visualizer (IN PROGRESS)
- [x] Smart Unit Conversion: On-the-fly math for Liters/Gallons/Celsius/Fahrenheit.
- [x] Interactive Time-Series: Range switching (24h to 1y) in the UI.
- [ ] Dynamic Component: Refactor to
UniversalTelemetryWidgetfor auto-rendering unknown points.
7. Success Metrics
- Capability Traceability: Full
@capcoverage for IoT ingestion. - Scale: Ability to add a "Generator Fuel Level" point by only adding a configuration entry, with zero code changes to the dashboard.
- Stability: Resolution of serialization issues by ensuring all readings are processed through the same ISO-string conversion layer.