96 lines
2.4 KiB
Python
96 lines
2.4 KiB
Python
"""Pydantic schemas for the Expose API (M5-T12).
|
|||
|
|
|
||
|
|
Three endpoints:
|
||
|
|
GET /api/expose — catalog + toggle state + MQTT/Discovery status
|
||
|
|
PUT /api/expose — set toggles (map key → bool)
|
||
|
|
POST /api/expose/republish — trigger discovery re-publish
|
||
|
|
"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from pydantic import BaseModel
|
||
|
|
|
||
|
|
|
||
|
|
# ---------------------------------------------------------------------------
|
||
|
|
# Nested schemas
|
||
|
|
# ---------------------------------------------------------------------------
|
||
|
|
|
||
|
|
|
||
|
|
class DeviceInfoSchema(BaseModel):
|
||
|
|
"""HA device grouping info for an exposable entity."""
|
||
|
|
|
||
|
|
identifiers: list[str]
|
||
|
|
name: str
|
||
|
|
|
||
|
|
|
||
|
|
class ExposableEntitySchema(BaseModel):
|
||
|
|
"""One exposable entity in the catalog.
|
||
|
|
|
||
|
|
``value_getter`` is intentionally excluded — it is a non-serialisable
|
||
|
|
callable and is only used internally by the HA Discovery service.
|
||
|
|
"""
|
||
|
|
|
||
|
|
key: str
|
||
|
|
component: str
|
||
|
|
device: DeviceInfoSchema
|
||
|
|
device_class: str | None
|
||
|
|
unit: str
|
||
|
|
name: str
|
||
|
|
state_class: str | None = None
|
||
|
|
|
||
|
|
|
||
|
|
class CatalogEntrySchema(BaseModel):
|
||
|
|
"""An entity from the catalog with its current toggle state."""
|
||
|
|
|
||
|
|
entity: ExposableEntitySchema
|
||
|
|
enabled: bool
|
||
|
|
|
||
|
|
|
||
|
|
class MqttStatusSchema(BaseModel):
|
||
|
|
"""Connection status for MQTT and HA Discovery."""
|
||
|
|
|
||
|
|
mqtt_configured: bool
|
||
|
|
mqtt_connected: bool
|
||
|
|
discovery_enabled: bool
|
||
|
|
|
||
|
|
|
||
|
|
# ---------------------------------------------------------------------------
|
||
|
|
# Response schemas
|
||
|
|
# ---------------------------------------------------------------------------
|
||
|
|
|
||
|
|
|
||
|
|
class ExposeResponse(BaseModel):
|
||
|
|
"""Response for GET /api/expose."""
|
||
|
|
|
||
|
|
catalog: list[CatalogEntrySchema]
|
||
|
|
mqtt_status: MqttStatusSchema
|
||
|
|
|
||
|
|
|
||
|
|
class ExposeUpdateResponse(BaseModel):
|
||
|
|
"""Response for PUT /api/expose (returns updated catalog + status)."""
|
||
|
|
|
||
|
|
catalog: list[CatalogEntrySchema]
|
||
|
|
mqtt_status: MqttStatusSchema
|
||
|
|
|
||
|
|
|
||
|
|
class RepublishResponse(BaseModel):
|
||
|
|
"""Response for POST /api/expose/republish."""
|
||
|
|
|
||
|
|
ok: bool
|
||
|
|
message: str
|
||
|
|
|
||
|
|
|
||
|
|
# ---------------------------------------------------------------------------
|
||
|
|
# Request schemas
|
||
|
|
# ---------------------------------------------------------------------------
|
||
|
|
|
||
|
|
|
||
|
|
class ExposeUpdateRequest(BaseModel):
|
||
|
|
"""Request body for PUT /api/expose.
|
||
|
|
|
||
|
|
``toggles`` is a map from entity key to desired enabled state (bool).
|
||
|
|
Only keys present in the map are updated; absent keys are untouched.
|
||
|
|
"""
|
||
|
|
|
||
|
|
toggles: dict[str, bool]
|