48 lines
1.3 KiB
Python
48 lines
1.3 KiB
Python
from pydantic import BaseModel
|
|
from typing import Optional, List
|
|
from enum import Enum
|
|
|
|
|
|
class UpdateType(str, Enum):
|
|
optional = "optional" # user-initiated only
|
|
mandatory = "mandatory" # auto-installs on next reboot
|
|
emergency = "emergency" # auto-installs on reboot + daily check + MQTT push
|
|
|
|
|
|
class FirmwareVersion(BaseModel):
|
|
id: str
|
|
hw_type: str # e.g. "vesper", "vesper_plus", "vesper_pro"
|
|
channel: str # "stable", "beta", "alpha", "testing"
|
|
version: str # semver e.g. "1.5"
|
|
filename: str
|
|
size_bytes: int
|
|
sha256: str
|
|
update_type: UpdateType = UpdateType.mandatory
|
|
min_fw_version: Optional[str] = None # minimum fw version required to install this
|
|
uploaded_at: str
|
|
notes: Optional[str] = None
|
|
is_latest: bool = False
|
|
|
|
|
|
class FirmwareListResponse(BaseModel):
|
|
firmware: List[FirmwareVersion]
|
|
total: int
|
|
|
|
|
|
class FirmwareMetadataResponse(BaseModel):
|
|
"""Returned by both /latest and /{version}/info endpoints."""
|
|
hw_type: str
|
|
channel: str
|
|
version: str
|
|
size_bytes: int
|
|
sha256: str
|
|
update_type: UpdateType
|
|
min_fw_version: Optional[str] = None
|
|
download_url: str
|
|
uploaded_at: str
|
|
notes: Optional[str] = None
|
|
|
|
|
|
# Keep backwards-compatible alias
|
|
FirmwareLatestResponse = FirmwareMetadataResponse
|