M5-T12: add expose toggle API and Home Assistant Expose settings panel

This commit is contained in:
2026-06-22 15:50:49 +02:00
parent 35b95f5c88
commit 45d87f36f7
11 changed files with 2420 additions and 3 deletions
+328
View File
@@ -695,6 +695,136 @@
}
}
},
"/api/expose": {
"get": {
"tags": [
"api-expose"
],
"summary": "Get Expose",
"description": "Return the full exposable-entity catalog with toggle states and MQTT status.\n\nThe catalog is computed dynamically from registered providers (e.g. the\nModbus provider enumerates all enabled devices and their metric entities).\nToggle states come from the ``exposed_entity_toggle`` table; entities with\nno row default to ``enabled=False``.",
"operationId": "get_expose_api_expose_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ExposeResponse"
}
}
}
}
}
},
"put": {
"tags": [
"api-expose"
],
"summary": "Put Expose",
"description": "Set per-entity toggle state.\n\nAccepts a map of ``{key: bool}`` and upserts rows in the\n``exposed_entity_toggle`` table. Only keys present in ``body.toggles``\nare touched; other entities' toggles are left unchanged.\n\nAfter writing the toggles, triggers a HA Discovery re-publish so any\nchanges (enabled ↔ disabled) are reflected in Home Assistant immediately.",
"operationId": "put_expose_api_expose_put",
"parameters": [
{
"name": "X-CSRF-Token",
"in": "header",
"required": false,
"schema": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "X-Csrf-Token"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ExposeUpdateRequest"
}
}
}
},
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ExposeUpdateResponse"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
}
},
"/api/expose/republish": {
"post": {
"tags": [
"api-expose"
],
"summary": "Post Expose Republish",
"description": "Manually trigger a full HA Discovery re-publish.\n\nCalls ``publish_discovery(session)`` from the HA discovery service (M5-T11).\nReturns a status indicating whether the publish was attempted (or skipped\nbecause MQTT / discovery is not enabled / connected).",
"operationId": "post_expose_republish_api_expose_republish_post",
"parameters": [
{
"name": "X-CSRF-Token",
"in": "header",
"required": false,
"schema": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "X-Csrf-Token"
}
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RepublishResponse"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
}
},
"/api/modbus/profiles": {
"get": {
"tags": [
@@ -1677,6 +1807,24 @@
},
"components": {
"schemas": {
"CatalogEntrySchema": {
"properties": {
"entity": {
"$ref": "#/components/schemas/ExposableEntitySchema"
},
"enabled": {
"type": "boolean",
"title": "Enabled"
}
},
"type": "object",
"required": [
"entity",
"enabled"
],
"title": "CatalogEntrySchema",
"description": "An entity from the catalog with its current toggle state."
},
"ConfigField": {
"properties": {
"env_name": {
@@ -1785,6 +1933,143 @@
],
"title": "ConfigUpdateResponse"
},
"DeviceInfoSchema": {
"properties": {
"identifiers": {
"items": {
"type": "string"
},
"type": "array",
"title": "Identifiers"
},
"name": {
"type": "string",
"title": "Name"
}
},
"type": "object",
"required": [
"identifiers",
"name"
],
"title": "DeviceInfoSchema",
"description": "HA device grouping info for an exposable entity."
},
"ExposableEntitySchema": {
"properties": {
"key": {
"type": "string",
"title": "Key"
},
"component": {
"type": "string",
"title": "Component"
},
"device": {
"$ref": "#/components/schemas/DeviceInfoSchema"
},
"device_class": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Device Class"
},
"unit": {
"type": "string",
"title": "Unit"
},
"name": {
"type": "string",
"title": "Name"
},
"state_class": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "State Class"
}
},
"type": "object",
"required": [
"key",
"component",
"device",
"device_class",
"unit",
"name"
],
"title": "ExposableEntitySchema",
"description": "One exposable entity in the catalog.\n\n``value_getter`` is intentionally excluded — it is a non-serialisable\ncallable and is only used internally by the HA Discovery service."
},
"ExposeResponse": {
"properties": {
"catalog": {
"items": {
"$ref": "#/components/schemas/CatalogEntrySchema"
},
"type": "array",
"title": "Catalog"
},
"mqtt_status": {
"$ref": "#/components/schemas/MqttStatusSchema"
}
},
"type": "object",
"required": [
"catalog",
"mqtt_status"
],
"title": "ExposeResponse",
"description": "Response for GET /api/expose."
},
"ExposeUpdateRequest": {
"properties": {
"toggles": {
"additionalProperties": {
"type": "boolean"
},
"type": "object",
"title": "Toggles"
}
},
"type": "object",
"required": [
"toggles"
],
"title": "ExposeUpdateRequest",
"description": "Request body for PUT /api/expose.\n\n``toggles`` is a map from entity key to desired enabled state (bool).\nOnly keys present in the map are updated; absent keys are untouched."
},
"ExposeUpdateResponse": {
"properties": {
"catalog": {
"items": {
"$ref": "#/components/schemas/CatalogEntrySchema"
},
"type": "array",
"title": "Catalog"
},
"mqtt_status": {
"$ref": "#/components/schemas/MqttStatusSchema"
}
},
"type": "object",
"required": [
"catalog",
"mqtt_status"
],
"title": "ExposeUpdateResponse",
"description": "Response for PUT /api/expose (returns updated catalog + status)."
},
"HTTPValidationError": {
"properties": {
"detail": {
@@ -2399,6 +2684,30 @@
"title": "ModbusTestReadResponse",
"description": "Response for POST /api/modbus/devices/{uuid}/test.\n\nOn success ``ok=True`` and ``payload`` contains the decoded values.\nOn failure ``ok=False`` and ``error`` describes the problem."
},
"MqttStatusSchema": {
"properties": {
"mqtt_configured": {
"type": "boolean",
"title": "Mqtt Configured"
},
"mqtt_connected": {
"type": "boolean",
"title": "Mqtt Connected"
},
"discovery_enabled": {
"type": "boolean",
"title": "Discovery Enabled"
}
},
"type": "object",
"required": [
"mqtt_configured",
"mqtt_connected",
"discovery_enabled"
],
"title": "MqttStatusSchema",
"description": "Connection status for MQTT and HA Discovery."
},
"MqttTestResponse": {
"properties": {
"result": {
@@ -2741,6 +3050,25 @@
],
"title": "PublicIPStateSchema"
},
"RepublishResponse": {
"properties": {
"ok": {
"type": "boolean",
"title": "Ok"
},
"message": {
"type": "string",
"title": "Message"
}
},
"type": "object",
"required": [
"ok",
"message"
],
"title": "RepublishResponse",
"description": "Response for POST /api/expose/republish."
},
"SessionResponse": {
"properties": {
"user": {
+255
View File
@@ -516,6 +516,112 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/api/expose:
get:
tags:
- api-expose
summary: Get Expose
description: 'Return the full exposable-entity catalog with toggle states and
MQTT status.
The catalog is computed dynamically from registered providers (e.g. the
Modbus provider enumerates all enabled devices and their metric entities).
Toggle states come from the ``exposed_entity_toggle`` table; entities with
no row default to ``enabled=False``.'
operationId: get_expose_api_expose_get
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/ExposeResponse'
put:
tags:
- api-expose
summary: Put Expose
description: 'Set per-entity toggle state.
Accepts a map of ``{key: bool}`` and upserts rows in the
``exposed_entity_toggle`` table. Only keys present in ``body.toggles``
are touched; other entities'' toggles are left unchanged.
After writing the toggles, triggers a HA Discovery re-publish so any
changes (enabled ↔ disabled) are reflected in Home Assistant immediately.'
operationId: put_expose_api_expose_put
parameters:
- name: X-CSRF-Token
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Csrf-Token
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ExposeUpdateRequest'
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/ExposeUpdateResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/api/expose/republish:
post:
tags:
- api-expose
summary: Post Expose Republish
description: 'Manually trigger a full HA Discovery re-publish.
Calls ``publish_discovery(session)`` from the HA discovery service (M5-T11).
Returns a status indicating whether the publish was attempted (or skipped
because MQTT / discovery is not enabled / connected).'
operationId: post_expose_republish_api_expose_republish_post
parameters:
- name: X-CSRF-Token
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Csrf-Token
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/RepublishResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/api/modbus/profiles:
get:
tags:
@@ -1267,6 +1373,19 @@ paths:
schema: {}
components:
schemas:
CatalogEntrySchema:
properties:
entity:
$ref: '#/components/schemas/ExposableEntitySchema'
enabled:
type: boolean
title: Enabled
type: object
required:
- entity
- enabled
title: CatalogEntrySchema
description: An entity from the catalog with its current toggle state.
ConfigField:
properties:
env_name:
@@ -1345,6 +1464,110 @@ components:
required:
- sections
title: ConfigUpdateResponse
DeviceInfoSchema:
properties:
identifiers:
items:
type: string
type: array
title: Identifiers
name:
type: string
title: Name
type: object
required:
- identifiers
- name
title: DeviceInfoSchema
description: HA device grouping info for an exposable entity.
ExposableEntitySchema:
properties:
key:
type: string
title: Key
component:
type: string
title: Component
device:
$ref: '#/components/schemas/DeviceInfoSchema'
device_class:
anyOf:
- type: string
- type: 'null'
title: Device Class
unit:
type: string
title: Unit
name:
type: string
title: Name
state_class:
anyOf:
- type: string
- type: 'null'
title: State Class
type: object
required:
- key
- component
- device
- device_class
- unit
- name
title: ExposableEntitySchema
description: '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.'
ExposeResponse:
properties:
catalog:
items:
$ref: '#/components/schemas/CatalogEntrySchema'
type: array
title: Catalog
mqtt_status:
$ref: '#/components/schemas/MqttStatusSchema'
type: object
required:
- catalog
- mqtt_status
title: ExposeResponse
description: Response for GET /api/expose.
ExposeUpdateRequest:
properties:
toggles:
additionalProperties:
type: boolean
type: object
title: Toggles
type: object
required:
- toggles
title: ExposeUpdateRequest
description: '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.'
ExposeUpdateResponse:
properties:
catalog:
items:
$ref: '#/components/schemas/CatalogEntrySchema'
type: array
title: Catalog
mqtt_status:
$ref: '#/components/schemas/MqttStatusSchema'
type: object
required:
- catalog
- mqtt_status
title: ExposeUpdateResponse
description: Response for PUT /api/expose (returns updated catalog + status).
HTTPValidationError:
properties:
detail:
@@ -1763,6 +1986,24 @@ components:
On success ``ok=True`` and ``payload`` contains the decoded values.
On failure ``ok=False`` and ``error`` describes the problem.'
MqttStatusSchema:
properties:
mqtt_configured:
type: boolean
title: Mqtt Configured
mqtt_connected:
type: boolean
title: Mqtt Connected
discovery_enabled:
type: boolean
title: Discovery Enabled
type: object
required:
- mqtt_configured
- mqtt_connected
- discovery_enabled
title: MqttStatusSchema
description: Connection status for MQTT and HA Discovery.
MqttTestResponse:
properties:
result:
@@ -1991,6 +2232,20 @@ components:
- last_check_error
- last_provider
title: PublicIPStateSchema
RepublishResponse:
properties:
ok:
type: boolean
title: Ok
message:
type: string
title: Message
type: object
required:
- ok
- message
title: RepublishResponse
description: Response for POST /api/expose/republish.
SessionResponse:
properties:
user: