pulsemesh-open-telemetry-vi.../src/pulsemesh_open_telemetry_vi.../edge_agent.py

56 lines
2.0 KiB
Python

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"]