초기 커밋

This commit is contained in:
2026-03-01 07:44:19 +09:00
commit 09359f30be
146 changed files with 6120 additions and 0 deletions

View File

View File

@@ -0,0 +1,37 @@
from __future__ import annotations
from datetime import datetime
from app.models.mongodb.device_log import DeviceLog
async def analyze_device_status(
device_id: str, start: datetime, end: datetime
) -> dict:
"""Analyze device status changes over a period."""
logs = await (
DeviceLog.find(
DeviceLog.device_id == device_id,
DeviceLog.event_type == "status_change",
DeviceLog.timestamp >= start,
DeviceLog.timestamp <= end,
)
.sort("+timestamp")
.to_list()
)
status_counts: dict[str, int] = {}
for log in logs:
status = log.payload.get("status", "unknown")
status_counts[status] = status_counts.get(status, 0) + 1
total_events = len(logs)
uptime_events = status_counts.get("online", 0)
uptime_ratio = uptime_events / total_events if total_events > 0 else 0.0
return {
"total_events": total_events,
"status_counts": status_counts,
"uptime_ratio": round(uptime_ratio, 4),
"period": {"start": start.isoformat(), "end": end.isoformat()},
}

View File

@@ -0,0 +1,45 @@
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",
}