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": {