from __future__ import annotations from typing import List import time import uuid from pulsemesh_open_telemetry_visualization_a.adapters import der_health as der_adapter from pulsemesh_open_telemetry_visualization_a.adapters import hvac_telemetry as hvac_adapter from pulsemesh_open_telemetry_visualization_a.telemetry import TelemetrySample from pulsemesh_open_telemetry_visualization_a.anomaly import AnomalySignal from pulsemesh_open_telemetry_visualization_a.delta import Delta def collect_edge_metrics() -> List[TelemetrySample]: samples: List[TelemetrySample] = [] # Collect from available starter adapters try: samples.append(der_adapter.collect_telemetry()) except Exception: pass try: samples.append(hvac_adapter.collect_telemetry()) except Exception: pass return samples def detect_anomalies(samples: List[TelemetrySample]) -> List[AnomalySignal]: anomalies: List[AnomalySignal] = [] now = time.time() for s in samples: # Very lightweight, rule-based anomaly checks if s.metric == "der.health": if s.value < 0.25: anomalies.append(AnomalySignal(timestamp=now, anomaly_type="der_health_degradation", location=s.source, severity="high", confidence=0.9)) if s.metric == "hvac.energy_kW": if s.value > 30.0: anomalies.append(AnomalySignal(timestamp=now, anomaly_type="hvac_energy_spike", location=s.source, severity="medium", confidence=0.7)) return anomalies def build_delta() -> Delta: samples = collect_edge_metrics() anomalies = detect_anomalies(samples) delta_id = str(uuid.uuid4()) ts = time.time() items: List[dict] = [] for s in samples: items.append({"type": "telemetry", **s.to_dict()}) for a in anomalies: items.append({"type": "anomaly", **a.to_dict()}) return Delta(delta_id=delta_id, timestamp=ts, items=items) __all__ = ["collect_edge_metrics", "detect_anomalies", "build_delta"]