from __future__ import annotations from datetime import datetime from pydantic import Field from app.models.common import APIModel, DockerContainerState, OverallStatus, SourceStatus class BeszelDiskMetric(APIModel): name: str mount: str used_gb: float total_gb: float free_gb: float usage_percent: float class BeszelSystemSnapshot(APIModel): source_name: str = "system" source_status: SourceStatus = "offline" host_name: str = "unknown" agent_name: str = "not_configured" cpu_usage_percent: float = 0.0 cpu_cores: int = 0 load_1: float = 0.0 load_5: float = 0.0 load_15: float = 0.0 memory_used_gb: float = 0.0 memory_total_gb: float = 0.0 memory_available_gb: float = 0.0 memory_usage_percent: float = 0.0 primary_interface: str = "unknown" network_rx_mbps: float = 0.0 network_tx_mbps: float = 0.0 uptime_seconds: int = 0 platform: str = "unknown" kernel: str = "unknown" disks: list[BeszelDiskMetric] = Field(default_factory=list) class DockerContainerSummary(APIModel): id: str name: str state: DockerContainerState status_text: str image: str health: str | None = None class DockerSnapshot(APIModel): source_name: str = "docker" source_status: SourceStatus = "offline" containers: list[DockerContainerSummary] = Field(default_factory=list) running: int = 0 stopped: int = 0 unhealthy: int = 0 total: int = 0 class UptimeKumaMonitor(APIModel): id: int name: str status: str = "unknown" # "online" | "offline" | "degraded" | "unknown" uptime_24h: float = 0.0 heartbeats: list[int] = Field(default_factory=list) # 1=up, 0=down, last 20 class UptimeKumaSnapshot(APIModel): source_name: str = "uptime_kuma" source_status: SourceStatus = "offline" monitors_up: int = 0 monitors_down: int = 0 monitors_paused: int = 0 total: int = 0 monitors: list[UptimeKumaMonitor] = Field(default_factory=list) class HomeAssistantSnapshot(APIModel): source_name: str = "home_assistant" status: SourceStatus = "offline" label: str = "Home Assistant" version: str | None = None response_time_ms: int | None = None last_checked: datetime | None = None lights_on: int = 0 lights_total: int = 0 climate_active: int = 0 doors_open: int = 0 alerts: int = 0 class AdGuardSnapshot(APIModel): source_name: str = "adguard" source_status: SourceStatus = "offline" total_queries: int = 0 blocked_queries: int = 0 blocked_percent: float = 0.0 avg_processing_ms: float = 0.0 class ScrutinyDevice(APIModel): name: str model: str status: str = "unknown" # "passed" | "failed" | "unknown" temperature: int | None = None class ScrutinySnapshot(APIModel): source_name: str = "scrutiny" source_status: SourceStatus = "offline" overall_status: str = "offline" devices: list[ScrutinyDevice] = Field(default_factory=list) failed_count: int = 0 total_count: int = 0 class ImmichSnapshot(APIModel): source_name: str = "immich" source_status: SourceStatus = "offline" photos: int = 0 videos: int = 0 storage_gb: float = 0.0 class BackrestSnapshot(APIModel): source_name: str = "backrest" source_status: SourceStatus = "offline" repo_count: int = 0 last_backup_age_hours: float | None = None last_backup_status: str = "unknown" # "ok" | "error" | "unknown" error_count: int = 0