From d94fd8e1185f601028ff81ba90c995b40b2a30d4 Mon Sep 17 00:00:00 2001 From: Eric Bariaux <375613+ebariaux@users.noreply.github.com> Date: Tue, 6 Jan 2026 14:36:34 +0100 Subject: [PATCH 1/6] Added documentation on ESP32 devices support and the ESPProvision mechanism and console provider --- .gitignore | 1 + api/provisioningapi.yaml | 89 +++++++ docs/architecture/apps-and-consoles.md | 319 +++++++++++++++++++++++++ docs/architecture/esp32-device.md | 107 +++++++++ docusaurus.config.ts | 10 + 5 files changed, 526 insertions(+) create mode 100644 api/provisioningapi.yaml create mode 100644 docs/architecture/esp32-device.md diff --git a/.gitignore b/.gitignore index 1a6e7fc8..a697acd3 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ npm-debug.log* yarn-debug.log* yarn-error.log* +docs/provisioning-api diff --git a/api/provisioningapi.yaml b/api/provisioningapi.yaml new file mode 100644 index 00000000..6b30a5b9 --- /dev/null +++ b/api/provisioningapi.yaml @@ -0,0 +1,89 @@ +openapi: "3.0.2" +info: + title: Provisioning REST API + description: Provisioning REST API + contact: + email: info@openremote.io + license: + name: AGPL 3.0 + url: https://www.gnu.org/licenses/agpl-3.0.en.html + version: "1.0" +servers: + - url: "https://demo.openremote.io/api/{realm}/" + variables: + realm: + default: master +security: + - bearerAuth: [] +paths: + /device: + post: + summary: Provisions a new device for the user + description: Provisions a new device, creating both an Asset to represent it and a Service Account for the device to connect over MQTT. The asset type is selected based on the provided modelName. If none matches, an error is reported. + requestBody: + $ref: "#/components/requestBodies/DeviceProvisioning" + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: "#/components/responses/DeviceProvisioningResponse" + '401': + $ref: '#/components/responses/UnauthorizedError' + '403': + $ref: '#/components/responses/ForbiddenError' +components: + securitySchemes: + bearerAuth: # arbitrary name for the security scheme + type: http + scheme: bearer + requestBodies: + DeviceProvisioning: + content: + application/json: + schema: + type: object + required: + - deviceId + - password + properties: + deviceId: + type: string + description: ID of device + example: "123456789ABC" + password: + type: string + description: Password for service account + example: "s3cr3t" + modelName: + type: string + description: Model of device to provision + example: "orbattery" + responses: + UnauthorizedError: + description: Access token is missing or invalid + ForbiddenError: + description: Principal is not allowed to perform this operation + DeviceProvisioningResponse: + content: + application/json: + schema: + type: object + required: + - assetId + - assetCreated + - serviceUserCreated + properties: + assetId: + type: string + description: OpenRemote Asset ID + example: "6tXbmMvQLd2e7UrY5xLviR" + assetCreated: + type: boolean + description: Indicates if the battery asset was created by this call (true) or already existed (false) + example: true + serviceUserCreated: + type: boolean + description: Indicates if the service user was created by this call (true) or already existed (false) + example: true \ No newline at end of file diff --git a/docs/architecture/apps-and-consoles.md b/docs/architecture/apps-and-consoles.md index 92ff4cdb..d1a92586 100644 --- a/docs/architecture/apps-and-consoles.md +++ b/docs/architecture/apps-and-consoles.md @@ -327,3 +327,322 @@ Start the camera and scan a QR code. } } ``` + +### ESP Provision (provider: "espprovision") +Allows provisioning an ESP32 device in the system via a 3-step workflow: +1. discover the device and establish a secure communication to the device over BLE +2. discover Wifi networks and configure the device to connect to it +3. provision the device in the backend and configure the device to connect to the backend + +This is based on Espressif [Unified Provisioning](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/provisioning/provisioning.html) +and uses their [esp-idf-provisioning-ios](https://github.com/espressif/esp-idf-provisioning-ios) and [esp-idf-provisioning-android](https://github.com/espressif/esp-idf-provisioning-android) libraries. + +#### Start BLE scan (App -> Console) + +Starts a BLE scans without any timeout. + +```json +{ + "provider": "espprovision", + "action": "START_BLE_SCAN", + "prefix": "PROV_" +} +``` + +The prefix value is optional, if not specified a default empty value is used. + +The returned devices are filtered based on their service name having the given prefix. + +#### BLE scan error response (Console -> App) + +If there’s an error starting or during the scan, the following message is sent + +```json +{ + "provider": "espprovision", + "action": "STOP_BLE_SCAN", + "errorCode": , + "errorMessage": "An optional detail message about the error, not meant for end-user" +} +``` + +All errors will be reported to the web application and not handled by the native code. + +| Error | errorCode | Reason | +|----------------|-----------|-------------------------------------------------------------------------------------------------------| +| Timeout | 600 | A timeout (120s) occurred during device search (even if some devices were already found and reported) | +| Generic error | 10000 | A non specific error has occurred | + +#### BLE scan response (Console -> App) + +Periodically during the scan, if the provider has found BLE devices, it will send the complete list to the web app using the below structure + +```json +{ + "provider": "espprovision", + "action": "START_BLE_SCAN", + "devices": [ + { + "id": "", + "name": "", + "signalStrengh": "" + }, ... + ] +} +``` +signalStrengh is optional, it will not be present in a first version. + +#### Stop BLE scan (App -> Console) + +Stops on-going BLE scans, calling this if none is underway is not an error. + +```json +{ + "provider": "espprovision", + "action": "STOP_BLE_SCAN" +} +``` + +#### BLE scan stop response (Console -> App) + +Always sends back a confirmation message, even if no scan was underway. +This message is also sent when the scan is stopped upon connection to a device. + +```json +{ + "provider": "espprovision", + "action": "STOP_BLE_SCAN" +} +``` + +#### Connect to device (App -> Console) + +Establishes a secure connection to the device with the given id. + +This also stops any BLE scan that was in progress. + +```json +{ + "provider": "espprovision", + "action": "CONNECT_TO_DEVICE", + "id": "", + "pop": "xyz" +} +``` + +The pop (Proof of Possession) is used for establishing the security layer of the device communication channel. +If not provided, a default value is used. + +#### Device connection status (Console -> App) + +Connection status information can be sent at any time (and multiple times), +e.g. if at any point the BLE connection is lost, message with status `disconnected` is sent. + +```json +{ + "provider": "espprovision", + "action": "CONNECT_TO_DEVICE", + "id": "", + "status": "connected" | "disconnected" | "connectionError", + "errorCode": , + "errorMessage": "An optional detail message about the error, not meant for end-user" +} +``` + +Possible error codes +| Error | errorCode | Reason | +|----------------------|-----------|---------------------------------------------------------------------------| +| Unknown device | 100 | The provided id was not discovered in the previous search | +| BLE connection error | 200 | Error establishing a BLE connection with the device | +| Communication error | 301 | Error establishing a connection with the device (on top of BLE connection)| +| Security error | 400 | Error while handling security (includes invalid credentials) | +| Generic error | 10000 | A non specific error has occurred | + +#### Disconnect from device (App -> Console) + +```json +{ + "provider": "espprovision", + "action": "DISCONNECT_FROM_DEVICE" +} +``` + +#### Start Wifi scan (App -> Console) + +Asks the connected device to start a WiFi scan without any timeout. + +```json +{ + "provider": "espprovision", + "action": "START_WIFI_SCAN" +} +``` + +#### Wifi scan error response (Console -> App) + +If there’s an error starting or during the scan, the following message is sent +```json +{ + "provider": "espprovision", + "action": "STOP_WIFI_SCAN", + "errorCode": , + "errorMessage": "An optional detail message about the error, not meant for end-user" +} +``` + +| Error | errorCode | Reason | +|---------------------|-----------|--------------------------------------------------------------------------------------------| +| Not connected | 300 | There is no communication channel with the device | +| Communication error | 301 | Error in communication with device to start scan or receive information back | +| Timeout | 600 | A timeout (120s) occurred during wifi scan (even if some networks were already found and reported) | + +#### Wifi scan response (Console -> App) + +Periodically during the scan, if the provider has found SSIDs, it will send the complete list to the web app using the below structure + +```json +{ + "provider": "espprovision", + "action": "START_WIFI_SCAN", + "networks": [ + { + "ssid": "", + "signalStrengh": -12 + }, ... + ] +} +``` + +#### Stop Wifi scan (App -> Console) + +Stops on-going WiFi scans, calling this if none is underway is not an error. + +```json +{ + "provider": "espprovision", + "action": "STOP_WIFI_SCAN" +} +``` + +#### Stop Wifi scan response (Console -> App) + +Always sends back a confirmation message, even if no scan was underway. +```json +{ + "provider": "espprovision", + "action": "STOP_WIFI_SCAN" +} +``` +Implementation note: there is no command to stop the WiFi scan on the device, but it only does it for a limited amount of time. +The provider is the one implementing a loop to scan “indefinitely”. +When the STOP_WIFI_SCAN command is sent, the provider stops this loop. + +#### Send Wifi configuration (App -> Console) + +Sends SSID and password to the device for it to configure its Wifi network. + +This also stops any WiFi scan that was in progress. + +```json +{ + "provider": "espprovision", + "action": "SEND_WIFI_CONFIGURATION", + "ssid": "", + "password": "" +} +``` + +#### Wifi configuration response (Console -> App) + +Once device has reported its status, the following information is sent by the provider + +```json +{ + "provider": "espprovision", + "action": "SEND_WIFI_CONFIGURATION", + "connected": true | false, + "errorCode": , + "errorMessage": "An optional detail message about the error, not meant for end-user" +} +``` +| Error | errorCode | Reason | +|----------------------------|-----------|--------------------------------------------------------------------------| +| Not connected | 300 | There is no communication channel with the device | +| Communication error | 301 | Error in communication with device to start scan or receive information back | +| WiFi configuration error | 500 | Error in applying the provided Wifi configuration | +| Wifi communication error | 501 | Could not determine the status of the Wifi network | +| Wifi authentication error | 502 | Wrong Wifi credentials | +| Wifi network not found | 503 | Could not find given Wifi network | +| Generic error | 10000 | A non specific error has occurred | + +#### Provision device (App -> Console) +```json +{ + "provider": "espprovision", + "action": "PROVISION_DEVICE" + "userToken": "" +} +``` + +Provisions the device with the backend. A valid authentication token towards the backend, +as the user logged in to the app, must be provided in `userToken`. + +The provider will perform all the required steps to accomplish this and notify back the status to the caller. + +This includes: +- Getting the model name and device id from the device +- Generating a random password +- Provisioning the device with the backend, creating the required asset and service account. + The provider performs a `POST` on `/rest/device` to trigger this. +- Linked the created asset to the end user account (corresponding to userToken) +- Sending the required configuration to the device +- Waiting for the device to connect + +#### Provision device response (Console -> App) + +Once the device is connected to the backend or if connection failed, the following information is sent by the provider + +```json +{ + "provider": "espprovision", + "action": "PROVISION_DEVICE", + "connected": true | false, + "errorCode": , + "errorMessage": "An optional detail message about the error, not meant for end-user" +} +``` + +| Error | errorCode | Reason | +|---------------------|-----------|------------------------------------------------------------------------------| +| Not connected | 300 | There is no communication channel with the device | +| Communication error | 301 | Error in communication with device to start scan or receive information back | + +#### Exit provisioning (App -> Console) + +```json +{ + "provider": "espprovision", + "action": "EXIT_PROVISIONING" +} +``` +Asks the device to exit provisioning mode. + +#### Exit provisioning response (Console -> App) + +Once the device is out of provisioning mode, the following information is sent by the provider + +```json +{ + "provider": "espprovision", + "action": "EXIT_PROVISIONING", + "exit": true | false + "errorCode": , + "errorMessage": "An optional detail message about the error, not meant for end-user" +} +``` + +| Error | errorCode | Reason | +|---------------------|-----------|------------------------------------------------------------------------------| +| Not connected | 300 | There is no communication channel with the device | +| Communication error | 301 | Error in communication with device to start scan or receive information back | +| Generic error | 10000 | A non specific error has occurred | diff --git a/docs/architecture/esp32-device.md b/docs/architecture/esp32-device.md new file mode 100644 index 00000000..fbd0585b --- /dev/null +++ b/docs/architecture/esp32-device.md @@ -0,0 +1,107 @@ +--- +sidebar_position: 5 +--- + +# ESP32 devices + +Many IoT devices are or can be based on an ESP32 microcontroller. +A typical setup for integrating such a device in the OpenRemote ecosystem includes 3 components: +- a firmware running on the ESP32 MCU in the device +- a mobile app to configure the device and connect to the backend +- the OpenRemote backend + +```mermaid +graph LR + %% Styling Definitions + classDef greenStyle fill:#d4edda,stroke:#28a745,stroke-width:2px,color:#000; + classDef innerGreenStyle fill:#e8f5e9,stroke:#28a745,stroke-width:1px,color:#000; + classDef orangeStyle fill:#ffe0b2,stroke:#f57c00,stroke-width:2px,color:#000; + classDef redStyle fill:#ffcdd2,stroke:#c62828,stroke-width:2px,color:#000; + classDef purpleStyle fill:#e1bee7,stroke:#7b1fa2,stroke-width:2px,color:#000; + + App[App]:::orangeStyle + + OR[Backend]::::greenStyle + + ESP[Device]::::purpleStyle + + %% Connections + App <--> OR + App <--> ESP + ESP <--> OR +``` + +We offer software elements to support the development of all 3 components. + +A device is represented in the OpenRemote backend by an asset of a specific type. +The device communicates with OpenRemote over MQTTS, authenticated with a dedicated service user. + +In this typical use case, the device uses Wifi for its internet connectivity. + +To integrate a new device into the system, it needs to be provisioned. +This can either be done automatically, see [User Guide Auto provisioning](/user-guide/gateways-and-devices/auto-provisioning.md) +or through a manual process performed by the end-user. + +For the later case, the workflow is as follows + +```mermaid +sequenceDiagram + autonumber + + Note over User,Backend: User login + + User->>App: Login + App->>Backend: Authenticate user + Backend-->>App: Authenticated + + Note over User,Backend: Device WiFi provisioning + + User->>Device: Put in discovery mode + App->>App: Start device scan + Device-->>App: Device name + User->>App: select device + App->>App: Stop device scan + App->>Device: Connect + Device->>App: Get PoP + App-->>Device: PoP + App->>Device: Start WiFi scan + Device-->>App: WiFi information + User->>App: Select WiFi (or join other) + User->>App: Enter WiFi password + App->>Device: WiFi configuration + Device->>App: WiFi connection status + + Note over User,Backend: Device provisioning + + App->>Device: Get Device Id (DeviceInfo Request) + Device-->>App: Device Id (DeviceInfo Response) + + App->>App: Create password + App->>Backend: Provision device + Note right of App: App provides Device Id and password + + Backend->>Backend: Create Device Asset + Note right of Backend: Asset is linked to user account + + Backend->>Backend: Create Service Account + Note right of Backend: Service Account is restricted
and only has rights on the Device Asset.
username is Device Id + + Backend-->>App: Confirmed + Note right of Backend: Returns Asset Id + + App->>Device: Send configuration (OpenRemoteConfig Request) + Device->>Backend: connect + Note right of Device: Over MQTTS using username/password
(Service Account) + + Device-->>App: Status (OpenRemoteConfig Response) + App->>Device: Get connection status (BackendConnectionStatus Request) + Device-->>App: connection status (BackendConnectionStatus Response) + Note right of Device: Repeat to poll for connected status +``` + +Communication between the Mobile Application and the Device is based on Espressif [Unified Provisioning](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/provisioning/provisioning.html). +This mechanism is used to discover the device, then establish a secure communication channel over BLE. +Communication on this channel uses Protocol Buffer payloads, in addition to the messages defined by Espressif, OpenRemote uses messages defined in the following ProtoBuf spec: [ORConfigChannelProtocol](https://github.com/openremote/console-ios-lib/blob/7212bc905c7df34c2f3d62f801f0e4df7529a2f0/ORLib/ORConfigChannelProtocol.proto) +OpenRemote includes the [ESP Provision provider](apps-and-consoles.md#esp-provision-provider-espprovision) to support the implementation of the mobile application side. + +On the backend, the project must implement a single `/rest/device` endpoint, see [Provision Device API](../provisioning-api/provisions-a-new-device-for-the-user.api.mdx) for more details. diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 916020e9..72647704 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -77,6 +77,16 @@ const config: Config = { hideSendButton: false, showSchemas: true, } satisfies OpenApiPlugin.Options, + provisioningapi: { + specPath: "api/provisioningapi.yaml", + outputDir: "docs/provisioning-api", + sidebarOptions: { + groupPathsBy: "tag", + categoryLinkSource: "tag", + }, + hideSendButton: false, + showSchemas: true, + } satisfies OpenApiPlugin.Options, } satisfies Plugin.PluginOptions, }, ], From 769470e7f974e1138d629c1d11990d19faf9646a Mon Sep 17 00:00:00 2001 From: Eric Bariaux <375613+ebariaux@users.noreply.github.com> Date: Tue, 6 Jan 2026 18:10:43 +0100 Subject: [PATCH 2/6] Fixed some typos --- docs/architecture/apps-and-consoles.md | 10 +++++----- docs/architecture/esp32-device.md | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/architecture/apps-and-consoles.md b/docs/architecture/apps-and-consoles.md index d1a92586..8823ae8e 100644 --- a/docs/architecture/apps-and-consoles.md +++ b/docs/architecture/apps-and-consoles.md @@ -385,12 +385,12 @@ Periodically during the scan, if the provider has found BLE devices, it will sen { "id": "", "name": "", - "signalStrengh": "" + "signalStrength": "" }, ... ] } ``` -signalStrengh is optional, it will not be present in a first version. +signalStrength is optional, it will not be present in a first version. #### Stop BLE scan (App -> Console) @@ -507,7 +507,7 @@ Periodically during the scan, if the provider has found SSIDs, it will send the "networks": [ { "ssid": "", - "signalStrengh": -12 + "signalStrength": -12 }, ... ] } @@ -579,7 +579,7 @@ Once device has reported its status, the following information is sent by the pr ```json { "provider": "espprovision", - "action": "PROVISION_DEVICE" + "action": "PROVISION_DEVICE", "userToken": "" } ``` @@ -635,7 +635,7 @@ Once the device is out of provisioning mode, the following information is sent b { "provider": "espprovision", "action": "EXIT_PROVISIONING", - "exit": true | false + "exit": true | false, "errorCode": , "errorMessage": "An optional detail message about the error, not meant for end-user" } diff --git a/docs/architecture/esp32-device.md b/docs/architecture/esp32-device.md index fbd0585b..7bfcce7a 100644 --- a/docs/architecture/esp32-device.md +++ b/docs/architecture/esp32-device.md @@ -21,9 +21,9 @@ graph LR App[App]:::orangeStyle - OR[Backend]::::greenStyle + OR[Backend]:::greenStyle - ESP[Device]::::purpleStyle + ESP[Device]:::purpleStyle %% Connections App <--> OR @@ -42,7 +42,7 @@ To integrate a new device into the system, it needs to be provisioned. This can either be done automatically, see [User Guide Auto provisioning](/user-guide/gateways-and-devices/auto-provisioning.md) or through a manual process performed by the end-user. -For the later case, the workflow is as follows +For the latter case, the workflow is as follows ```mermaid sequenceDiagram From 1754a1ca07791195d8f47fadaa3f9886021ffb32 Mon Sep 17 00:00:00 2001 From: Eric Bariaux <375613+ebariaux@users.noreply.github.com> Date: Tue, 6 Jan 2026 18:11:14 +0100 Subject: [PATCH 3/6] Generated API docs should also be committed --- .gitignore | 1 - .../provisioning-rest-api.info.mdx | 98 +++++++++++++++++++ ...ovisions-a-new-device-for-the-user.api.mdx | 71 ++++++++++++++ docs/provisioning-api/sidebar.ts | 24 +++++ 4 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 docs/provisioning-api/provisioning-rest-api.info.mdx create mode 100644 docs/provisioning-api/provisions-a-new-device-for-the-user.api.mdx create mode 100644 docs/provisioning-api/sidebar.ts diff --git a/.gitignore b/.gitignore index a697acd3..1a6e7fc8 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,3 @@ npm-debug.log* yarn-debug.log* yarn-error.log* -docs/provisioning-api diff --git a/docs/provisioning-api/provisioning-rest-api.info.mdx b/docs/provisioning-api/provisioning-rest-api.info.mdx new file mode 100644 index 00000000..04ceea10 --- /dev/null +++ b/docs/provisioning-api/provisioning-rest-api.info.mdx @@ -0,0 +1,98 @@ +--- +id: provisioning-rest-api +title: "Provisioning REST API" +description: "Provisioning REST API" +sidebar_label: Introduction +sidebar_position: 0 +hide_title: true +custom_edit_url: null +--- + +import ApiLogo from "@theme/ApiLogo"; +import Heading from "@theme/Heading"; +import SchemaTabs from "@theme/SchemaTabs"; +import TabItem from "@theme/TabItem"; +import Export from "@theme/ApiExplorer/Export"; + + + + + + + + + +Provisioning REST API + +
+ + + + + + + +
+ + + + + + + + +
+ Security Scheme Type: + + http +
+ HTTP Authorization Scheme: + + bearer +
+
+
+
+
+

+ Contact +

+ [info@openremote.io](mailto:info@openremote.io) + +
+

+ License +

+ AGPL 3.0 + +
+ \ No newline at end of file diff --git a/docs/provisioning-api/provisions-a-new-device-for-the-user.api.mdx b/docs/provisioning-api/provisions-a-new-device-for-the-user.api.mdx new file mode 100644 index 00000000..e329cf8e --- /dev/null +++ b/docs/provisioning-api/provisions-a-new-device-for-the-user.api.mdx @@ -0,0 +1,71 @@ +--- +id: provisions-a-new-device-for-the-user +title: "Provisions a new device for the user" +description: "Provisions a new device, creating both an Asset to represent it and a Service Account for the device to connect over MQTT. The asset type is selected based on the provided modelName. If none matches, an error is reported." +sidebar_label: "Provisions a new device for the user" +hide_title: true +hide_table_of_contents: true +api: eJzdVl1v2zYU/SvEfWoBVXbifmx6mpsWQ7BkcRMHWBHkgaauLbYUyV5SdgzD/324lOzIcbsMQ5+mJ4W5XzrnnkNvoMSgSPuonYUCJuSWOmhng5DC4kqUuNQKM6EIZdR2IWYuVkJaMQ4Bo4hOEHrCgDYKHYW0pZDiBomzxFgp19go5o5ErLArxknKWYsqCrdEEpefptNcTCsUsi269ih0EAENqoilmMmApXA2FfE8YomlqF2J5k9ZYy7O58I6i6KWUVUYMh4QiRxxGULvKGKZQwaE3xoM8b0r11BsQDkb0UZ+ld4brSTjMPgSGIwNBFVhLfmNR4IC3OwLqtjV0YQlFHfQftV5CRl4GcLKUQn3GXhyHilqDFxgH/RYLETSdgHZEwrOPwg376CCDPBB1t5w/Mnp6PWbt+9++XX8/gy2vWbPlpx0kYmI0JEjW3IOWoSRolHk4ntwn69+yaGPMzO9frdGB9UdzWSMSGvYpodhDN7Z0EJ0Ohy2SPWLX/0B2b+n6afwmZYw0Zneznjzkf/skLsNSLvDI553yc+iduXRXmPtInZSOv9wANbb+Nesvlx+uihP8d0tfX7zcLHU10zNwVSPfWbOGZT2eJ9syThgEHqeBNSR0IltJUMrbtbZWsRKB6GkMeJFpAZfCkdCGkJZrgU+6MBhL+bSBHzZH5djt99F6D8MuNvQJiD9zPl2TwavhyfHqzZWCkMQ0X1Fy75R6xDY8dhF7FIaXUJKHR2nTkhbpb00nGddFNIYt8IyaQFp7qhuJ+dVSTsJPEaNsXIlFOBdiMk+YgUFDPbiZySQAhR3G2jIQAFVjD4Ug0GJtcudR0tph3LtBtLrwYZQmno7gAyWkrScmXYt03E791w2JkIBtQwRiaV4z41UQzquU6cZSkIaNzzM3X3/3zcsoLZiP2hPMU/HY6cwpjwFpW9lDV4/uu/HHTN9azy0uL7D7ZzpwJj6hpKBtnOXRtExCWh/lTGH1x9vpmI8OT+2xh9EsZNIlZwEa6kZem7w2wHk3NZohTakD7HtVOPfJxdilA8he8LZarXKF7bJHS0GXVoYyIU3r0b5MEebV7E2XJM5b8c7yYfJ6l2ItbS9Jj+4qPdXLWvn6cf2/PF/f9F3CxnxIQ68kdoyjImOTSez3cXNHl6x/oo72Gx4glsy2y0ff2t4t4q7+0c1JUVkUKEskZJavuIaCjhrkX015b4cbhruf3QLbbNdBtuNj/8Ye9+ziMnVzRQymHW/XBgTKIDkim8vuYICIAOXmG4Vz2cbMNIuGrng2LYmP38DY6V0Qg== +sidebar_class_name: "post api-method" +info_path: docs/provisioning-api/provisioning-rest-api +custom_edit_url: null +--- + +import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; +import ParamsDetails from "@theme/ParamsDetails"; +import RequestSchema from "@theme/RequestSchema"; +import StatusCodes from "@theme/StatusCodes"; +import OperationTabs from "@theme/OperationTabs"; +import TabItem from "@theme/TabItem"; +import Heading from "@theme/Heading"; + + + + + + + + + + +Provisions a new device, creating both an Asset to represent it and a Service Account for the device to connect over MQTT. The asset type is selected based on the provided modelName. If none matches, an error is reported. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/provisioning-api/sidebar.ts b/docs/provisioning-api/sidebar.ts new file mode 100644 index 00000000..8867b2d2 --- /dev/null +++ b/docs/provisioning-api/sidebar.ts @@ -0,0 +1,24 @@ +import type { SidebarsConfig } from "@docusaurus/plugin-content-docs"; + +const sidebar: SidebarsConfig = { + apisidebar: [ + { + type: "doc", + id: "provisioning-api/provisioning-rest-api", + }, + { + type: "category", + label: "UNTAGGED", + items: [ + { + type: "doc", + id: "provisioning-api/provisions-a-new-device-for-the-user", + label: "Provisions a new device for the user", + className: "api-method post", + }, + ], + }, + ], +}; + +export default sidebar.apisidebar; From 84c0f653e46250b60a3cd43716a65aa8544996ab Mon Sep 17 00:00:00 2001 From: Eric Bariaux <375613+ebariaux@users.noreply.github.com> Date: Tue, 6 Jan 2026 18:29:54 +0100 Subject: [PATCH 4/6] Fix issues with OpenAPI spec --- api/provisioningapi.yaml | 10 ++- docs/architecture/esp32-device.md | 2 +- .../provisioning-api/provision-device.api.mdx | 71 +++++++++++++++++++ ...ovisions-a-new-device-for-the-user.api.mdx | 71 ------------------- docs/provisioning-api/sidebar.ts | 2 +- 5 files changed, 77 insertions(+), 79 deletions(-) create mode 100644 docs/provisioning-api/provision-device.api.mdx delete mode 100644 docs/provisioning-api/provisions-a-new-device-for-the-user.api.mdx diff --git a/api/provisioningapi.yaml b/api/provisioningapi.yaml index 6b30a5b9..2bae8d8c 100644 --- a/api/provisioningapi.yaml +++ b/api/provisioningapi.yaml @@ -9,7 +9,7 @@ info: url: https://www.gnu.org/licenses/agpl-3.0.en.html version: "1.0" servers: - - url: "https://demo.openremote.io/api/{realm}/" + - url: "https://demo.openremote.io/api/{realm}" variables: realm: default: master @@ -18,17 +18,14 @@ security: paths: /device: post: + operationId: provisionDevice summary: Provisions a new device for the user description: Provisions a new device, creating both an Asset to represent it and a Service Account for the device to connect over MQTT. The asset type is selected based on the provided modelName. If none matches, an error is reported. requestBody: $ref: "#/components/requestBodies/DeviceProvisioning" responses: '200': - description: OK - content: - application/json: - schema: - $ref: "#/components/responses/DeviceProvisioningResponse" + $ref: "#/components/responses/DeviceProvisioningResponse" '401': $ref: '#/components/responses/UnauthorizedError' '403': @@ -66,6 +63,7 @@ components: ForbiddenError: description: Principal is not allowed to perform this operation DeviceProvisioningResponse: + description: Information about a successfully provisioned device content: application/json: schema: diff --git a/docs/architecture/esp32-device.md b/docs/architecture/esp32-device.md index 7bfcce7a..28107b8b 100644 --- a/docs/architecture/esp32-device.md +++ b/docs/architecture/esp32-device.md @@ -104,4 +104,4 @@ This mechanism is used to discover the device, then establish a secure communica Communication on this channel uses Protocol Buffer payloads, in addition to the messages defined by Espressif, OpenRemote uses messages defined in the following ProtoBuf spec: [ORConfigChannelProtocol](https://github.com/openremote/console-ios-lib/blob/7212bc905c7df34c2f3d62f801f0e4df7529a2f0/ORLib/ORConfigChannelProtocol.proto) OpenRemote includes the [ESP Provision provider](apps-and-consoles.md#esp-provision-provider-espprovision) to support the implementation of the mobile application side. -On the backend, the project must implement a single `/rest/device` endpoint, see [Provision Device API](../provisioning-api/provisions-a-new-device-for-the-user.api.mdx) for more details. +On the backend, the project must implement a single `/rest/device` endpoint, see [Provision Device API](../provisioning-api/provision-device.api.mdx) for more details. diff --git a/docs/provisioning-api/provision-device.api.mdx b/docs/provisioning-api/provision-device.api.mdx new file mode 100644 index 00000000..74f21964 --- /dev/null +++ b/docs/provisioning-api/provision-device.api.mdx @@ -0,0 +1,71 @@ +--- +id: provision-device +title: "Provisions a new device for the user" +description: "Provisions a new device, creating both an Asset to represent it and a Service Account for the device to connect over MQTT. The asset type is selected based on the provided modelName. If none matches, an error is reported." +sidebar_label: "Provisions a new device for the user" +hide_title: true +hide_table_of_contents: true +api: eJzdVk1v20YQ/SuLOSUAQ8lWPlqeqthBIcBuFFsGWgg+jMiRuMlyl5ldShYE/fdiltSX1dRAkVN1oqjZmdn35r3RBlxNjEE7Oyogg5rdUnvt7DUtdU6QQEE+Z11LBGQw3v3uFSpLK1XEuETlTBi0XaiZC6VCq4beU1DBKaaayZMNSgeFtlCo7onllBrmuWtsUHPHKpTUJZNDubOW8qDckljdfplMUjUpSWGbdF2T0l55MpQHKtQMPRXK2ZgkXqGgQlWuIPMHVpSq0VxZZ0lVGPKSfCINErNjScNUOw5UpJAA0/eGfPjoijVkG8idDWSDPGJdG51HpHpfvYCxAZ+XVKE8SUuQgZt9pTx0eTRTAdkU2luNCkigRu9Xjgt4TATqmjho8pJgH3RI5gNruzijYHSt3LyDChKgJ6xqI/EXl4O3795/+OXX4ccr2B4VezHluIuMRPiOHGzJOSnhBzkPgiTfg/ty9lsJPfQs9O7H7CS74xmGQLyGbfwIjL521rcQXfb7LVInaNi54yrSonDmmqBQ+SbPyft5Y8z6UIqKA2g/hdc4jJHW+HQlCiD52iH44Il3L8/43h1+Eb3PNdk7qlygTlKj6xPQ3oc/Z9Xt8stNcUkfHvivd083S30nFJ10dagzc84Q2vO5soXgQF7peRRSR0YnuhX6VuSit7UKpfYqR2PUq8ANvVaOFRomLNaKnrSXsFdzNJ5eH7crsdt/ROg/NLib1MYT/8z+uuF72784n7dhHC0V3DeyYh6V9l5sT6zELtHoAuLRwfnRMWub6xqNnLMuKDTGraiIgiCWOW7b3lsySBsVhdJFb3Y+RA8JJWTQ2w+zwEDsIZtuoGEDGZQh1D7r9QqqXOpqshwHKNWuh7XubZjQVFtIYImscWbakYxv27bn2JgAGVToA7HI8VHq5A3rsI6FZoRMPGykl+nj8c/3Ip4243HQnl5pTrqOYUJ3DIpXFf3dHRz4046VY3s8tbljl9u504k5HZtKAtrOXWxFhyie/ToTCu8+3U/UcDz68dJ7FiUugnl0EapQC/JS4LcTxKWs0TlZHy9i266Gv49v1CDtQ/KMstVqlS5skzpe9LpjvoeL2rwZpP2UbFqGykhOobxt7yLtR7t3PlRoj4r8YFnv163o5vllj3be/37ZdwMZ6Cn0aoPaCoyRjk2nst3yFv8uRX7ZFDYb6eCBzXYrr783MlvZ9PGgpqiIBErCgjiq5RutIYOrFtk3E6kr4aaR+mcbaJvsTojb1OFfYx+PHGL8+X4CCcy6fy+CCWTAuJLNhSvIABJwkelW8fJuAwbtosGFxLY55fM3JViCvA== +sidebar_class_name: "post api-method" +info_path: docs/provisioning-api/provisioning-rest-api +custom_edit_url: null +--- + +import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; +import ParamsDetails from "@theme/ParamsDetails"; +import RequestSchema from "@theme/RequestSchema"; +import StatusCodes from "@theme/StatusCodes"; +import OperationTabs from "@theme/OperationTabs"; +import TabItem from "@theme/TabItem"; +import Heading from "@theme/Heading"; + + + + + + + + + + +Provisions a new device, creating both an Asset to represent it and a Service Account for the device to connect over MQTT. The asset type is selected based on the provided modelName. If none matches, an error is reported. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/provisioning-api/provisions-a-new-device-for-the-user.api.mdx b/docs/provisioning-api/provisions-a-new-device-for-the-user.api.mdx deleted file mode 100644 index e329cf8e..00000000 --- a/docs/provisioning-api/provisions-a-new-device-for-the-user.api.mdx +++ /dev/null @@ -1,71 +0,0 @@ ---- -id: provisions-a-new-device-for-the-user -title: "Provisions a new device for the user" -description: "Provisions a new device, creating both an Asset to represent it and a Service Account for the device to connect over MQTT. The asset type is selected based on the provided modelName. If none matches, an error is reported." -sidebar_label: "Provisions a new device for the user" -hide_title: true -hide_table_of_contents: true -api: eJzdVl1v2zYU/SvEfWoBVXbifmx6mpsWQ7BkcRMHWBHkgaauLbYUyV5SdgzD/324lOzIcbsMQ5+mJ4W5XzrnnkNvoMSgSPuonYUCJuSWOmhng5DC4kqUuNQKM6EIZdR2IWYuVkJaMQ4Bo4hOEHrCgDYKHYW0pZDiBomzxFgp19go5o5ErLArxknKWYsqCrdEEpefptNcTCsUsi269ih0EAENqoilmMmApXA2FfE8YomlqF2J5k9ZYy7O58I6i6KWUVUYMh4QiRxxGULvKGKZQwaE3xoM8b0r11BsQDkb0UZ+ld4brSTjMPgSGIwNBFVhLfmNR4IC3OwLqtjV0YQlFHfQftV5CRl4GcLKUQn3GXhyHilqDFxgH/RYLETSdgHZEwrOPwg376CCDPBB1t5w/Mnp6PWbt+9++XX8/gy2vWbPlpx0kYmI0JEjW3IOWoSRolHk4ntwn69+yaGPMzO9frdGB9UdzWSMSGvYpodhDN7Z0EJ0Ohy2SPWLX/0B2b+n6afwmZYw0Zneznjzkf/skLsNSLvDI553yc+iduXRXmPtInZSOv9wANbb+Nesvlx+uihP8d0tfX7zcLHU10zNwVSPfWbOGZT2eJ9syThgEHqeBNSR0IltJUMrbtbZWsRKB6GkMeJFpAZfCkdCGkJZrgU+6MBhL+bSBHzZH5djt99F6D8MuNvQJiD9zPl2TwavhyfHqzZWCkMQ0X1Fy75R6xDY8dhF7FIaXUJKHR2nTkhbpb00nGddFNIYt8IyaQFp7qhuJ+dVSTsJPEaNsXIlFOBdiMk+YgUFDPbiZySQAhR3G2jIQAFVjD4Ug0GJtcudR0tph3LtBtLrwYZQmno7gAyWkrScmXYt03E791w2JkIBtQwRiaV4z41UQzquU6cZSkIaNzzM3X3/3zcsoLZiP2hPMU/HY6cwpjwFpW9lDV4/uu/HHTN9azy0uL7D7ZzpwJj6hpKBtnOXRtExCWh/lTGH1x9vpmI8OT+2xh9EsZNIlZwEa6kZem7w2wHk3NZohTakD7HtVOPfJxdilA8he8LZarXKF7bJHS0GXVoYyIU3r0b5MEebV7E2XJM5b8c7yYfJ6l2ItbS9Jj+4qPdXLWvn6cf2/PF/f9F3CxnxIQ68kdoyjImOTSez3cXNHl6x/oo72Gx4glsy2y0ff2t4t4q7+0c1JUVkUKEskZJavuIaCjhrkX015b4cbhruf3QLbbNdBtuNj/8Ye9+ziMnVzRQymHW/XBgTKIDkim8vuYICIAOXmG4Vz2cbMNIuGrng2LYmP38DY6V0Qg== -sidebar_class_name: "post api-method" -info_path: docs/provisioning-api/provisioning-rest-api -custom_edit_url: null ---- - -import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; -import ParamsDetails from "@theme/ParamsDetails"; -import RequestSchema from "@theme/RequestSchema"; -import StatusCodes from "@theme/StatusCodes"; -import OperationTabs from "@theme/OperationTabs"; -import TabItem from "@theme/TabItem"; -import Heading from "@theme/Heading"; - - - - - - - - - - -Provisions a new device, creating both an Asset to represent it and a Service Account for the device to connect over MQTT. The asset type is selected based on the provided modelName. If none matches, an error is reported. - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/provisioning-api/sidebar.ts b/docs/provisioning-api/sidebar.ts index 8867b2d2..41b69798 100644 --- a/docs/provisioning-api/sidebar.ts +++ b/docs/provisioning-api/sidebar.ts @@ -12,7 +12,7 @@ const sidebar: SidebarsConfig = { items: [ { type: "doc", - id: "provisioning-api/provisions-a-new-device-for-the-user", + id: "provisioning-api/provision-device", label: "Provisions a new device for the user", className: "api-method post", }, From f0d54f666c2a50731e093e7f48b2c8e11fa79198 Mon Sep 17 00:00:00 2001 From: Eric Bariaux <375613+ebariaux@users.noreply.github.com> Date: Thu, 8 Jan 2026 10:43:03 +0100 Subject: [PATCH 5/6] modelName is required attribute in DeviceProvisioning payload --- api/provisioningapi.yaml | 1 + docs/provisioning-api/provision-device.api.mdx | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/api/provisioningapi.yaml b/api/provisioningapi.yaml index 2bae8d8c..e9ed6cf0 100644 --- a/api/provisioningapi.yaml +++ b/api/provisioningapi.yaml @@ -44,6 +44,7 @@ components: required: - deviceId - password + - modelName properties: deviceId: type: string diff --git a/docs/provisioning-api/provision-device.api.mdx b/docs/provisioning-api/provision-device.api.mdx index 74f21964..a9625961 100644 --- a/docs/provisioning-api/provision-device.api.mdx +++ b/docs/provisioning-api/provision-device.api.mdx @@ -5,7 +5,7 @@ description: "Provisions a new device, creating both an Asset to represent it an sidebar_label: "Provisions a new device for the user" hide_title: true hide_table_of_contents: true -api: eJzdVk1v20YQ/SuLOSUAQ8lWPlqeqthBIcBuFFsGWgg+jMiRuMlyl5ldShYE/fdiltSX1dRAkVN1oqjZmdn35r3RBlxNjEE7Oyogg5rdUnvt7DUtdU6QQEE+Z11LBGQw3v3uFSpLK1XEuETlTBi0XaiZC6VCq4beU1DBKaaayZMNSgeFtlCo7onllBrmuWtsUHPHKpTUJZNDubOW8qDckljdfplMUjUpSWGbdF2T0l55MpQHKtQMPRXK2ZgkXqGgQlWuIPMHVpSq0VxZZ0lVGPKSfCINErNjScNUOw5UpJAA0/eGfPjoijVkG8idDWSDPGJdG51HpHpfvYCxAZ+XVKE8SUuQgZt9pTx0eTRTAdkU2luNCkigRu9Xjgt4TATqmjho8pJgH3RI5gNruzijYHSt3LyDChKgJ6xqI/EXl4O3795/+OXX4ccr2B4VezHluIuMRPiOHGzJOSnhBzkPgiTfg/ty9lsJPfQs9O7H7CS74xmGQLyGbfwIjL521rcQXfb7LVInaNi54yrSonDmmqBQ+SbPyft5Y8z6UIqKA2g/hdc4jJHW+HQlCiD52iH44Il3L8/43h1+Eb3PNdk7qlygTlKj6xPQ3oc/Z9Xt8stNcUkfHvivd083S30nFJ10dagzc84Q2vO5soXgQF7peRRSR0YnuhX6VuSit7UKpfYqR2PUq8ANvVaOFRomLNaKnrSXsFdzNJ5eH7crsdt/ROg/NLib1MYT/8z+uuF72784n7dhHC0V3DeyYh6V9l5sT6zELtHoAuLRwfnRMWub6xqNnLMuKDTGraiIgiCWOW7b3lsySBsVhdJFb3Y+RA8JJWTQ2w+zwEDsIZtuoGEDGZQh1D7r9QqqXOpqshwHKNWuh7XubZjQVFtIYImscWbakYxv27bn2JgAGVToA7HI8VHq5A3rsI6FZoRMPGykl+nj8c/3Ip4243HQnl5pTrqOYUJ3DIpXFf3dHRz4046VY3s8tbljl9u504k5HZtKAtrOXWxFhyie/ToTCu8+3U/UcDz68dJ7FiUugnl0EapQC/JS4LcTxKWs0TlZHy9i266Gv49v1CDtQ/KMstVqlS5skzpe9LpjvoeL2rwZpP2UbFqGykhOobxt7yLtR7t3PlRoj4r8YFnv163o5vllj3be/37ZdwMZ6Cn0aoPaCoyRjk2nst3yFv8uRX7ZFDYb6eCBzXYrr783MlvZ9PGgpqiIBErCgjiq5RutIYOrFtk3E6kr4aaR+mcbaJvsTojb1OFfYx+PHGL8+X4CCcy6fy+CCWTAuJLNhSvIABJwkelW8fJuAwbtosGFxLY55fM3JViCvA== +api: eJzdVk1v20YQ/SuLOSUAQ8lWPlqeqthBIcBuFFsGWgg+jMiRuMlyl5ldShYE/fdiltSX1dRAkVN1oqjZmbfvzbzRBlxNjEE7Oyogg5rdUnvt7DUtdU6QQEE+Z11LBGQw3v3uFSpLK1XEuETlTBi0XaiZC6VCq4beU1DBKaaayZMNSgeFtlCo7onllBrmuWtsUHPHKpTUJZNDubOW8qDckljdfplMUjUpSWGbdF2T0l55MpQHKtQMPRXK2ZgkXqGgQlWuIPMHVpSq0VxZZ0lVGPKSfCIAidmxpGGqHQcqUkiA6XtDPnx0xRqyDeTOBrJBHrGujc4jU72vXsjYgM9LqlCeBBJk4GZfKQ9dHs1UQDaF9lajAhKo0fuVY3nco4PHRGiviYMmL8n2Bw6JfWBtF2dyjK6Vm3e0QQL0hFVtJP7icvD23fsPv/w6/HgF26PCL6Ycd5FRFN8Jha1QJyX8IOdBkOSHq7yY/VZCD5hF6n3LnWR3PMMQiNewjR+h1NfO+paiy36/ZeqEDTt3XEWJFM5cExQq3+Q5eT9vjFkfSlFxIO2naBwbM0ocn65kGki+dgw+eOLdyzO9d4dfZO9zTfaOKheoG6/R9Qlp78Ofs+p2+eWmuKQPD/zXu6ebpb4TiU5QHerMnDOE9ryvbCE8kFd6HoeqE6MbwBX6duBl9tYqlNqrHI1RrwI39Fo5VmiYsFgretJewl7N0Xh6fQxXYrf/yNB/ALjr1MYT/0x8XfO97V+c99swtpYK7htZMZJKey8WKLZil2h0AfHo4PzomLXNdY1GzlkXFBrjVlTEgSCWPm5h7+0ZBEZFoXTRp50P0U9CCRn09s0sNBB7yKYbaNhABmUItc96vYIql7qaLMcGSrXrYa17GyY01RYSWCJrnJm2JePbFvYcGxMggwp9IJZxfJQ6ecM6rGOhGSETDxvBMn08/vlehqfNeBy0l1fACeoYJnLHoHhVmb+7gxt/2qlybI+nNnfscjt3OjGnY1NJQNu5i1B0iMOzX20i4d2n+4kajkc/XoDPosRFMI8uQhVqYV4K/HbCuJQ1Oifr40Vsi2r4+/hGDdI+JM8kW61W6cI2qeNFrzvme7iozZtB2k/JpmWojOQUyVt4F2k/2r3zoUJ7VOQHi3u/emVunl/2aP/97xd/15CBnkKvNqit0Bjl2HRTtlvk4t+ljF82hc1GEDyw2W7l9fdGeiubPh6mKU5EAiVhQRyn5RutIYOrltk3E6kr4aaR+mcbaJvsTojb1OFfYx+PHGL8+X4CCcy6fzLCCWTAuJLNhSvIABJwUel24uXdBgzaRYMLiW1zyudvH2aGvg== sidebar_class_name: "post api-method" info_path: docs/provisioning-api/provisioning-rest-api custom_edit_url: null @@ -54,7 +54,7 @@ Provisions a new device, creating both an Asset to represent it and a Service Ac From 730a19e5a04a97bc3331e8fd3f98ffbda96d2557 Mon Sep 17 00:00:00 2001 From: Eric Bariaux <375613+ebariaux@users.noreply.github.com> Date: Thu, 8 Jan 2026 10:43:30 +0100 Subject: [PATCH 6/6] Standardize writting of Wi-Fi term --- docs/architecture/apps-and-consoles.md | 54 +++++++++++++------------- docs/architecture/esp32-device.md | 16 ++++---- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/docs/architecture/apps-and-consoles.md b/docs/architecture/apps-and-consoles.md index 8823ae8e..baccea84 100644 --- a/docs/architecture/apps-and-consoles.md +++ b/docs/architecture/apps-and-consoles.md @@ -331,7 +331,7 @@ Start the camera and scan a QR code. ### ESP Provision (provider: "espprovision") Allows provisioning an ESP32 device in the system via a 3-step workflow: 1. discover the device and establish a secure communication to the device over BLE -2. discover Wifi networks and configure the device to connect to it +2. discover Wi-Fi networks and configure the device to connect to it 3. provision the device in the backend and configure the device to connect to the backend This is based on Espressif [Unified Provisioning](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/provisioning/provisioning.html) @@ -467,9 +467,9 @@ Possible error codes } ``` -#### Start Wifi scan (App -> Console) +#### Start Wi-Fi scan (App -> Console) -Asks the connected device to start a WiFi scan without any timeout. +Asks the connected device to start a Wi-Fi scan without any timeout. ```json { @@ -478,7 +478,7 @@ Asks the connected device to start a WiFi scan without any timeout. } ``` -#### Wifi scan error response (Console -> App) +#### Wi-Fi scan error response (Console -> App) If there’s an error starting or during the scan, the following message is sent ```json @@ -490,13 +490,13 @@ If there’s an error starting or during the scan, the following message is sent } ``` -| Error | errorCode | Reason | -|---------------------|-----------|--------------------------------------------------------------------------------------------| -| Not connected | 300 | There is no communication channel with the device | -| Communication error | 301 | Error in communication with device to start scan or receive information back | -| Timeout | 600 | A timeout (120s) occurred during wifi scan (even if some networks were already found and reported) | +| Error | errorCode | Reason | +|---------------------|-----------|-----------------------------------------------------------------------------------------------------| +| Not connected | 300 | There is no communication channel with the device | +| Communication error | 301 | Error in communication with device to start scan or receive information back | +| Timeout | 600 | A timeout (120s) occurred during Wi-Fi scan (even if some networks were already found and reported) | -#### Wifi scan response (Console -> App) +#### Wi-Fi scan response (Console -> App) Periodically during the scan, if the provider has found SSIDs, it will send the complete list to the web app using the below structure @@ -513,9 +513,9 @@ Periodically during the scan, if the provider has found SSIDs, it will send the } ``` -#### Stop Wifi scan (App -> Console) +#### Stop Wi-Fi scan (App -> Console) -Stops on-going WiFi scans, calling this if none is underway is not an error. +Stops on-going Wi-Fi scans, calling this if none is underway is not an error. ```json { @@ -524,7 +524,7 @@ Stops on-going WiFi scans, calling this if none is underway is not an error. } ``` -#### Stop Wifi scan response (Console -> App) +#### Stop Wi-Fi scan response (Console -> App) Always sends back a confirmation message, even if no scan was underway. ```json @@ -533,15 +533,15 @@ Always sends back a confirmation message, even if no scan was underway. "action": "STOP_WIFI_SCAN" } ``` -Implementation note: there is no command to stop the WiFi scan on the device, but it only does it for a limited amount of time. +Implementation note: there is no command to stop the Wi-Fi scan on the device, but it only does it for a limited amount of time. The provider is the one implementing a loop to scan “indefinitely”. When the STOP_WIFI_SCAN command is sent, the provider stops this loop. -#### Send Wifi configuration (App -> Console) +#### Send Wi-Fi configuration (App -> Console) -Sends SSID and password to the device for it to configure its Wifi network. +Sends SSID and password to the device for it to configure its Wi-Fi network. -This also stops any WiFi scan that was in progress. +This also stops any Wi-Fi scan that was in progress. ```json { @@ -552,7 +552,7 @@ This also stops any WiFi scan that was in progress. } ``` -#### Wifi configuration response (Console -> App) +#### Wi-Fi configuration response (Console -> App) Once device has reported its status, the following information is sent by the provider @@ -565,15 +565,15 @@ Once device has reported its status, the following information is sent by the pr "errorMessage": "An optional detail message about the error, not meant for end-user" } ``` -| Error | errorCode | Reason | -|----------------------------|-----------|--------------------------------------------------------------------------| -| Not connected | 300 | There is no communication channel with the device | -| Communication error | 301 | Error in communication with device to start scan or receive information back | -| WiFi configuration error | 500 | Error in applying the provided Wifi configuration | -| Wifi communication error | 501 | Could not determine the status of the Wifi network | -| Wifi authentication error | 502 | Wrong Wifi credentials | -| Wifi network not found | 503 | Could not find given Wifi network | -| Generic error | 10000 | A non specific error has occurred | +| Error | errorCode | Reason | +|---------------------------|-----------|--------------------------------------------------------------------------| +| Not connected | 300 | There is no communication channel with the device | +| Communication error | 301 | Error in communication with device to start scan or receive information back | +| Wi-Fi configuration error | 500 | Error in applying the provided Wi-Fi configuration | +| Wi-Fi communication error | 501 | Could not determine the status of the Wi-Fi network | +| Wi-Fi authentication error | 502 | Wrong Wi-Fi credentials | +| Wi-Fi network not found | 503 | Could not find given Wi-Fi network | +| Generic error | 10000 | A non specific error has occurred | #### Provision device (App -> Console) ```json diff --git a/docs/architecture/esp32-device.md b/docs/architecture/esp32-device.md index 28107b8b..41eccdc2 100644 --- a/docs/architecture/esp32-device.md +++ b/docs/architecture/esp32-device.md @@ -36,7 +36,7 @@ We offer software elements to support the development of all 3 components. A device is represented in the OpenRemote backend by an asset of a specific type. The device communicates with OpenRemote over MQTTS, authenticated with a dedicated service user. -In this typical use case, the device uses Wifi for its internet connectivity. +In this typical use case, the device uses Wi-Fi for its internet connectivity. To integrate a new device into the system, it needs to be provisioned. This can either be done automatically, see [User Guide Auto provisioning](/user-guide/gateways-and-devices/auto-provisioning.md) @@ -54,7 +54,7 @@ sequenceDiagram App->>Backend: Authenticate user Backend-->>App: Authenticated - Note over User,Backend: Device WiFi provisioning + Note over User,Backend: Device Wi-Fi provisioning User->>Device: Put in discovery mode App->>App: Start device scan @@ -64,12 +64,12 @@ sequenceDiagram App->>Device: Connect Device->>App: Get PoP App-->>Device: PoP - App->>Device: Start WiFi scan - Device-->>App: WiFi information - User->>App: Select WiFi (or join other) - User->>App: Enter WiFi password - App->>Device: WiFi configuration - Device->>App: WiFi connection status + App->>Device: Start Wi-Fi scan + Device-->>App: Wi-Fi information + User->>App: Select Wi-Fi (or join other) + User->>App: Enter Wi-Fi password + App->>Device: Wi-Fi configuration + Device->>App: Wi-Fi connection status Note over User,Backend: Device provisioning