Files
jbod-monitor/models/schemas.py
adam 0112875894 Add enclosure health details (PSUs, fans, temps, voltages) via SES
Parse sg_ses --page=0x02 output to surface enclosure-level health data
including power supply status, fan RPMs, temperature sensors, and voltage
rails. Failed/critical components are reflected in the overview totals
and shown as status pills in the enclosure card header with an expandable
detail panel.
2026-03-07 06:03:26 +00:00

150 lines
3.5 KiB
Python

from pydantic import BaseModel
class Enclosure(BaseModel):
id: str
sg_device: str | None = None
vendor: str
model: str
revision: str
total_slots: int
populated_slots: int
class SlotInfo(BaseModel):
slot: int
populated: bool
device: str | None = None
class DriveDetail(BaseModel):
device: str
model: str | None = None
serial: str | None = None
wwn: str | None = None
firmware: str | None = None
capacity_bytes: int | None = None
smart_healthy: bool | None = None
smart_supported: bool = True
temperature_c: int | None = None
power_on_hours: int | None = None
reallocated_sectors: int | None = None
pending_sectors: int | None = None
uncorrectable_errors: int | None = None
wear_leveling_percent: int | None = None
zfs_pool: str | None = None
zfs_vdev: str | None = None
zfs_state: str | None = None
smart_attributes: list[dict] = []
class DriveHealthSummary(BaseModel):
device: str
model: str | None = None
serial: str | None = None
wwn: str | None = None
firmware: str | None = None
capacity_bytes: int | None = None
smart_healthy: bool | None = None
smart_supported: bool = True
temperature_c: int | None = None
power_on_hours: int | None = None
reallocated_sectors: int | None = None
pending_sectors: int | None = None
uncorrectable_errors: int | None = None
zfs_pool: str | None = None
zfs_vdev: str | None = None
zfs_state: str | None = None
health_status: str = "healthy"
class SlotWithDrive(BaseModel):
slot: int
populated: bool
device: str | None = None
drive: DriveHealthSummary | None = None
class PsuStatus(BaseModel):
index: int
status: str
fail: bool = False
ac_fail: bool = False
dc_fail: bool = False
class FanStatus(BaseModel):
index: int
status: str
rpm: int | None = None
fail: bool = False
class TempSensor(BaseModel):
index: int
status: str
temperature_c: float | None = None
class VoltageSensor(BaseModel):
index: int
status: str
voltage: float | None = None
class EnclosureHealth(BaseModel):
overall_status: str = "OK"
psus: list[PsuStatus] = []
fans: list[FanStatus] = []
temps: list[TempSensor] = []
voltages: list[VoltageSensor] = []
class EnclosureWithDrives(BaseModel):
id: str
sg_device: str | None = None
vendor: str
model: str
revision: str
total_slots: int
populated_slots: int
slots: list[SlotWithDrive]
health: EnclosureHealth | None = None
class HostDrive(BaseModel):
device: str
drive_type: str = "disk"
model: str | None = None
serial: str | None = None
wwn: str | None = None
firmware: str | None = None
capacity_bytes: int | None = None
smart_healthy: bool | None = None
smart_supported: bool = True
temperature_c: int | None = None
power_on_hours: int | None = None
reallocated_sectors: int | None = None
pending_sectors: int | None = None
uncorrectable_errors: int | None = None
zfs_pool: str | None = None
zfs_vdev: str | None = None
zfs_state: str | None = None
health_status: str = "healthy"
megaraid_id: str | None = None
physical_drives: list["HostDrive"] = []
class Overview(BaseModel):
healthy: bool
drive_count: int
warning_count: int
error_count: int
enclosures: list[EnclosureWithDrives]
host_drives: list[HostDrive] = []
class HealthCheck(BaseModel):
status: str
tools: dict[str, bool]