M5-T05: add Modbus JSON API (device CRUD, readings, metrics, test)
This commit is contained in:
@@ -625,6 +625,502 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/modbus/profiles": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"api-modbus"
|
||||
],
|
||||
"summary": "Get Profiles",
|
||||
"description": "List all available Modbus YAML profiles (name + description).\n\nIntended for the front-end's device-creation profile drop-down.",
|
||||
"operationId": "get_profiles_api_modbus_profiles_get",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ModbusProfilesResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/modbus/devices": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"api-modbus"
|
||||
],
|
||||
"summary": "List Devices",
|
||||
"description": "Return all Modbus devices (no pagination — device counts stay small).",
|
||||
"operationId": "list_devices_api_modbus_devices_get",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ModbusDeviceListResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"tags": [
|
||||
"api-modbus"
|
||||
],
|
||||
"summary": "Create Device",
|
||||
"description": "Create a new Modbus device.\n\n- Validates that the referenced ``profile`` exists; returns 422 if not.\n- Returns 201 with the created device on success.",
|
||||
"operationId": "create_device_api_modbus_devices_post",
|
||||
"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/ModbusDeviceCreate"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ModbusDeviceResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/modbus/devices/{uuid}": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"api-modbus"
|
||||
],
|
||||
"summary": "Get Device",
|
||||
"description": "Return a single Modbus device by UUID.",
|
||||
"operationId": "get_device_api_modbus_devices__uuid__get",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"title": "Uuid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ModbusDeviceResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"patch": {
|
||||
"tags": [
|
||||
"api-modbus"
|
||||
],
|
||||
"summary": "Patch Device",
|
||||
"description": "Partially update a Modbus device (including enable/disable).\n\nOnly fields explicitly provided in the request body are updated.\nProviding ``profile`` triggers a profile-existence check (422 if unknown).",
|
||||
"operationId": "patch_device_api_modbus_devices__uuid__patch",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"title": "Uuid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"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/ModbusDeviceUpdate"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ModbusDeviceResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"tags": [
|
||||
"api-modbus"
|
||||
],
|
||||
"summary": "Delete Device",
|
||||
"description": "Delete a Modbus device.\n\nReturns 409 Conflict if the device has any associated readings; use\n``enabled=false`` to disable it instead.\n\n**Application-layer safety**: the check is performed via an explicit\nSELECT COUNT query — not by relying on SQLite's FK RESTRICT constraint,\nwhich is not enforced at runtime in this project (no PRAGMA foreign_keys=ON).",
|
||||
"operationId": "delete_device_api_modbus_devices__uuid__delete",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"title": "Uuid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "X-CSRF-Token",
|
||||
"in": "header",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "X-Csrf-Token"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "Successful Response"
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/modbus/devices/{uuid}/latest": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"api-modbus"
|
||||
],
|
||||
"summary": "Get Latest Reading",
|
||||
"description": "Return the most recent reading for a device.\n\nIf no readings exist yet, returns ``{\"found\": false, \"recorded_at\": null,\n\"payload\": null}`` (200, not 404) so the front-end can distinguish\n\"device exists but has no data\" from \"device not found\".",
|
||||
"operationId": "get_latest_reading_api_modbus_devices__uuid__latest_get",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"title": "Uuid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ModbusLatestResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/modbus/devices/{uuid}/readings": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"api-modbus"
|
||||
],
|
||||
"summary": "Get Readings",
|
||||
"description": "Return time-range readings for a device.\n\nResults are ordered by ``recorded_at`` ascending and capped by ``limit``\n(max {_READINGS_LIMIT_MAX}) to prevent accidental full-table exports.\n\nThe query uses the ``(device_id, recorded_at)`` composite index for\nefficient time-window scans.\n\nQuery parameters:\n- ``start``: inclusive lower bound (ISO8601 datetime)\n- ``end``: inclusive upper bound (ISO8601 datetime)\n- ``limit``: max rows to return (default 500, max {_READINGS_LIMIT_MAX})",
|
||||
"operationId": "get_readings_api_modbus_devices__uuid__readings_get",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"title": "Uuid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "start",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Start"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "end",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "End"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "limit",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"maximum": 5000,
|
||||
"minimum": 1,
|
||||
"default": 500,
|
||||
"title": "Limit"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ModbusReadingsResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/modbus/devices/{uuid}/metrics": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"api-modbus"
|
||||
],
|
||||
"summary": "Get Metrics",
|
||||
"description": "Return the metric catalogue for a device's profile.\n\nEach entry has ``key``, ``label`` (derived from key if the profile has\nnone — underscores → spaces, title-cased), ``unit``, and ``device_class``.\nThis is the authoritative metadata source for front-end card labels and\nchart axis labels.",
|
||||
"operationId": "get_metrics_api_modbus_devices__uuid__metrics_get",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"title": "Uuid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ModbusMetricsResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/modbus/devices/{uuid}/test": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"api-modbus"
|
||||
],
|
||||
"summary": "Test Read",
|
||||
"description": "Immediately read and decode the device once without persisting any data.\n\nUseful for validating gateway connectivity and Modbus address settings\nbefore relying on the background polling job.\n\nThis is a write-class endpoint (it initiates network I/O on demand) and\ntherefore requires a CSRF token. The response payload is never stored.",
|
||||
"operationId": "test_read_api_modbus_devices__uuid__test_post",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "uuid",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"title": "Uuid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"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/ModbusTestReadResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/session": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -1367,6 +1863,472 @@
|
||||
],
|
||||
"title": "LoginRequest"
|
||||
},
|
||||
"MetricInfo": {
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string",
|
||||
"title": "Key"
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"title": "Label"
|
||||
},
|
||||
"unit": {
|
||||
"type": "string",
|
||||
"title": "Unit"
|
||||
},
|
||||
"device_class": {
|
||||
"type": "string",
|
||||
"title": "Device Class"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"key",
|
||||
"label",
|
||||
"unit",
|
||||
"device_class"
|
||||
],
|
||||
"title": "MetricInfo",
|
||||
"description": "Metadata for a single measurable quantity in a device's profile."
|
||||
},
|
||||
"ModbusDeviceCreate": {
|
||||
"properties": {
|
||||
"friendly_name": {
|
||||
"type": "string",
|
||||
"maxLength": 255,
|
||||
"minLength": 1,
|
||||
"title": "Friendly Name"
|
||||
},
|
||||
"transport": {
|
||||
"type": "string",
|
||||
"maxLength": 16,
|
||||
"title": "Transport",
|
||||
"default": "tcp"
|
||||
},
|
||||
"host": {
|
||||
"type": "string",
|
||||
"maxLength": 255,
|
||||
"minLength": 1,
|
||||
"title": "Host"
|
||||
},
|
||||
"port": {
|
||||
"type": "integer",
|
||||
"maximum": 65535.0,
|
||||
"minimum": 1.0,
|
||||
"title": "Port",
|
||||
"default": 502
|
||||
},
|
||||
"unit_id": {
|
||||
"type": "integer",
|
||||
"maximum": 247.0,
|
||||
"minimum": 0.0,
|
||||
"title": "Unit Id",
|
||||
"default": 1
|
||||
},
|
||||
"profile": {
|
||||
"type": "string",
|
||||
"maxLength": 64,
|
||||
"minLength": 1,
|
||||
"title": "Profile"
|
||||
},
|
||||
"poll_interval_s": {
|
||||
"type": "integer",
|
||||
"maximum": 3600.0,
|
||||
"minimum": 1.0,
|
||||
"title": "Poll Interval S",
|
||||
"default": 5
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"title": "Enabled",
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"friendly_name",
|
||||
"host",
|
||||
"profile"
|
||||
],
|
||||
"title": "ModbusDeviceCreate",
|
||||
"description": "Request body for POST /api/modbus/devices."
|
||||
},
|
||||
"ModbusDeviceListResponse": {
|
||||
"properties": {
|
||||
"items": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ModbusDeviceResponse"
|
||||
},
|
||||
"type": "array",
|
||||
"title": "Items"
|
||||
},
|
||||
"total": {
|
||||
"type": "integer",
|
||||
"title": "Total"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"items",
|
||||
"total"
|
||||
],
|
||||
"title": "ModbusDeviceListResponse",
|
||||
"description": "Response schema for listing Modbus devices."
|
||||
},
|
||||
"ModbusDeviceResponse": {
|
||||
"properties": {
|
||||
"uuid": {
|
||||
"type": "string",
|
||||
"title": "Uuid"
|
||||
},
|
||||
"friendly_name": {
|
||||
"type": "string",
|
||||
"title": "Friendly Name"
|
||||
},
|
||||
"transport": {
|
||||
"type": "string",
|
||||
"title": "Transport"
|
||||
},
|
||||
"host": {
|
||||
"type": "string",
|
||||
"title": "Host"
|
||||
},
|
||||
"port": {
|
||||
"type": "integer",
|
||||
"title": "Port"
|
||||
},
|
||||
"unit_id": {
|
||||
"type": "integer",
|
||||
"title": "Unit Id"
|
||||
},
|
||||
"profile": {
|
||||
"type": "string",
|
||||
"title": "Profile"
|
||||
},
|
||||
"poll_interval_s": {
|
||||
"type": "integer",
|
||||
"title": "Poll Interval S"
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"title": "Enabled"
|
||||
},
|
||||
"last_poll_at": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Last Poll At"
|
||||
},
|
||||
"last_poll_ok": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Last Poll Ok"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"title": "Created At"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"title": "Updated At"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"uuid",
|
||||
"friendly_name",
|
||||
"transport",
|
||||
"host",
|
||||
"port",
|
||||
"unit_id",
|
||||
"profile",
|
||||
"poll_interval_s",
|
||||
"enabled",
|
||||
"last_poll_at",
|
||||
"last_poll_ok",
|
||||
"created_at",
|
||||
"updated_at"
|
||||
],
|
||||
"title": "ModbusDeviceResponse",
|
||||
"description": "Response schema for a single Modbus device."
|
||||
},
|
||||
"ModbusDeviceUpdate": {
|
||||
"properties": {
|
||||
"friendly_name": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"maxLength": 255,
|
||||
"minLength": 1
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Friendly Name"
|
||||
},
|
||||
"transport": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"maxLength": 16
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Transport"
|
||||
},
|
||||
"host": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"maxLength": 255,
|
||||
"minLength": 1
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Host"
|
||||
},
|
||||
"port": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"maximum": 65535.0,
|
||||
"minimum": 1.0
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Port"
|
||||
},
|
||||
"unit_id": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"maximum": 247.0,
|
||||
"minimum": 0.0
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Unit Id"
|
||||
},
|
||||
"profile": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"maxLength": 64,
|
||||
"minLength": 1
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Profile"
|
||||
},
|
||||
"poll_interval_s": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"maximum": 3600.0,
|
||||
"minimum": 1.0
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Poll Interval S"
|
||||
},
|
||||
"enabled": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Enabled"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"title": "ModbusDeviceUpdate",
|
||||
"description": "Request body for PATCH /api/modbus/devices/{uuid} — all fields optional."
|
||||
},
|
||||
"ModbusLatestResponse": {
|
||||
"properties": {
|
||||
"found": {
|
||||
"type": "boolean",
|
||||
"title": "Found"
|
||||
},
|
||||
"recorded_at": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Recorded At"
|
||||
},
|
||||
"payload": {
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": true,
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Payload"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"found",
|
||||
"recorded_at",
|
||||
"payload"
|
||||
],
|
||||
"title": "ModbusLatestResponse",
|
||||
"description": "Response for the /latest endpoint.\n\n``found`` is False and ``recorded_at``/``payload`` are None when the device\nhas no readings yet. Callers should check ``found`` before using the values."
|
||||
},
|
||||
"ModbusMetricsResponse": {
|
||||
"properties": {
|
||||
"profile": {
|
||||
"type": "string",
|
||||
"title": "Profile"
|
||||
},
|
||||
"metrics": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/MetricInfo"
|
||||
},
|
||||
"type": "array",
|
||||
"title": "Metrics"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"profile",
|
||||
"metrics"
|
||||
],
|
||||
"title": "ModbusMetricsResponse",
|
||||
"description": "Response schema for GET /api/modbus/devices/{uuid}/metrics."
|
||||
},
|
||||
"ModbusProfilesResponse": {
|
||||
"properties": {
|
||||
"profiles": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ProfileSummary"
|
||||
},
|
||||
"type": "array",
|
||||
"title": "Profiles"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"profiles"
|
||||
],
|
||||
"title": "ModbusProfilesResponse",
|
||||
"description": "Response schema for GET /api/modbus/profiles."
|
||||
},
|
||||
"ModbusReadingResponse": {
|
||||
"properties": {
|
||||
"recorded_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"title": "Recorded At"
|
||||
},
|
||||
"payload": {
|
||||
"additionalProperties": true,
|
||||
"type": "object",
|
||||
"title": "Payload"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"recorded_at",
|
||||
"payload"
|
||||
],
|
||||
"title": "ModbusReadingResponse",
|
||||
"description": "A single reading row: timestamp + decoded payload."
|
||||
},
|
||||
"ModbusReadingsResponse": {
|
||||
"properties": {
|
||||
"items": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ModbusReadingResponse"
|
||||
},
|
||||
"type": "array",
|
||||
"title": "Items"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"title": "ModbusReadingsResponse",
|
||||
"description": "Response schema for the readings time-range endpoint."
|
||||
},
|
||||
"ModbusTestReadResponse": {
|
||||
"properties": {
|
||||
"ok": {
|
||||
"type": "boolean",
|
||||
"title": "Ok"
|
||||
},
|
||||
"payload": {
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": true,
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Payload"
|
||||
},
|
||||
"error": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Error"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ok"
|
||||
],
|
||||
"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."
|
||||
},
|
||||
"PasswordChangeRequest": {
|
||||
"properties": {
|
||||
"current_password": {
|
||||
@@ -1484,6 +2446,25 @@
|
||||
"title": "PooUpdateRequest",
|
||||
"description": "PATCH body for a poo record — all fields optional; PK field excluded."
|
||||
},
|
||||
"ProfileSummary": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"title": "Name"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"title": "Description"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"description"
|
||||
],
|
||||
"title": "ProfileSummary",
|
||||
"description": "One entry in the GET /api/modbus/profiles response."
|
||||
},
|
||||
"PublicIPCheckResponse": {
|
||||
"properties": {
|
||||
"status": {
|
||||
|
||||
@@ -452,6 +452,379 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/HTTPValidationError'
|
||||
/api/modbus/profiles:
|
||||
get:
|
||||
tags:
|
||||
- api-modbus
|
||||
summary: Get Profiles
|
||||
description: 'List all available Modbus YAML profiles (name + description).
|
||||
|
||||
|
||||
Intended for the front-end''s device-creation profile drop-down.'
|
||||
operationId: get_profiles_api_modbus_profiles_get
|
||||
responses:
|
||||
'200':
|
||||
description: Successful Response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ModbusProfilesResponse'
|
||||
/api/modbus/devices:
|
||||
get:
|
||||
tags:
|
||||
- api-modbus
|
||||
summary: List Devices
|
||||
description: Return all Modbus devices (no pagination — device counts stay small).
|
||||
operationId: list_devices_api_modbus_devices_get
|
||||
responses:
|
||||
'200':
|
||||
description: Successful Response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ModbusDeviceListResponse'
|
||||
post:
|
||||
tags:
|
||||
- api-modbus
|
||||
summary: Create Device
|
||||
description: 'Create a new Modbus device.
|
||||
|
||||
|
||||
- Validates that the referenced ``profile`` exists; returns 422 if not.
|
||||
|
||||
- Returns 201 with the created device on success.'
|
||||
operationId: create_device_api_modbus_devices_post
|
||||
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/ModbusDeviceCreate'
|
||||
responses:
|
||||
'201':
|
||||
description: Successful Response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ModbusDeviceResponse'
|
||||
'422':
|
||||
description: Validation Error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/HTTPValidationError'
|
||||
/api/modbus/devices/{uuid}:
|
||||
get:
|
||||
tags:
|
||||
- api-modbus
|
||||
summary: Get Device
|
||||
description: Return a single Modbus device by UUID.
|
||||
operationId: get_device_api_modbus_devices__uuid__get
|
||||
parameters:
|
||||
- name: uuid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
title: Uuid
|
||||
responses:
|
||||
'200':
|
||||
description: Successful Response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ModbusDeviceResponse'
|
||||
'422':
|
||||
description: Validation Error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/HTTPValidationError'
|
||||
patch:
|
||||
tags:
|
||||
- api-modbus
|
||||
summary: Patch Device
|
||||
description: 'Partially update a Modbus device (including enable/disable).
|
||||
|
||||
|
||||
Only fields explicitly provided in the request body are updated.
|
||||
|
||||
Providing ``profile`` triggers a profile-existence check (422 if unknown).'
|
||||
operationId: patch_device_api_modbus_devices__uuid__patch
|
||||
parameters:
|
||||
- name: uuid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
title: Uuid
|
||||
- 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/ModbusDeviceUpdate'
|
||||
responses:
|
||||
'200':
|
||||
description: Successful Response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ModbusDeviceResponse'
|
||||
'422':
|
||||
description: Validation Error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/HTTPValidationError'
|
||||
delete:
|
||||
tags:
|
||||
- api-modbus
|
||||
summary: Delete Device
|
||||
description: 'Delete a Modbus device.
|
||||
|
||||
|
||||
Returns 409 Conflict if the device has any associated readings; use
|
||||
|
||||
``enabled=false`` to disable it instead.
|
||||
|
||||
|
||||
**Application-layer safety**: the check is performed via an explicit
|
||||
|
||||
SELECT COUNT query — not by relying on SQLite''s FK RESTRICT constraint,
|
||||
|
||||
which is not enforced at runtime in this project (no PRAGMA foreign_keys=ON).'
|
||||
operationId: delete_device_api_modbus_devices__uuid__delete
|
||||
parameters:
|
||||
- name: uuid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
title: Uuid
|
||||
- name: X-CSRF-Token
|
||||
in: header
|
||||
required: false
|
||||
schema:
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: 'null'
|
||||
title: X-Csrf-Token
|
||||
responses:
|
||||
'204':
|
||||
description: Successful Response
|
||||
'422':
|
||||
description: Validation Error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/HTTPValidationError'
|
||||
/api/modbus/devices/{uuid}/latest:
|
||||
get:
|
||||
tags:
|
||||
- api-modbus
|
||||
summary: Get Latest Reading
|
||||
description: 'Return the most recent reading for a device.
|
||||
|
||||
|
||||
If no readings exist yet, returns ``{"found": false, "recorded_at": null,
|
||||
|
||||
"payload": null}`` (200, not 404) so the front-end can distinguish
|
||||
|
||||
"device exists but has no data" from "device not found".'
|
||||
operationId: get_latest_reading_api_modbus_devices__uuid__latest_get
|
||||
parameters:
|
||||
- name: uuid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
title: Uuid
|
||||
responses:
|
||||
'200':
|
||||
description: Successful Response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ModbusLatestResponse'
|
||||
'422':
|
||||
description: Validation Error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/HTTPValidationError'
|
||||
/api/modbus/devices/{uuid}/readings:
|
||||
get:
|
||||
tags:
|
||||
- api-modbus
|
||||
summary: Get Readings
|
||||
description: 'Return time-range readings for a device.
|
||||
|
||||
|
||||
Results are ordered by ``recorded_at`` ascending and capped by ``limit``
|
||||
|
||||
(max {_READINGS_LIMIT_MAX}) to prevent accidental full-table exports.
|
||||
|
||||
|
||||
The query uses the ``(device_id, recorded_at)`` composite index for
|
||||
|
||||
efficient time-window scans.
|
||||
|
||||
|
||||
Query parameters:
|
||||
|
||||
- ``start``: inclusive lower bound (ISO8601 datetime)
|
||||
|
||||
- ``end``: inclusive upper bound (ISO8601 datetime)
|
||||
|
||||
- ``limit``: max rows to return (default 500, max {_READINGS_LIMIT_MAX})'
|
||||
operationId: get_readings_api_modbus_devices__uuid__readings_get
|
||||
parameters:
|
||||
- name: uuid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
title: Uuid
|
||||
- name: start
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
anyOf:
|
||||
- type: string
|
||||
format: date-time
|
||||
- type: 'null'
|
||||
title: Start
|
||||
- name: end
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
anyOf:
|
||||
- type: string
|
||||
format: date-time
|
||||
- type: 'null'
|
||||
title: End
|
||||
- name: limit
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
maximum: 5000
|
||||
minimum: 1
|
||||
default: 500
|
||||
title: Limit
|
||||
responses:
|
||||
'200':
|
||||
description: Successful Response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ModbusReadingsResponse'
|
||||
'422':
|
||||
description: Validation Error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/HTTPValidationError'
|
||||
/api/modbus/devices/{uuid}/metrics:
|
||||
get:
|
||||
tags:
|
||||
- api-modbus
|
||||
summary: Get Metrics
|
||||
description: 'Return the metric catalogue for a device''s profile.
|
||||
|
||||
|
||||
Each entry has ``key``, ``label`` (derived from key if the profile has
|
||||
|
||||
none — underscores → spaces, title-cased), ``unit``, and ``device_class``.
|
||||
|
||||
This is the authoritative metadata source for front-end card labels and
|
||||
|
||||
chart axis labels.'
|
||||
operationId: get_metrics_api_modbus_devices__uuid__metrics_get
|
||||
parameters:
|
||||
- name: uuid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
title: Uuid
|
||||
responses:
|
||||
'200':
|
||||
description: Successful Response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ModbusMetricsResponse'
|
||||
'422':
|
||||
description: Validation Error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/HTTPValidationError'
|
||||
/api/modbus/devices/{uuid}/test:
|
||||
post:
|
||||
tags:
|
||||
- api-modbus
|
||||
summary: Test Read
|
||||
description: 'Immediately read and decode the device once without persisting
|
||||
any data.
|
||||
|
||||
|
||||
Useful for validating gateway connectivity and Modbus address settings
|
||||
|
||||
before relying on the background polling job.
|
||||
|
||||
|
||||
This is a write-class endpoint (it initiates network I/O on demand) and
|
||||
|
||||
therefore requires a CSRF token. The response payload is never stored.'
|
||||
operationId: test_read_api_modbus_devices__uuid__test_post
|
||||
parameters:
|
||||
- name: uuid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
title: Uuid
|
||||
- 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/ModbusTestReadResponse'
|
||||
'422':
|
||||
description: Validation Error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/HTTPValidationError'
|
||||
/api/session:
|
||||
get:
|
||||
tags:
|
||||
@@ -987,6 +1360,330 @@ components:
|
||||
- username
|
||||
- password
|
||||
title: LoginRequest
|
||||
MetricInfo:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
title: Key
|
||||
label:
|
||||
type: string
|
||||
title: Label
|
||||
unit:
|
||||
type: string
|
||||
title: Unit
|
||||
device_class:
|
||||
type: string
|
||||
title: Device Class
|
||||
type: object
|
||||
required:
|
||||
- key
|
||||
- label
|
||||
- unit
|
||||
- device_class
|
||||
title: MetricInfo
|
||||
description: Metadata for a single measurable quantity in a device's profile.
|
||||
ModbusDeviceCreate:
|
||||
properties:
|
||||
friendly_name:
|
||||
type: string
|
||||
maxLength: 255
|
||||
minLength: 1
|
||||
title: Friendly Name
|
||||
transport:
|
||||
type: string
|
||||
maxLength: 16
|
||||
title: Transport
|
||||
default: tcp
|
||||
host:
|
||||
type: string
|
||||
maxLength: 255
|
||||
minLength: 1
|
||||
title: Host
|
||||
port:
|
||||
type: integer
|
||||
maximum: 65535.0
|
||||
minimum: 1.0
|
||||
title: Port
|
||||
default: 502
|
||||
unit_id:
|
||||
type: integer
|
||||
maximum: 247.0
|
||||
minimum: 0.0
|
||||
title: Unit Id
|
||||
default: 1
|
||||
profile:
|
||||
type: string
|
||||
maxLength: 64
|
||||
minLength: 1
|
||||
title: Profile
|
||||
poll_interval_s:
|
||||
type: integer
|
||||
maximum: 3600.0
|
||||
minimum: 1.0
|
||||
title: Poll Interval S
|
||||
default: 5
|
||||
enabled:
|
||||
type: boolean
|
||||
title: Enabled
|
||||
default: true
|
||||
type: object
|
||||
required:
|
||||
- friendly_name
|
||||
- host
|
||||
- profile
|
||||
title: ModbusDeviceCreate
|
||||
description: Request body for POST /api/modbus/devices.
|
||||
ModbusDeviceListResponse:
|
||||
properties:
|
||||
items:
|
||||
items:
|
||||
$ref: '#/components/schemas/ModbusDeviceResponse'
|
||||
type: array
|
||||
title: Items
|
||||
total:
|
||||
type: integer
|
||||
title: Total
|
||||
type: object
|
||||
required:
|
||||
- items
|
||||
- total
|
||||
title: ModbusDeviceListResponse
|
||||
description: Response schema for listing Modbus devices.
|
||||
ModbusDeviceResponse:
|
||||
properties:
|
||||
uuid:
|
||||
type: string
|
||||
title: Uuid
|
||||
friendly_name:
|
||||
type: string
|
||||
title: Friendly Name
|
||||
transport:
|
||||
type: string
|
||||
title: Transport
|
||||
host:
|
||||
type: string
|
||||
title: Host
|
||||
port:
|
||||
type: integer
|
||||
title: Port
|
||||
unit_id:
|
||||
type: integer
|
||||
title: Unit Id
|
||||
profile:
|
||||
type: string
|
||||
title: Profile
|
||||
poll_interval_s:
|
||||
type: integer
|
||||
title: Poll Interval S
|
||||
enabled:
|
||||
type: boolean
|
||||
title: Enabled
|
||||
last_poll_at:
|
||||
anyOf:
|
||||
- type: string
|
||||
format: date-time
|
||||
- type: 'null'
|
||||
title: Last Poll At
|
||||
last_poll_ok:
|
||||
anyOf:
|
||||
- type: boolean
|
||||
- type: 'null'
|
||||
title: Last Poll Ok
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
title: Created At
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
title: Updated At
|
||||
type: object
|
||||
required:
|
||||
- uuid
|
||||
- friendly_name
|
||||
- transport
|
||||
- host
|
||||
- port
|
||||
- unit_id
|
||||
- profile
|
||||
- poll_interval_s
|
||||
- enabled
|
||||
- last_poll_at
|
||||
- last_poll_ok
|
||||
- created_at
|
||||
- updated_at
|
||||
title: ModbusDeviceResponse
|
||||
description: Response schema for a single Modbus device.
|
||||
ModbusDeviceUpdate:
|
||||
properties:
|
||||
friendly_name:
|
||||
anyOf:
|
||||
- type: string
|
||||
maxLength: 255
|
||||
minLength: 1
|
||||
- type: 'null'
|
||||
title: Friendly Name
|
||||
transport:
|
||||
anyOf:
|
||||
- type: string
|
||||
maxLength: 16
|
||||
- type: 'null'
|
||||
title: Transport
|
||||
host:
|
||||
anyOf:
|
||||
- type: string
|
||||
maxLength: 255
|
||||
minLength: 1
|
||||
- type: 'null'
|
||||
title: Host
|
||||
port:
|
||||
anyOf:
|
||||
- type: integer
|
||||
maximum: 65535.0
|
||||
minimum: 1.0
|
||||
- type: 'null'
|
||||
title: Port
|
||||
unit_id:
|
||||
anyOf:
|
||||
- type: integer
|
||||
maximum: 247.0
|
||||
minimum: 0.0
|
||||
- type: 'null'
|
||||
title: Unit Id
|
||||
profile:
|
||||
anyOf:
|
||||
- type: string
|
||||
maxLength: 64
|
||||
minLength: 1
|
||||
- type: 'null'
|
||||
title: Profile
|
||||
poll_interval_s:
|
||||
anyOf:
|
||||
- type: integer
|
||||
maximum: 3600.0
|
||||
minimum: 1.0
|
||||
- type: 'null'
|
||||
title: Poll Interval S
|
||||
enabled:
|
||||
anyOf:
|
||||
- type: boolean
|
||||
- type: 'null'
|
||||
title: Enabled
|
||||
type: object
|
||||
title: ModbusDeviceUpdate
|
||||
description: Request body for PATCH /api/modbus/devices/{uuid} — all fields
|
||||
optional.
|
||||
ModbusLatestResponse:
|
||||
properties:
|
||||
found:
|
||||
type: boolean
|
||||
title: Found
|
||||
recorded_at:
|
||||
anyOf:
|
||||
- type: string
|
||||
format: date-time
|
||||
- type: 'null'
|
||||
title: Recorded At
|
||||
payload:
|
||||
anyOf:
|
||||
- additionalProperties: true
|
||||
type: object
|
||||
- type: 'null'
|
||||
title: Payload
|
||||
type: object
|
||||
required:
|
||||
- found
|
||||
- recorded_at
|
||||
- payload
|
||||
title: ModbusLatestResponse
|
||||
description: 'Response for the /latest endpoint.
|
||||
|
||||
|
||||
``found`` is False and ``recorded_at``/``payload`` are None when the device
|
||||
|
||||
has no readings yet. Callers should check ``found`` before using the values.'
|
||||
ModbusMetricsResponse:
|
||||
properties:
|
||||
profile:
|
||||
type: string
|
||||
title: Profile
|
||||
metrics:
|
||||
items:
|
||||
$ref: '#/components/schemas/MetricInfo'
|
||||
type: array
|
||||
title: Metrics
|
||||
type: object
|
||||
required:
|
||||
- profile
|
||||
- metrics
|
||||
title: ModbusMetricsResponse
|
||||
description: Response schema for GET /api/modbus/devices/{uuid}/metrics.
|
||||
ModbusProfilesResponse:
|
||||
properties:
|
||||
profiles:
|
||||
items:
|
||||
$ref: '#/components/schemas/ProfileSummary'
|
||||
type: array
|
||||
title: Profiles
|
||||
type: object
|
||||
required:
|
||||
- profiles
|
||||
title: ModbusProfilesResponse
|
||||
description: Response schema for GET /api/modbus/profiles.
|
||||
ModbusReadingResponse:
|
||||
properties:
|
||||
recorded_at:
|
||||
type: string
|
||||
format: date-time
|
||||
title: Recorded At
|
||||
payload:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
title: Payload
|
||||
type: object
|
||||
required:
|
||||
- recorded_at
|
||||
- payload
|
||||
title: ModbusReadingResponse
|
||||
description: 'A single reading row: timestamp + decoded payload.'
|
||||
ModbusReadingsResponse:
|
||||
properties:
|
||||
items:
|
||||
items:
|
||||
$ref: '#/components/schemas/ModbusReadingResponse'
|
||||
type: array
|
||||
title: Items
|
||||
type: object
|
||||
required:
|
||||
- items
|
||||
title: ModbusReadingsResponse
|
||||
description: Response schema for the readings time-range endpoint.
|
||||
ModbusTestReadResponse:
|
||||
properties:
|
||||
ok:
|
||||
type: boolean
|
||||
title: Ok
|
||||
payload:
|
||||
anyOf:
|
||||
- additionalProperties: true
|
||||
type: object
|
||||
- type: 'null'
|
||||
title: Payload
|
||||
error:
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: 'null'
|
||||
title: Error
|
||||
type: object
|
||||
required:
|
||||
- ok
|
||||
title: ModbusTestReadResponse
|
||||
description: 'Response for POST /api/modbus/devices/{uuid}/test.
|
||||
|
||||
|
||||
On success ``ok=True`` and ``payload`` contains the decoded values.
|
||||
|
||||
On failure ``ok=False`` and ``error`` describes the problem.'
|
||||
PasswordChangeRequest:
|
||||
properties:
|
||||
current_password:
|
||||
@@ -1064,6 +1761,20 @@ components:
|
||||
type: object
|
||||
title: PooUpdateRequest
|
||||
description: PATCH body for a poo record — all fields optional; PK field excluded.
|
||||
ProfileSummary:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
title: Name
|
||||
description:
|
||||
type: string
|
||||
title: Description
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- description
|
||||
title: ProfileSummary
|
||||
description: One entry in the GET /api/modbus/profiles response.
|
||||
PublicIPCheckResponse:
|
||||
properties:
|
||||
status:
|
||||
|
||||
Reference in New Issue
Block a user