46 lines
1.2 KiB
Python
46 lines
1.2 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
import numpy as np
|
|
|
|
from app.models.mongodb.telemetry import TelemetryData
|
|
|
|
|
|
async def analyze_trend(
|
|
device_id: str, start: datetime, end: datetime
|
|
) -> dict:
|
|
"""Analyze telemetry data trends using linear regression."""
|
|
docs = await (
|
|
TelemetryData.find(
|
|
TelemetryData.device_id == device_id,
|
|
TelemetryData.timestamp >= start,
|
|
TelemetryData.timestamp <= end,
|
|
)
|
|
.sort("+timestamp")
|
|
.to_list()
|
|
)
|
|
|
|
if len(docs) < 2:
|
|
return {"status": "insufficient_data", "count": len(docs)}
|
|
|
|
timestamps = np.array([d.timestamp.timestamp() for d in docs])
|
|
values = np.array([d.metrics.get("value", 0) for d in docs], dtype=float)
|
|
|
|
# Normalize timestamps
|
|
t_norm = timestamps - timestamps[0]
|
|
|
|
# Linear regression
|
|
coeffs = np.polyfit(t_norm, values, 1)
|
|
slope = float(coeffs[0])
|
|
|
|
return {
|
|
"count": len(docs),
|
|
"mean": float(np.mean(values)),
|
|
"std": float(np.std(values)),
|
|
"min": float(np.min(values)),
|
|
"max": float(np.max(values)),
|
|
"slope": slope,
|
|
"trend": "increasing" if slope > 0.001 else "decreasing" if slope < -0.001 else "stable",
|
|
}
|