diff --git a/ce/docs/DeviceApiControllerApi.md b/ce/docs/DeviceApiControllerApi.md deleted file mode 100644 index ad70f8db..00000000 --- a/ce/docs/DeviceApiControllerApi.md +++ /dev/null @@ -1,300 +0,0 @@ -# DeviceApiControllerApi - -`ThingsboardClient` methods: - -``` -String getDeviceAttributes(@Nonnull String deviceToken, @Nonnull String clientKeys, @Nonnull String sharedKeys) // Get attributes (getDeviceAttributes) -String getFirmware(@Nonnull String deviceToken, @Nonnull String title, @Nonnull String version, @Nullable Integer size, @Nullable Integer chunk) // Get Device Firmware (getFirmware) -String getSoftware(@Nonnull String deviceToken, @Nonnull String title, @Nonnull String version, @Nullable Integer size, @Nullable Integer chunk) // Get Device Software (getSoftware) -String postDeviceAttributes(@Nonnull String deviceToken, @Nonnull String body) // Post attributes (postDeviceAttributes) -String postRpcRequest(@Nonnull String deviceToken, @Nonnull String body) // Send the RPC command (postRpcRequest) -String postTelemetry(@Nonnull String deviceToken, @Nonnull String body) // Post time series data (postTelemetry) -String provisionDevice(@Nonnull String body) // Provision new device (provisionDevice) -String replyToCommand(@Nonnull String deviceToken, @Nonnull String requestId, @Nonnull String body) // Reply to RPC commands (replyToCommand) -String saveClaimingInfo(@Nonnull String deviceToken, @Nullable String body) // Save claiming information (saveClaimingInfo) -String subscribeToAttributes(@Nonnull String deviceToken, @Nullable Long timeout) // Subscribe to attribute updates (subscribeToAttributes) (Deprecated) -String subscribeToCommands(@Nonnull String deviceToken, @Nullable Long timeout) // Subscribe to RPC commands (subscribeToCommands) (Deprecated) -``` - - -## getDeviceAttributes - -``` -String getDeviceAttributes(@Nonnull String deviceToken, @Nonnull String clientKeys, @Nonnull String sharedKeys) -``` - -**GET** `/api/v1/{deviceToken}/attributes` - -Get attributes (getDeviceAttributes) - -Returns all attributes that belong to device. Use optional 'clientKeys' and/or 'sharedKeys' parameter to return specific attributes. Example of the result: ```json { \"stringKey\":\"value1\", \"booleanKey\":true, \"doubleKey\":42.0, \"longKey\":73, \"jsonKey\": { \"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"} } } ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - - -### Parameters - -| Name | Type | Description | Notes | -|------------- | ------------- | ------------- | -------------| -| **deviceToken** | **String** | Your device access token. | | -| **clientKeys** | **String** | Comma separated key names for attribute with client scope | | -| **sharedKeys** | **String** | Comma separated key names for attribute with shared scope | | - -### Return type - -**String** - - -## getFirmware - -``` -String getFirmware(@Nonnull String deviceToken, @Nonnull String title, @Nonnull String version, @Nullable Integer size, @Nullable Integer chunk) -``` - -**GET** `/api/v1/{deviceToken}/firmware` - -Get Device Firmware (getFirmware) - -Downloads the current firmware package.When the platform initiates firmware update, it informs the device by updating the 'fw_title', 'fw_version', 'fw_checksum' and 'fw_checksum_algorithm' shared attributes.The 'fw_title' and 'fw_version' parameters must be supplied in this request to double-check that the firmware that device is downloading matches the firmware it expects to download. This is important, since the administrator may change the firmware assignment while device is downloading the firmware. Optional 'chunk' and 'size' parameters may be used to download the firmware in chunks. For example, device may request first 16 KB of firmware using 'chunk'=0 and 'size'=16384. Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - - -### Parameters - -| Name | Type | Description | Notes | -|------------- | ------------- | ------------- | -------------| -| **deviceToken** | **String** | Your device access token. | | -| **title** | **String** | Title of the firmware, corresponds to the value of 'fw_title' attribute. | | -| **version** | **String** | Version of the firmware, corresponds to the value of 'fw_version' attribute. | | -| **size** | **Integer** | Size of the chunk. Optional. Omit to download the entire file without chunks. | [optional] [default to 0] | -| **chunk** | **Integer** | Index of the chunk. Optional. Omit to download the entire file without chunks. | [optional] [default to 0] | - -### Return type - -**String** - - -## getSoftware - -``` -String getSoftware(@Nonnull String deviceToken, @Nonnull String title, @Nonnull String version, @Nullable Integer size, @Nullable Integer chunk) -``` - -**GET** `/api/v1/{deviceToken}/software` - -Get Device Software (getSoftware) - -Downloads the current software package.When the platform initiates software update, it informs the device by updating the 'sw_title', 'sw_version', 'sw_checksum' and 'sw_checksum_algorithm' shared attributes.The 'sw_title' and 'sw_version' parameters must be supplied in this request to double-check that the software that device is downloading matches the software it expects to download. This is important, since the administrator may change the software assignment while device is downloading the software. Optional 'chunk' and 'size' parameters may be used to download the software in chunks. For example, device may request first 16 KB of software using 'chunk'=0 and 'size'=16384. Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - - -### Parameters - -| Name | Type | Description | Notes | -|------------- | ------------- | ------------- | -------------| -| **deviceToken** | **String** | Your device access token. | | -| **title** | **String** | Title of the software, corresponds to the value of 'sw_title' attribute. | | -| **version** | **String** | Version of the software, corresponds to the value of 'sw_version' attribute. | | -| **size** | **Integer** | Size of the chunk. Optional. Omit to download the entire file without using chunks. | [optional] [default to 0] | -| **chunk** | **Integer** | Index of the chunk. Optional. Omit to download the entire file without using chunks. | [optional] [default to 0] | - -### Return type - -**String** - - -## postDeviceAttributes - -``` -String postDeviceAttributes(@Nonnull String deviceToken, @Nonnull String body) -``` - -**POST** `/api/v1/{deviceToken}/attributes` - -Post attributes (postDeviceAttributes) - -Post client attribute updates on behalf of device. Example of the request: ```json { \"stringKey\":\"value1\", \"booleanKey\":true, \"doubleKey\":42.0, \"longKey\":73, \"jsonKey\": { \"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"} } } ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - - -### Parameters - -| Name | Type | Description | Notes | -|------------- | ------------- | ------------- | -------------| -| **deviceToken** | **String** | Your device access token. | | -| **body** | **String** | JSON with attribute key-value pairs. See API call description for example. | | - -### Return type - -**String** - - -## postRpcRequest - -``` -String postRpcRequest(@Nonnull String deviceToken, @Nonnull String body) -``` - -**POST** `/api/v1/{deviceToken}/rpc` - -Send the RPC command (postRpcRequest) - -Send the RPC request to server. The request payload is a JSON document that contains 'method' and 'params'. For example: ```json {\"method\": \"sumOnServer\", \"params\":{\"a\":2, \"b\":2}} ``` The response contains arbitrary JSON with the RPC reply. For example: ```json {\"result\": 4} ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - - -### Parameters - -| Name | Type | Description | Notes | -|------------- | ------------- | ------------- | -------------| -| **deviceToken** | **String** | Your device access token. | | -| **body** | **String** | The RPC request JSON | | - -### Return type - -**String** - - -## postTelemetry - -``` -String postTelemetry(@Nonnull String deviceToken, @Nonnull String body) -``` - -**POST** `/api/v1/{deviceToken}/telemetry` - -Post time series data (postTelemetry) - -Post time series data on behalf of device. Example of the request: The request payload is a JSON document with three possible formats: Simple format without timestamp. In such a case, current server time will be used: ```json { \"stringKey\":\"value1\", \"booleanKey\":true, \"doubleKey\":42.0, \"longKey\":73, \"jsonKey\": { \"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"} } } ``` Single JSON object with timestamp: ```json {\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}} ``` JSON array with timestamps: ```json [ {\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}}, {\"ts\":1634712588000,\"values\":{\"temperature\":25, \"humidity\":88}} ] ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - - -### Parameters - -| Name | Type | Description | Notes | -|------------- | ------------- | ------------- | -------------| -| **deviceToken** | **String** | Your device access token. | | -| **body** | **String** | | | - -### Return type - -**String** - - -## provisionDevice - -``` -String provisionDevice(@Nonnull String body) -``` - -**POST** `/api/v1/provision` - -Provision new device (provisionDevice) - -Exchange the provision request to the device credentials. See more info about provisioning in the corresponding 'Device provisioning' platform documentation.Requires valid JSON request with the following format: ```json { \"deviceName\": \"NEW_DEVICE_NAME\", \"provisionDeviceKey\": \"u7piawkboq8v32dmcmpp\", \"provisionDeviceSecret\": \"jpmwdn8ptlswmf4m29bw\" } ``` Where 'deviceName' is the name of enw or existing device which depends on the provisioning strategy. The 'provisionDeviceKey' and 'provisionDeviceSecret' matches info configured in one of the existing device profiles. The result of the successful call is the JSON object that contains new credentials: ```json { \"credentialsType\":\"ACCESS_TOKEN\", \"credentialsValue\":\"DEVICE_ACCESS_TOKEN\", \"status\":\"SUCCESS\" } ``` - - -### Parameters - -| Name | Type | Description | Notes | -|------------- | ------------- | ------------- | -------------| -| **body** | **String** | JSON with provision request. See API call description for example. | | - -### Return type - -**String** - - -## replyToCommand - -``` -String replyToCommand(@Nonnull String deviceToken, @Nonnull String requestId, @Nonnull String body) -``` - -**POST** `/api/v1/{deviceToken}/rpc/{requestId}` - -Reply to RPC commands (replyToCommand) - -Replies to server originated RPC command identified by 'requestId' parameter. The response is arbitrary JSON. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - - -### Parameters - -| Name | Type | Description | Notes | -|------------- | ------------- | ------------- | -------------| -| **deviceToken** | **String** | Your device access token. | | -| **requestId** | **String** | RPC request id from the incoming RPC request | | -| **body** | **String** | Reply to the RPC request, JSON. For example: {\"status\":\"success\"} | | - -### Return type - -**String** - - -## saveClaimingInfo - -``` -String saveClaimingInfo(@Nonnull String deviceToken, @Nullable String body) -``` - -**POST** `/api/v1/{deviceToken}/claim` - -Save claiming information (saveClaimingInfo) - -Saves the information required for user to claim the device. See more info about claiming in the corresponding 'Claiming devices' platform documentation. Example of the request payload: ```json {\"secretKey\":\"value\", \"durationMs\":60000} ``` Note: both 'secretKey' and 'durationMs' is optional parameters. In case the secretKey is not specified, the empty string as a default value is used. In case the durationMs is not specified, the system parameter device.claim.duration is used. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - - -### Parameters - -| Name | Type | Description | Notes | -|------------- | ------------- | ------------- | -------------| -| **deviceToken** | **String** | Your device access token. | | -| **body** | **String** | | [optional] | - -### Return type - -**String** - - -## subscribeToAttributes - -``` -String subscribeToAttributes(@Nonnull String deviceToken, @Nullable Long timeout) -``` - -**GET** `/api/v1/{deviceToken}/attributes/updates` - -Subscribe to attribute updates (subscribeToAttributes) (Deprecated) - -Subscribes to client and shared scope attribute updates using http long polling. Deprecated, since long polling is resource and network consuming. Consider using MQTT or CoAP protocol for light-weight real-time updates. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - - -### Parameters - -| Name | Type | Description | Notes | -|------------- | ------------- | ------------- | -------------| -| **deviceToken** | **String** | Your device access token. | | -| **timeout** | **Long** | Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side. | [optional] [default to 0] | - -### Return type - -**String** - - -## subscribeToCommands - -``` -String subscribeToCommands(@Nonnull String deviceToken, @Nullable Long timeout) -``` - -**GET** `/api/v1/{deviceToken}/rpc` - -Subscribe to RPC commands (subscribeToCommands) (Deprecated) - -Subscribes to RPC commands using http long polling. Deprecated, since long polling is resource and network consuming. Consider using MQTT or CoAP protocol for light-weight real-time updates. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - - -### Parameters - -| Name | Type | Description | Notes | -|------------- | ------------- | ------------- | -------------| -| **deviceToken** | **String** | Your device access token. | | -| **timeout** | **Long** | Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side. | [optional] [default to 0] | - -### Return type - -**String** - diff --git a/ce/spec/openapi.json b/ce/spec/openapi.json index 30b87b0a..1e387d06 100644 --- a/ce/spec/openapi.json +++ b/ce/spec/openapi.json @@ -73,10 +73,6 @@ "name": "dashboard-controller", "description": "Dashboard Controller" }, - { - "name": "device-api-controller", - "description": "Device Api Controller" - }, { "name": "device-connectivity-controller", "description": "Device Connectivity Controller" @@ -22021,32 +22017,33 @@ ] } }, - "/api/v1/provision": { - "post": { + "/api/device-connectivity/gateway-launch/{deviceId}/docker-compose/download": { + "get": { "tags": [ - "device-api-controller" + "device-connectivity-controller" ], - "summary": "Provision new device (provisionDevice)", - "description": "Exchange the provision request to the device credentials. See more info about provisioning in the corresponding 'Device provisioning' platform documentation.Requires valid JSON request with the following format: \n\n```json\n{\n \"deviceName\": \"NEW_DEVICE_NAME\",\n \"provisionDeviceKey\": \"u7piawkboq8v32dmcmpp\",\n \"provisionDeviceSecret\": \"jpmwdn8ptlswmf4m29bw\"\n}\n```\n\nWhere 'deviceName' is the name of enw or existing device which depends on the provisioning strategy. The 'provisionDeviceKey' and 'provisionDeviceSecret' matches info configured in one of the existing device profiles. The result of the successful call is the JSON object that contains new credentials:\n\n```json\n{\n \"credentialsType\":\"ACCESS_TOKEN\",\n \"credentialsValue\":\"DEVICE_ACCESS_TOKEN\",\n \"status\":\"SUCCESS\"\n}\n```\n\n", - "operationId": "provisionDevice", - "requestBody": { - "description": "JSON with provision request. See API call description for example.", - "content": { - "application/json": { - "schema": { - "type": "string" - } + "summary": "Download generated docker-compose.yml file for gateway (downloadGatewayDockerCompose)", + "description": "Download generated docker-compose.yml for gateway.", + "operationId": "downloadGatewayDockerCompose", + "parameters": [ + { + "name": "deviceId", + "in": "path", + "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" } - }, - "required": true - }, + } + ], "responses": { "200": { "description": "OK", "content": { - "application/json": { + "application/octet-stream": { "schema": { - "type": "string" + "type": "string", + "format": "binary" } } } @@ -22063,7 +22060,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -22156,40 +22153,30 @@ } } } - } + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] } }, - "/api/v1/{deviceToken}/attributes": { + "/api/device-connectivity/{deviceId}": { "get": { "tags": [ - "device-api-controller" + "device-connectivity-controller" ], - "summary": "Get attributes (getDeviceAttributes)", - "description": "Returns all attributes that belong to device. Use optional 'clientKeys' and/or 'sharedKeys' parameter to return specific attributes. \n Example of the result: \n\n```json\n{\n \"stringKey\":\"value1\", \n \"booleanKey\":true, \n \"doubleKey\":42.0, \n \"longKey\":73, \n \"jsonKey\": {\n \"someNumber\": 42,\n \"someArray\": [1,2,3],\n \"someNestedObject\": {\"key\": \"value\"}\n }\n}\n```\n\nThe API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead).\n", - "operationId": "getDeviceAttributes", + "summary": "Get commands to publish device telemetry (getDevicePublishTelemetryCommands)", + "description": "Fetch the list of commands to publish device telemetry based on device profile If the user has the authority of 'Tenant Administrator', the server checks that the device is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the device is assigned to the same customer. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getDevicePublishTelemetryCommands", "parameters": [ { - "name": "deviceToken", + "name": "deviceId", "in": "path", - "description": "Your device access token.", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "clientKeys", - "in": "query", - "description": "Comma separated key names for attribute with client scope", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "sharedKeys", - "in": "query", - "description": "Comma separated key names for attribute with shared scope", + "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" @@ -22202,7 +22189,21 @@ "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/JsonNode" + }, + "examples": { + "http": { + "description": "http", + "value": "curl -v -X POST http://localhost:8080/api/v1/0ySs4FTOn5WU15XLmal8/telemetry --header Content-Type:application/json --data {temperature:25}" + }, + "mqtt": { + "description": "mqtt", + "value": "mosquitto_pub -d -q 1 -h localhost -t v1/devices/me/telemetry -i myClient1 -u myUsername1 -P myPassword -m {temperature:25}" + }, + "coap": { + "description": "coap", + "value": "coap-client -m POST coap://localhost:5683/api/v1/0ySs4FTOn5WU15XLmal8/telemetry -t json -e {temperature:25}" + } } } } @@ -22312,44 +22313,44 @@ } } } - } - }, - "post": { + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] + } + }, + "/api/device-connectivity/{protocol}/certificate/download": { + "get": { "tags": [ - "device-api-controller" + "device-connectivity-controller" ], - "summary": "Post attributes (postDeviceAttributes)", - "description": "Post client attribute updates on behalf of device. \n Example of the request: \n\n```json\n{\n \"stringKey\":\"value1\", \n \"booleanKey\":true, \n \"doubleKey\":42.0, \n \"longKey\":73, \n \"jsonKey\": {\n \"someNumber\": 42,\n \"someArray\": [1,2,3],\n \"someNestedObject\": {\"key\": \"value\"}\n }\n}\n```\n\nThe API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead).\n", - "operationId": "postDeviceAttributes", + "summary": "Download server certificate using file path defined in device.connectivity properties (downloadServerCertificate)", + "description": "Download server certificate.", + "operationId": "downloadServerCertificate", "parameters": [ { - "name": "deviceToken", + "name": "protocol", "in": "path", - "description": "Your device access token.", + "description": "A string value representing the device connectivity protocol. Possible values: 'mqtt', 'mqtts', 'http', 'https', 'coap', 'coaps'", "required": true, "schema": { "type": "string" } } ], - "requestBody": { - "description": "JSON with attribute key-value pairs. See API call description for example.", - "content": { - "application/json": { - "schema": { - "type": "string" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { - "application/json": { + "application/octet-stream": { "schema": { - "type": "string" + "type": "string", + "format": "binary" } } } @@ -22366,7 +22367,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -22459,37 +22460,34 @@ } } } - } + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] } }, - "/api/v1/{deviceToken}/attributes/updates": { - "get": { + "/api/customer/device/{deviceId}": { + "delete": { "tags": [ - "device-api-controller" + "device-controller" ], - "summary": "Subscribe to attribute updates (subscribeToAttributes) (Deprecated)", - "description": "Subscribes to client and shared scope attribute updates using http long polling. Deprecated, since long polling is resource and network consuming. Consider using MQTT or CoAP protocol for light-weight real-time updates. \n\nThe API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead).\n", - "operationId": "subscribeToAttributes", + "summary": "Unassign device from customer (unassignDeviceFromCustomer)", + "description": "Clears assignment of the device to customer. Customer will not be able to query device afterwards.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "unassignDeviceFromCustomer", "parameters": [ { - "name": "deviceToken", + "name": "deviceId", "in": "path", - "description": "Your device access token.", + "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" } - }, - { - "name": "timeout", - "in": "query", - "description": "Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side.", - "required": false, - "schema": { - "type": "integer", - "format": "int64", - "default": 0 - } } ], "responses": { @@ -22498,7 +22496,7 @@ "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/Device" } } } @@ -22608,22 +22606,30 @@ } } } - } + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] } }, - "/api/v1/{deviceToken}/claim": { + "/api/customer/device/{deviceName}/claim": { "post": { "tags": [ - "device-api-controller" + "device-controller" ], - "summary": "Save claiming information (saveClaimingInfo)", - "description": "Saves the information required for user to claim the device. See more info about claiming in the corresponding 'Claiming devices' platform documentation.\n Example of the request payload: \n\n```json\n{\"secretKey\":\"value\", \"durationMs\":60000}\n```\n\nNote: both 'secretKey' and 'durationMs' is optional parameters. In case the secretKey is not specified, the empty string as a default value is used. In case the durationMs is not specified, the system parameter device.claim.duration is used.\n\nThe API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead).\n", - "operationId": "saveClaimingInfo", + "summary": "Claim device (claimDevice)", + "description": "Claiming makes it possible to assign a device to the specific customer using device/server side claiming data (in the form of secret key).To make this happen you have to provide unique device name and optional claiming data (it is needed only for device-side claiming).Once device is claimed, the customer becomes its owner and customer users may access device data as well as control the device. \nIn order to enable claiming devices feature a system parameter security.claim.allowClaimingByDefault should be set to true, otherwise a server-side claimingAllowed attribute with the value true is obligatory for provisioned devices. \nSee official documentation for more details regarding claiming.\n\nAvailable for users with 'CUSTOMER_USER' authority.", + "operationId": "claimDevice", "parameters": [ { - "name": "deviceToken", + "name": "deviceName", "in": "path", - "description": "Your device access token.", + "description": "Unique name of the device which is going to be claimed", "required": true, "schema": { "type": "string" @@ -22634,7 +22640,7 @@ "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/ClaimRequest" } } } @@ -22755,66 +22761,32 @@ } } } - } - } - }, - "/api/v1/{deviceToken}/firmware": { - "get": { + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] + }, + "delete": { "tags": [ - "device-api-controller" + "device-controller" ], - "summary": "Get Device Firmware (getFirmware)", - "description": "Downloads the current firmware package.When the platform initiates firmware update, it informs the device by updating the 'fw_title', 'fw_version', 'fw_checksum' and 'fw_checksum_algorithm' shared attributes.The 'fw_title' and 'fw_version' parameters must be supplied in this request to double-check that the firmware that device is downloading matches the firmware it expects to download. This is important, since the administrator may change the firmware assignment while device is downloading the firmware. \n\nOptional 'chunk' and 'size' parameters may be used to download the firmware in chunks. For example, device may request first 16 KB of firmware using 'chunk'=0 and 'size'=16384. Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. \n\nThe API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead).\n", - "operationId": "getFirmware", + "summary": "Reclaim device (reClaimDevice)", + "description": "Reclaiming means the device will be unassigned from the customer and the device will be available for claiming again.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "reClaimDevice", "parameters": [ { - "name": "deviceToken", + "name": "deviceName", "in": "path", - "description": "Your device access token.", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "title", - "in": "query", - "description": "Title of the firmware, corresponds to the value of 'fw_title' attribute.", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "version", - "in": "query", - "description": "Version of the firmware, corresponds to the value of 'fw_version' attribute.", + "description": "Unique name of the device which is going to be reclaimed", "required": true, "schema": { "type": "string" } - }, - { - "name": "size", - "in": "query", - "description": "Size of the chunk. Optional. Omit to download the entire file without chunks.", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "default": 0 - } - }, - { - "name": "chunk", - "in": "query", - "description": "Index of the chunk. Optional. Omit to download the entire file without chunks.", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "default": 0 - } } ], "responses": { @@ -22933,37 +22905,34 @@ } } } - } + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] } }, - "/api/v1/{deviceToken}/rpc": { - "get": { + "/api/customer/public/device/{deviceId}": { + "post": { "tags": [ - "device-api-controller" + "device-controller" ], - "summary": "Subscribe to RPC commands (subscribeToCommands) (Deprecated)", - "description": "Subscribes to RPC commands using http long polling. Deprecated, since long polling is resource and network consuming. Consider using MQTT or CoAP protocol for light-weight real-time updates. \n\nThe API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead).\n", - "operationId": "subscribeToCommands", + "summary": "Make device publicly available (assignDeviceToPublicCustomer)", + "description": "Device will be available for non-authorized (not logged-in) users. This is useful to create dashboards that you plan to share/embed on a publicly available website. However, users that are logged-in and belong to different tenant will not be able to access the device.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "assignDeviceToPublicCustomer", "parameters": [ { - "name": "deviceToken", + "name": "deviceId", "in": "path", - "description": "Your device access token.", + "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" } - }, - { - "name": "timeout", - "in": "query", - "description": "Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side.", - "required": false, - "schema": { - "type": "integer", - "format": "int64", - "default": 0 - } } ], "responses": { @@ -22972,7 +22941,7 @@ "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/Device" } } } @@ -22989,7 +22958,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -23082,64 +23051,73 @@ } } } - } - }, + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] + } + }, + "/api/customer/{customerId}/device/{deviceId}": { "post": { "tags": [ - "device-api-controller" + "device-controller" ], - "summary": "Send the RPC command (postRpcRequest)", - "description": "Send the RPC request to server. The request payload is a JSON document that contains 'method' and 'params'. For example:\n\n```json\n{\"method\": \"sumOnServer\", \"params\":{\"a\":2, \"b\":2}}\n```\n\nThe response contains arbitrary JSON with the RPC reply. For example: \n\n```json\n{\"result\": 4}\n```\n\nThe API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead).\n", - "operationId": "postRpcRequest", + "summary": "Assign device to customer (assignDeviceToCustomer)", + "description": "Creates assignment of the device to customer. Customer will be able to query device afterwards.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "assignDeviceToCustomer", "parameters": [ { - "name": "deviceToken", + "name": "customerId", + "in": "path", + "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "deviceId", "in": "path", - "description": "Your device access token.", + "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" } } ], - "requestBody": { - "description": "The RPC request JSON", - "content": { - "application/json": { - "schema": { - "type": "string" - } - } - }, - "required": true - }, "responses": { "200": { - "description": "RPC request to server was sent to Rule Engine.", + "description": "OK", "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/Device" } } } }, "400": { - "description": "Invalid structure of the request.", - "content": { - "application/json": { - "schema": { - "type": "string" - } - } - } - }, - "413": { - "description": "Request payload too large.", + "description": "Bad Request", "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/ThingsboardErrorResponse" + }, + "examples": { + "error-code-400": { + "summary": "Bad Request", + "value": { + "status": 400, + "message": "Invalid request body", + "errorCode": 31, + "timestamp": 1609459200000 + } + } } } } @@ -23228,75 +23206,149 @@ } } } - } + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] } }, - "/api/v1/{deviceToken}/rpc/{requestId}": { - "post": { + "/api/customer/{customerId}/deviceInfos": { + "get": { "tags": [ - "device-api-controller" + "device-controller" ], - "summary": "Reply to RPC commands (replyToCommand)", - "description": "Replies to server originated RPC command identified by 'requestId' parameter. The response is arbitrary JSON.\n\nThe API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead).\n", - "operationId": "replyToCommand", + "summary": "Get Customer Device Infos (getCustomerDeviceInfos)", + "description": "Returns a page of devices info objects assigned to customer. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. Device Info is an extension of the default Device object that contains information about the assigned customer name and device profile name. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getCustomerDeviceInfos", "parameters": [ { - "name": "deviceToken", + "name": "customerId", "in": "path", - "description": "Your device access token.", + "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" } }, { - "name": "requestId", - "in": "path", - "description": "RPC request id from the incoming RPC request", + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "type", + "in": "query", + "description": "Device type as the name of the device profile", + "required": false, "schema": { "type": "string" } - } - ], - "requestBody": { - "description": "Reply to the RPC request, JSON. For example: {\"status\":\"success\"}", - "content": { - "application/json": { - "schema": { - "type": "string" - } + }, + { + "name": "deviceProfileId", + "in": "query", + "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": false, + "schema": { + "type": "string" } }, - "required": true - }, + { + "name": "active", + "in": "query", + "description": "A boolean value representing the device active flag.", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'substring' filter based on the device name.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string", + "enum": [ + "createdTime", + "name", + "deviceProfileName", + "label", + "customerTitle" + ] + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ASC", + "DESC" + ] + } + } + ], "responses": { "200": { - "description": "RPC reply to command request was sent to Core.", + "description": "OK", "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/PageDataDeviceInfo" } } } }, "400": { - "description": "Invalid structure of the request.", - "content": { - "application/json": { - "schema": { - "type": "string" - } - } - } - }, - "413": { - "description": "Request payload is too large.", + "description": "Bad Request", "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/ThingsboardErrorResponse" + }, + "examples": { + "error-code-400": { + "summary": "Bad Request", + "value": { + "status": 400, + "message": "Invalid UUID string: 123", + "errorCode": 31, + "timestamp": 1609459200000 + } + } } } } @@ -23385,65 +23437,100 @@ } } } - } + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] } }, - "/api/v1/{deviceToken}/software": { + "/api/customer/{customerId}/devices": { "get": { "tags": [ - "device-api-controller" + "device-controller" ], - "summary": "Get Device Software (getSoftware)", - "description": "Downloads the current software package.When the platform initiates software update, it informs the device by updating the 'sw_title', 'sw_version', 'sw_checksum' and 'sw_checksum_algorithm' shared attributes.The 'sw_title' and 'sw_version' parameters must be supplied in this request to double-check that the software that device is downloading matches the software it expects to download. This is important, since the administrator may change the software assignment while device is downloading the software. \n\nOptional 'chunk' and 'size' parameters may be used to download the software in chunks. For example, device may request first 16 KB of software using 'chunk'=0 and 'size'=16384. Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. \n\nThe API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead).\n", - "operationId": "getSoftware", + "summary": "Get Customer Devices (getCustomerDevices)", + "description": "Returns a page of devices objects assigned to customer. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getCustomerDevices", "parameters": [ { - "name": "deviceToken", + "name": "customerId", "in": "path", - "description": "Your device access token.", + "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" } }, { - "name": "title", + "name": "pageSize", "in": "query", - "description": "Title of the software, corresponds to the value of 'sw_title' attribute.", + "description": "Maximum amount of entities in a one page", "required": true, "schema": { - "type": "string" + "type": "integer", + "format": "int32" } }, { - "name": "version", + "name": "page", "in": "query", - "description": "Version of the software, corresponds to the value of 'sw_version' attribute.", + "description": "Sequence number of page starting from 0", "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "type", + "in": "query", + "description": "Device type as the name of the device profile", + "required": false, "schema": { "type": "string" } }, { - "name": "size", + "name": "textSearch", "in": "query", - "description": "Size of the chunk. Optional. Omit to download the entire file without using chunks.", + "description": "The case insensitive 'substring' filter based on the device name.", "required": false, "schema": { - "type": "integer", - "format": "int32", - "default": 0 + "type": "string" } }, { - "name": "chunk", + "name": "sortProperty", "in": "query", - "description": "Index of the chunk. Optional. Omit to download the entire file without using chunks.", + "description": "Property of entity to sort by", "required": false, "schema": { - "type": "integer", - "format": "int32", - "default": 0 + "type": "string", + "enum": [ + "createdTime", + "name", + "deviceProfileName", + "label", + "customerTitle" + ] + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ASC", + "DESC" + ] } } ], @@ -23453,7 +23540,7 @@ "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/PageDataDevice" } } } @@ -23563,33 +23650,72 @@ } } } - } + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] } }, - "/api/v1/{deviceToken}/telemetry": { + "/api/device": { "post": { "tags": [ - "device-api-controller" + "device-controller" ], - "summary": "Post time series data (postTelemetry)", - "description": "Post time series data on behalf of device. \n Example of the request: The request payload is a JSON document with three possible formats:\n\nSimple format without timestamp. In such a case, current server time will be used: \n\n\n\n```json\n{\n \"stringKey\":\"value1\", \n \"booleanKey\":true, \n \"doubleKey\":42.0, \n \"longKey\":73, \n \"jsonKey\": {\n \"someNumber\": 42,\n \"someArray\": [1,2,3],\n \"someNestedObject\": {\"key\": \"value\"}\n }\n}\n```\n\n\n\n Single JSON object with timestamp: \n\n\n\n```json\n{\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}}\n```\n\n\n\n JSON array with timestamps: \n\n\n\n```json\n[\n{\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}}, \n{\"ts\":1634712588000,\"values\":{\"temperature\":25, \"humidity\":88}}\n]\n```\n\nThe API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead).\n", - "operationId": "postTelemetry", + "summary": "Create Or Update Device (saveDevice)", + "description": "Create or update the Device. When creating device, platform generates Device Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)). Device credentials are also generated if not provided in the 'accessToken' request parameter. The newly created device id will be present in the response. Specify existing Device id to update the device. Referencing non-existing device Id will cause 'Not Found' error.\n\nDevice name is unique in the scope of tenant. Use unique identifiers like MAC or IMEI for the device names and non-unique 'label' field for user-friendly visualization purposes.Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Device entity. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "saveDevice", "parameters": [ { - "name": "deviceToken", - "in": "path", - "description": "Your device access token.", - "required": true, + "name": "accessToken", + "in": "query", + "description": "Optional value of the device credentials to be used during device creation. If omitted, access token will be auto-generated.", + "required": false, "schema": { "type": "string" } + }, + { + "name": "nameConflictPolicy", + "in": "query", + "description": "Optional value of name conflict policy. Possible values: FAIL or UNIQUIFY. If omitted, FAIL policy is applied. FAIL policy implies exception will be thrown if an entity with the same name already exists. UNIQUIFY policy appends a suffix to the entity name, if a name conflict occurs.", + "required": false, + "schema": { + "$ref": "#/components/schemas/NameConflictPolicy", + "default": "FAIL" + } + }, + { + "name": "uniquifySeparator", + "in": "query", + "description": "Optional value of name suffix separator used by UNIQUIFY policy. By default, underscore separator is used. For example, strategy is UNIQUIFY, separator is '-'; if a name conflict occurs for entity name 'test-name', created entity will have name like 'test-name-7fsh4f'.", + "required": false, + "schema": { + "type": "string", + "default": "_" + } + }, + { + "name": "uniquifyStrategy", + "in": "query", + "description": "Optional value of uniquify strategy used by UNIQUIFY policy. Possible values: RANDOM or INCREMENTAL. By default, RANDOM strategy is used, which means random alphanumeric string will be added as a suffix to entity name. INCREMENTAL implies the first possible number starting from 1 will be added as a name suffix. For example, strategy is UNIQUIFY, uniquify strategy is INCREMENTAL; if a name conflict occurs for entity name 'test-name', created entity will have name like 'test-name-1.", + "required": false, + "schema": { + "$ref": "#/components/schemas/UniquifyStrategy", + "default": "RANDOM" + } } ], "requestBody": { + "description": "A JSON value representing the device.", "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/Device" } } }, @@ -23601,7 +23727,7 @@ "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/Device" } } } @@ -23711,36 +23837,74 @@ } } } - } + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] } }, - "/api/device-connectivity/gateway-launch/{deviceId}/docker-compose/download": { - "get": { + "/api/device-with-credentials": { + "post": { "tags": [ - "device-connectivity-controller" + "device-controller" ], - "summary": "Download generated docker-compose.yml file for gateway (downloadGatewayDockerCompose)", - "description": "Download generated docker-compose.yml for gateway.", - "operationId": "downloadGatewayDockerCompose", + "summary": "Create Device (saveDevice) with credentials ", + "description": "Create or update the Device. When creating device, platform generates Device Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)). Requires to provide the Device Credentials object as well as an existing device profile ID or use \"default\".\nYou may find the example of device with different type of credentials below: \n\n- Credentials type: **\"Access token\"** with **device profile ID** below: \n\n```json\n{\n \"device\": {\n \"name\":\"Name_DeviceWithCredantial_AccessToken\",\n \"label\":\"Label_DeviceWithCredantial_AccessToken\",\n \"deviceProfileId\":{\n \"id\":\"9d9588c0-06c9-11ee-b618-19be30fdeb60\",\n \"entityType\":\"DEVICE_PROFILE\"\n }\n },\n \"credentials\": {\n \"credentialsType\": \"ACCESS_TOKEN\",\n \"credentialsId\": \"6hmxew8pmmzng4e3une2\"\n }\n}\n```\n\n- Credentials type: **\"Access token\"** with **device profile default** below: \n\n```json\n{\n \"device\": {\n \"name\":\"Name_DeviceWithCredantial_AccessToken_Default\",\n \"label\":\"Label_DeviceWithCredantial_AccessToken_Default\",\n \"type\": \"default\"\n },\n \"credentials\": {\n \"credentialsType\": \"ACCESS_TOKEN\",\n \"credentialsId\": \"6hmxew8pmmzng4e3une3\"\n }\n}\n```\n\n- Credentials type: **\"X509\"** with **device profile ID** below: \n\nNote: **credentialsId** - format **Sha3Hash**, **certificateValue** - format **PEM** (with \"--BEGIN CERTIFICATE----\" and -\"----END CERTIFICATE-\").\n\n```json\n{\n \"device\": {\n \"name\":\"Name_DeviceWithCredantial_X509_Certificate\",\n \"label\":\"Label_DeviceWithCredantial_X509_Certificate\",\n \"deviceProfileId\":{\n \"id\":\"9d9588c0-06c9-11ee-b618-19be30fdeb60\",\n \"entityType\":\"DEVICE_PROFILE\"\n }\n },\n \"credentials\": {\n \"credentialsType\": \"X509_CERTIFICATE\",\n \"credentialsId\": \"84f5911765abba1f96bf4165604e9e90338fc6214081a8e623b6ff9669aedb27\",\n \"credentialsValue\": \"-----BEGIN CERTIFICATE----- MIICMTCCAdegAwIBAgIUI9dBuwN6pTtK6uZ03rkiCwV4wEYwCgYIKoZIzj0EAwIwbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGluZ3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlQ2VydGlmaWNhdGVAWDUwOVByb3Zpc2lvblN0cmF0ZWd5MB4XDTIzMDMyOTE0NTYxN1oXDTI0MDMyODE0NTYxN1owbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGluZ3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlQ2VydGlmaWNhdGVAWDUwOVByb3Zpc2lvblN0cmF0ZWd5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9Zo791qKQiGNBm11r4ZGxh+w+ossZL3xc46ufq5QckQHP7zkD2XDAcmP5GvdkM1sBFN9AWaCkQfNnWmfERsOOKNTMFEwHQYDVR0OBBYEFFFc5uyCyglQoZiKhzXzMcQ3BKORMB8GA1UdIwQYMBaAFFFc5uyCyglQoZiKhzXzMcQ3BKORMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIhANbA9CuhoOifZMMmqkpuld+65CR+ItKdXeRAhLMZuccuAiB0FSQB34zMutXrZj1g8Gl5OkE7YryFHbei1z0SveHR8g== -----END CERTIFICATE-----\"\n }\n}\n```\n\n- Credentials type: **\"MQTT_BASIC\"** with **device profile ID** below: \n\n```json\n{\n \"device\": {\n \"name\":\"Name_DeviceWithCredantial_MQTT_Basic\",\n \"label\":\"Label_DeviceWithCredantial_MQTT_Basic\",\n \"deviceProfileId\":{\n \"id\":\"9d9588c0-06c9-11ee-b618-19be30fdeb60\",\n \"entityType\":\"DEVICE_PROFILE\"\n }\n },\n \"credentials\": {\n \"credentialsType\": \"MQTT_BASIC\",\n \"credentialsValue\": \"{\\\"clientId\\\":\\\"5euh5nzm34bjjh1efmlt\\\",\\\"userName\\\":\\\"onasd1lgwasmjl7v2v7h\\\",\\\"password\\\":\\\"b9xtm4ny8kt9zewaga5o\\\"}\"\n }\n}\n```\n\n- You may find the example of **LwM2M** device and **RPK** credentials below: \n\nNote: LwM2M device - only existing device profile ID (Transport configuration -> Transport type: \"LWM2M\".\n\n```json\n{\n \"device\": {\n \"name\":\"Name_LwRpk00000000\",\n \"label\":\"Label_LwRpk00000000\",\n \"deviceProfileId\":{\n \"id\":\"a660bd50-10ef-11ee-8737-b5634e73c779\",\n \"entityType\":\"DEVICE_PROFILE\"\n }\n },\n \"credentials\": {\n \"credentialsType\": \"LWM2M_CREDENTIALS\",\n \"credentialsId\": \"LwRpk00000000\",\n \"credentialsValue\":\n \"{\\\"client\\\":{ \\\"endpoint\\\":\\\"LwRpk00000000\\\", \\\"securityConfigClientMode\\\":\\\"RPK\\\", \\\"key\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\\\" }, \\\"bootstrap\\\":{ \\\"bootstrapServer\\\":{ \\\"securityMode\\\":\\\"RPK\\\", \\\"clientPublicKeyOrId\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\\\", \\\"clientSecretKey\\\":\\\"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgd9GAx7yZW37autew5KZykn4IgRpge/tZSjnudnZJnMahRANCAARQQHE2X9Fxgk2byaT3ULJVeggmJE5gOVdxJKorp7lsMfA5bhmI3aU2ddqXIXQnHDwxsDK2cMwRFfICNrlUQx5V\\\"}, \\\"lwm2mServer\\\":{ \\\"securityMode\\\":\\\"RPK\\\", \\\"clientPublicKeyOrId\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\\\", \\\"clientSecretKey\\\":\\\"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgd9GAx7yZW37autew5KZykn4IgRpge/tZSjnudnZJnMahRANCAARQQHE2X9Fxgk2byaT3ULJVeggmJE5gOVdxJKorp7lsMfA5bhmI3aU2ddqXIXQnHDwxsDK2cMwRFfICNrlUQx5V\\\"}} }\"\n }\n}\n```\n\nRemove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Device entity. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "saveDeviceWithCredentials", "parameters": [ { - "name": "deviceId", - "in": "path", - "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, + "name": "nameConflictPolicy", + "in": "query", + "description": "Optional value of name conflict policy. Possible values: FAIL or UNIQUIFY. If omitted, FAIL policy is applied. FAIL policy implies exception will be thrown if an entity with the same name already exists. UNIQUIFY policy appends a suffix to the entity name, if a name conflict occurs.", + "required": false, "schema": { - "type": "string" + "$ref": "#/components/schemas/NameConflictPolicy", + "default": "FAIL" + } + }, + { + "name": "uniquifySeparator", + "in": "query", + "description": "Optional value of name suffix separator used by UNIQUIFY policy. By default, underscore separator is used. For example, strategy is UNIQUIFY, separator is '-'; if a name conflict occurs for entity name 'test-name', created entity will have name like 'test-name-7fsh4f'.", + "required": false, + "schema": { + "type": "string", + "default": "_" + } + }, + { + "name": "uniquifyStrategy", + "in": "query", + "description": "Optional value of uniquify strategy used by UNIQUIFY policy. Possible values: RANDOM or INCREMENTAL. By default, RANDOM strategy is used, which means random alphanumeric string will be added as a suffix to entity name. INCREMENTAL implies the first possible number starting from 1 will be added as a name suffix. For example, strategy is UNIQUIFY, uniquify strategy is INCREMENTAL; if a name conflict occurs for entity name 'test-name', created entity will have name like 'test-name-1.", + "required": false, + "schema": { + "$ref": "#/components/schemas/UniquifyStrategy", + "default": "RANDOM" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SaveDeviceWithCredentialsRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { - "application/octet-stream": { + "application/json": { "schema": { - "type": "string", - "format": "binary" + "$ref": "#/components/schemas/Device" } } } @@ -23757,7 +23921,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -23861,46 +24025,31 @@ ] } }, - "/api/device-connectivity/{deviceId}": { - "get": { + "/api/device/bulk_import": { + "post": { "tags": [ - "device-connectivity-controller" + "device-controller" ], - "summary": "Get commands to publish device telemetry (getDevicePublishTelemetryCommands)", - "description": "Fetch the list of commands to publish device telemetry based on device profile If the user has the authority of 'Tenant Administrator', the server checks that the device is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the device is assigned to the same customer. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getDevicePublishTelemetryCommands", - "parameters": [ - { - "name": "deviceId", - "in": "path", - "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" + "summary": "Import the bulk of devices (processDevicesBulkImport)", + "description": "There's an ability to import the bulk of devices using the only .csv file.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "processDevicesBulkImport", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkImportRequest" + } } - } - ], + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/JsonNode" - }, - "examples": { - "http": { - "description": "http", - "value": "curl -v -X POST http://localhost:8080/api/v1/0ySs4FTOn5WU15XLmal8/telemetry --header Content-Type:application/json --data {temperature:25}" - }, - "mqtt": { - "description": "mqtt", - "value": "mosquitto_pub -d -q 1 -h localhost -t v1/devices/me/telemetry -i myClient1 -u myUsername1 -P myPassword -m {temperature:25}" - }, - "coap": { - "description": "coap", - "value": "coap-client -m POST coap://localhost:5683/api/v1/0ySs4FTOn5WU15XLmal8/telemetry -t json -e {temperature:25}" - } + "$ref": "#/components/schemas/BulkImportResultDevice" } } } @@ -23917,7 +24066,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -24021,33 +24170,31 @@ ] } }, - "/api/device-connectivity/{protocol}/certificate/download": { - "get": { + "/api/device/credentials": { + "post": { "tags": [ - "device-connectivity-controller" + "device-controller" ], - "summary": "Download server certificate using file path defined in device.connectivity properties (downloadServerCertificate)", - "description": "Download server certificate.", - "operationId": "downloadServerCertificate", - "parameters": [ - { - "name": "protocol", - "in": "path", - "description": "A string value representing the device connectivity protocol. Possible values: 'mqtt', 'mqtts', 'http', 'https', 'coap', 'coaps'", - "required": true, - "schema": { - "type": "string" + "summary": "Update device credentials (updateDeviceCredentials)", + "description": "During device creation, platform generates random 'ACCESS_TOKEN' credentials. \" +\nUse this method to update the device credentials. First use 'getDeviceCredentialsByDeviceId' to get the credentials id and value.\nThen use current method to update the credentials type and value. It is not possible to create multiple device credentials for the same device.\nThe structure of device credentials id and value is simple for the 'ACCESS_TOKEN' but is much more complex for the 'MQTT_BASIC' or 'LWM2M_CREDENTIALS'.\nYou may find the example of device with different type of credentials below: \n\n- Credentials type: **\"Access token\"** with **device ID** and with **device ID** below: \n\n```json\n{\n \"id\": {\n \"id\":\"c886a090-168d-11ee-87c9-6f157dbc816a\"\n },\n \"deviceId\": {\n \"id\":\"c5fb3ac0-168d-11ee-87c9-6f157dbc816a\",\n \"entityType\":\"DEVICE\"\n },\n \"credentialsType\": \"ACCESS_TOKEN\",\n \"credentialsId\": \"6hmxew8pmmzng4e3une4\"\n}\n```\n\n- Credentials type: **\"X509\"** with **device profile ID** below: \n\nNote: **credentialsId** - format **Sha3Hash**, **certificateValue** - format **PEM** (with \"--BEGIN CERTIFICATE----\" and -\"----END CERTIFICATE-\").\n\n```json\n{\n \"id\": {\n \"id\":\"309bd9c0-14f4-11ee-9fc9-d9b7463abb63\"\n },\n \"deviceId\": {\n \"id\":\"3092b200-14f4-11ee-9fc9-d9b7463abb63\",\n \"entityType\":\"DEVICE\"\n },\n \"credentialsType\": \"X509_CERTIFICATE\",\n \"credentialsId\": \"6b8adb49015500e51a527acd332b51684ab9b49b4ade03a9582a44c455e2e9b6\",\n \"credentialsValue\": \"-----BEGIN CERTIFICATE----- MIICMTCCAdegAwIBAgIUUEKxS9hTz4l+oLUMF0LV6TC/gCIwCgYIKoZIzj0EAwIwbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGluZ3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlUHJvZmlsZUNlcnRAWDUwOVByb3Zpc2lvblN0cmF0ZWd5MB4XDTIzMDMyOTE0NTczNloXDTI0MDMyODE0NTczNlowbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGluZ3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlUHJvZmlsZUNlcnRAWDUwOVByb3Zpc2lvblN0cmF0ZWd5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECMlWO72krDoUL9FQjUmSCetkhaEGJUfQkdSfkLSNa0GyAEIMbfmzI4zITeapunu4rGet3EMyLydQzuQanBicp6NTMFEwHQYDVR0OBBYEFHpZ78tPnztNii4Da/yCw6mhEIL3MB8GA1UdIwQYMBaAFHpZ78tPnztNii4Da/yCw6mhEIL3MA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgJ7qyMFqNcwSYkH6o+UlQXzLWfwZbNjVk+aR7foAZNGsCIQDsd7v3WQIGHiArfZeDs1DLEDuV/2h6L+ZNoGNhEKL+1A== -----END CERTIFICATE-----\"\n}\n```\n\n- Credentials type: **\"MQTT_BASIC\"** with **device profile ID** below: \n\n```json\n{\n \"id\": {\n \"id\":\"d877ffb0-14f5-11ee-9fc9-d9b7463abb63\"\n },\n \"deviceId\": {\n \"id\":\"d875dcd0-14f5-11ee-9fc9-d9b7463abb63\",\n \"entityType\":\"DEVICE\"\n },\n \"credentialsType\": \"MQTT_BASIC\",\n \"credentialsValue\": \"{\\\"clientId\\\":\\\"juy03yv4owqxcmqhqtvk\\\",\\\"userName\\\":\\\"ov19fxca0cyjn7lm7w7u\\\",\\\"password\\\":\\\"twy94he114dfi9usyk1o\\\"}\"\n}\n```\n\n- You may find the example of **LwM2M** device and **RPK** credentials below: \n\nNote: LwM2M device - only existing device profile ID (Transport configuration -> Transport type: \"LWM2M\".\n\n```json\n{\n \"id\": {\n \"id\":\"e238d4d0-1689-11ee-98c6-1713c1be5a8e\"\n },\n \"deviceId\": {\n \"id\":\"e232e160-1689-11ee-98c6-1713c1be5a8e\",\n \"entityType\":\"DEVICE\"\n },\n \"credentialsType\": \"LWM2M_CREDENTIALS\",\n \"credentialsId\": \"LwRpk00000000\",\n \"credentialsValue\":\n \"{\\\"client\\\":{ \\\"endpoint\\\":\\\"LwRpk00000000\\\", \\\"securityConfigClientMode\\\":\\\"RPK\\\", \\\"key\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEdvBZZ2vQRK9wgDhctj6B1c7bxR3Z0wYg1+YdoYFnVUKWb+rIfTTyYK9tmQJx5Vlb5fxdLnVv1RJOPiwsLIQbAA==\\\" }, \\\"bootstrap\\\":{ \\\"bootstrapServer\\\":{ \\\"securityMode\\\":\\\"RPK\\\", \\\"clientPublicKeyOrId\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\\\", \\\"clientSecretKey\\\":\\\"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgd9GAx7yZW37autew5KZykn4IgRpge/tZSjnudnZJnMahRANCAARQQHE2X9Fxgk2byaT3ULJVeggmJE5gOVdxJKorp7lsMfA5bhmI3aU2ddqXIXQnHDwxsDK2cMwRFfICNrlUQx5V\\\"}, \\\"lwm2mServer\\\":{ \\\"securityMode\\\":\\\"RPK\\\", \\\"clientPublicKeyOrId\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\\\", \\\"clientSecretKey\\\":\\\"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgd9GAx7yZW37autew5KZykn4IgRpge/tZSjnudnZJnMahRANCAARQQHE2X9Fxgk2byaT3ULJVeggmJE5gOVdxJKorp7lsMfA5bhmI3aU2ddqXIXQnHDwxsDK2cMwRFfICNrlUQx5V\\\"}} }\"\n}\n```\n\nUpdate to real value:\n - 'id' (this is id of Device Credentials -> \"Get Device Credentials (getDeviceCredentialsByDeviceId)\",\n - 'deviceId.id' (this is id of Device).\nRemove 'tenantId' and optionally 'customerId' from the request body example (below) to create new Device entity.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "updateDeviceCredentials", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceCredentials" + } } - } - ], + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { - "application/octet-stream": { + "application/json": { "schema": { - "type": "string", - "format": "binary" + "$ref": "#/components/schemas/DeviceCredentials" } } } @@ -24064,7 +24211,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -24168,14 +24315,14 @@ ] } }, - "/api/customer/device/{deviceId}": { - "delete": { + "/api/device/info/{deviceId}": { + "get": { "tags": [ "device-controller" ], - "summary": "Unassign device from customer (unassignDeviceFromCustomer)", - "description": "Clears assignment of the device to customer. Customer will not be able to query device afterwards.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "unassignDeviceFromCustomer", + "summary": "Get Device Info (getDeviceInfoById)", + "description": "Fetch the Device Info object based on the provided Device Id. If the user has the authority of 'Tenant Administrator', the server checks that the device is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the device is assigned to the same customer. Device Info is an extension of the default Device object that contains information about the assigned customer name and device profile name. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getDeviceInfoById", "parameters": [ { "name": "deviceId", @@ -24193,7 +24340,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Device" + "$ref": "#/components/schemas/DeviceInfo" } } } @@ -24314,41 +24461,24 @@ ] } }, - "/api/customer/device/{deviceName}/claim": { - "post": { + "/api/device/types": { + "get": { "tags": [ "device-controller" ], - "summary": "Claim device (claimDevice)", - "description": "Claiming makes it possible to assign a device to the specific customer using device/server side claiming data (in the form of secret key).To make this happen you have to provide unique device name and optional claiming data (it is needed only for device-side claiming).Once device is claimed, the customer becomes its owner and customer users may access device data as well as control the device. \nIn order to enable claiming devices feature a system parameter security.claim.allowClaimingByDefault should be set to true, otherwise a server-side claimingAllowed attribute with the value true is obligatory for provisioned devices. \nSee official documentation for more details regarding claiming.\n\nAvailable for users with 'CUSTOMER_USER' authority.", - "operationId": "claimDevice", - "parameters": [ - { - "name": "deviceName", - "in": "path", - "description": "Unique name of the device which is going to be claimed", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ClaimRequest" - } - } - } - }, + "summary": "Get Device Types (getDeviceTypes)", + "description": "Deprecated. See 'getDeviceProfileNames' API from Device Profile Controller instead.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getDeviceTypes", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "string" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntitySubtype" + } } } } @@ -24365,7 +24495,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -24459,6 +24589,7 @@ } } }, + "deprecated": true, "security": [ { "HttpLoginForm": [] @@ -24467,19 +24598,21 @@ "ApiKeyForm": [] } ] - }, - "delete": { + } + }, + "/api/device/{deviceId}": { + "get": { "tags": [ "device-controller" ], - "summary": "Reclaim device (reClaimDevice)", - "description": "Reclaiming means the device will be unassigned from the customer and the device will be available for claiming again.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "reClaimDevice", + "summary": "Get Device (getDeviceById)", + "description": "Fetch the Device object based on the provided Device Id. If the user has the authority of 'TENANT_ADMIN', the server checks that the device is owned by the same tenant. If the user has the authority of 'CUSTOMER_USER', the server checks that the device is assigned to the same customer.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getDeviceById", "parameters": [ { - "name": "deviceName", + "name": "deviceId", "in": "path", - "description": "Unique name of the device which is going to be reclaimed", + "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" @@ -24492,7 +24625,7 @@ "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/Device" } } } @@ -24611,16 +24744,14 @@ "ApiKeyForm": [] } ] - } - }, - "/api/customer/public/device/{deviceId}": { - "post": { + }, + "delete": { "tags": [ "device-controller" ], - "summary": "Make device publicly available (assignDeviceToPublicCustomer)", - "description": "Device will be available for non-authorized (not logged-in) users. This is useful to create dashboards that you plan to share/embed on a publicly available website. However, users that are logged-in and belong to different tenant will not be able to access the device.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "assignDeviceToPublicCustomer", + "summary": "Delete device (deleteDevice)", + "description": "Deletes the device, it's credentials and all the relations (from and to the device). Referencing non-existing device Id will cause an error.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "deleteDevice", "parameters": [ { "name": "deviceId", @@ -24634,14 +24765,7 @@ ], "responses": { "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Device" - } - } - } + "description": "OK" }, "400": { "description": "Bad Request", @@ -24655,7 +24779,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -24759,24 +24883,15 @@ ] } }, - "/api/customer/{customerId}/device/{deviceId}": { - "post": { + "/api/device/{deviceId}/credentials": { + "get": { "tags": [ "device-controller" ], - "summary": "Assign device to customer (assignDeviceToCustomer)", - "description": "Creates assignment of the device to customer. Customer will be able to query device afterwards.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "assignDeviceToCustomer", + "summary": "Get Device Credentials (getDeviceCredentialsByDeviceId)", + "description": "If during device creation there wasn't specified any credentials, platform generates random 'ACCESS_TOKEN' credentials.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getDeviceCredentialsByDeviceId", "parameters": [ - { - "name": "customerId", - "in": "path", - "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, { "name": "deviceId", "in": "path", @@ -24793,7 +24908,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Device" + "$ref": "#/components/schemas/DeviceCredentials" } } } @@ -24810,7 +24925,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -24914,107 +25029,25 @@ ] } }, - "/api/customer/{customerId}/deviceInfos": { + "/api/devices": { "get": { "tags": [ "device-controller" ], - "summary": "Get Customer Device Infos (getCustomerDeviceInfos)", - "description": "Returns a page of devices info objects assigned to customer. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. Device Info is an extension of the default Device object that contains information about the assigned customer name and device profile name. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getCustomerDeviceInfos", + "summary": "Get Devices By Ids (getDevicesByIds)", + "description": "Requested devices must be owned by tenant or assigned to customer which user is performing the request. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getDevicesByIds", "parameters": [ { - "name": "customerId", - "in": "path", - "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", + "name": "deviceIds", "in": "query", - "description": "Sequence number of page starting from 0", + "description": "A list of devices ids, separated by comma ','", "required": true, "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "type", - "in": "query", - "description": "Device type as the name of the device profile", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "deviceProfileId", - "in": "query", - "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "active", - "in": "query", - "description": "A boolean value representing the device active flag.", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'substring' filter based on the device name.", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string", - "enum": [ - "createdTime", - "name", - "deviceProfileName", - "label", - "customerTitle" - ] - } - }, - { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] + "type": "array", + "items": { + "type": "string" + } } } ], @@ -25024,7 +25057,10 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataDeviceInfo" + "type": "array", + "items": { + "$ref": "#/components/schemas/Device" + } } } } @@ -25143,101 +25179,34 @@ "ApiKeyForm": [] } ] - } - }, - "/api/customer/{customerId}/devices": { - "get": { + }, + "post": { "tags": [ "device-controller" ], - "summary": "Get Customer Devices (getCustomerDevices)", - "description": "Returns a page of devices objects assigned to customer. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getCustomerDevices", - "parameters": [ - { - "name": "customerId", - "in": "path", - "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "type", - "in": "query", - "description": "Device type as the name of the device profile", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'substring' filter based on the device name.", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string", - "enum": [ - "createdTime", - "name", - "deviceProfileName", - "label", - "customerTitle" - ] + "summary": "Find related devices (findDevicesByQuery)", + "description": "Returns all devices that are related to the specific entity. The entity id, relation type, device types, depth of the search, and other query parameters defined using complex 'DeviceSearchQuery' object. See 'Model' tab of the Parameters for more info.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "findDevicesByQuery", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceSearchQuery" + } } }, - { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] - } - } - ], + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataDevice" + "type": "array", + "items": { + "$ref": "#/components/schemas/Device" + } } } } @@ -25254,7 +25223,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -25358,73 +25327,46 @@ ] } }, - "/api/device": { - "post": { + "/api/devices/count/{otaPackageType}/{deviceProfileId}": { + "get": { "tags": [ "device-controller" ], - "summary": "Create Or Update Device (saveDevice)", - "description": "Create or update the Device. When creating device, platform generates Device Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)). Device credentials are also generated if not provided in the 'accessToken' request parameter. The newly created device id will be present in the response. Specify existing Device id to update the device. Referencing non-existing device Id will cause 'Not Found' error.\n\nDevice name is unique in the scope of tenant. Use unique identifiers like MAC or IMEI for the device names and non-unique 'label' field for user-friendly visualization purposes.Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Device entity. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "saveDevice", + "summary": "Count devices by device profile (countByDeviceProfileAndEmptyOtaPackage)", + "description": "The platform gives an ability to load OTA (over-the-air) packages to devices. It can be done in two different ways: device scope or device profile scope.In the response you will find the number of devices with specified device profile, but without previously defined device scope OTA package. It can be useful when you want to define number of devices that will be affected with future OTA package\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "countByDeviceProfileAndEmptyOtaPackage", "parameters": [ { - "name": "accessToken", - "in": "query", - "description": "Optional value of the device credentials to be used during device creation. If omitted, access token will be auto-generated.", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "nameConflictPolicy", - "in": "query", - "description": "Optional value of name conflict policy. Possible values: FAIL or UNIQUIFY. If omitted, FAIL policy is applied. FAIL policy implies exception will be thrown if an entity with the same name already exists. UNIQUIFY policy appends a suffix to the entity name, if a name conflict occurs.", - "required": false, - "schema": { - "$ref": "#/components/schemas/NameConflictPolicy", - "default": "FAIL" - } - }, - { - "name": "uniquifySeparator", - "in": "query", - "description": "Optional value of name suffix separator used by UNIQUIFY policy. By default, underscore separator is used. For example, strategy is UNIQUIFY, separator is '-'; if a name conflict occurs for entity name 'test-name', created entity will have name like 'test-name-7fsh4f'.", - "required": false, + "name": "otaPackageType", + "in": "path", + "description": "OTA package type", + "required": true, "schema": { "type": "string", - "default": "_" + "enum": [ + "FIRMWARE", + "SOFTWARE" + ] } }, { - "name": "uniquifyStrategy", - "in": "query", - "description": "Optional value of uniquify strategy used by UNIQUIFY policy. Possible values: RANDOM or INCREMENTAL. By default, RANDOM strategy is used, which means random alphanumeric string will be added as a suffix to entity name. INCREMENTAL implies the first possible number starting from 1 will be added as a name suffix. For example, strategy is UNIQUIFY, uniquify strategy is INCREMENTAL; if a name conflict occurs for entity name 'test-name', created entity will have name like 'test-name-1.", - "required": false, + "name": "deviceProfileId", + "in": "path", + "description": "Device Profile Id. I.g. '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, "schema": { - "$ref": "#/components/schemas/UniquifyStrategy", - "default": "RANDOM" + "type": "string" } } ], - "requestBody": { - "description": "A JSON value representing the device.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Device" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Device" + "type": "integer", + "format": "int64" } } } @@ -25441,7 +25383,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -25545,56 +25487,34 @@ ] } }, - "/api/device-with-credentials": { + "/api/edge/{edgeId}/device/{deviceId}": { "post": { "tags": [ "device-controller" ], - "summary": "Create Device (saveDevice) with credentials ", - "description": "Create or update the Device. When creating device, platform generates Device Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)). Requires to provide the Device Credentials object as well as an existing device profile ID or use \"default\".\nYou may find the example of device with different type of credentials below: \n\n- Credentials type: **\"Access token\"** with **device profile ID** below: \n\n```json\n{\n \"device\": {\n \"name\":\"Name_DeviceWithCredantial_AccessToken\",\n \"label\":\"Label_DeviceWithCredantial_AccessToken\",\n \"deviceProfileId\":{\n \"id\":\"9d9588c0-06c9-11ee-b618-19be30fdeb60\",\n \"entityType\":\"DEVICE_PROFILE\"\n }\n },\n \"credentials\": {\n \"credentialsType\": \"ACCESS_TOKEN\",\n \"credentialsId\": \"6hmxew8pmmzng4e3une2\"\n }\n}\n```\n\n- Credentials type: **\"Access token\"** with **device profile default** below: \n\n```json\n{\n \"device\": {\n \"name\":\"Name_DeviceWithCredantial_AccessToken_Default\",\n \"label\":\"Label_DeviceWithCredantial_AccessToken_Default\",\n \"type\": \"default\"\n },\n \"credentials\": {\n \"credentialsType\": \"ACCESS_TOKEN\",\n \"credentialsId\": \"6hmxew8pmmzng4e3une3\"\n }\n}\n```\n\n- Credentials type: **\"X509\"** with **device profile ID** below: \n\nNote: **credentialsId** - format **Sha3Hash**, **certificateValue** - format **PEM** (with \"--BEGIN CERTIFICATE----\" and -\"----END CERTIFICATE-\").\n\n```json\n{\n \"device\": {\n \"name\":\"Name_DeviceWithCredantial_X509_Certificate\",\n \"label\":\"Label_DeviceWithCredantial_X509_Certificate\",\n \"deviceProfileId\":{\n \"id\":\"9d9588c0-06c9-11ee-b618-19be30fdeb60\",\n \"entityType\":\"DEVICE_PROFILE\"\n }\n },\n \"credentials\": {\n \"credentialsType\": \"X509_CERTIFICATE\",\n \"credentialsId\": \"84f5911765abba1f96bf4165604e9e90338fc6214081a8e623b6ff9669aedb27\",\n \"credentialsValue\": \"-----BEGIN CERTIFICATE----- MIICMTCCAdegAwIBAgIUI9dBuwN6pTtK6uZ03rkiCwV4wEYwCgYIKoZIzj0EAwIwbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGluZ3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlQ2VydGlmaWNhdGVAWDUwOVByb3Zpc2lvblN0cmF0ZWd5MB4XDTIzMDMyOTE0NTYxN1oXDTI0MDMyODE0NTYxN1owbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGluZ3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlQ2VydGlmaWNhdGVAWDUwOVByb3Zpc2lvblN0cmF0ZWd5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9Zo791qKQiGNBm11r4ZGxh+w+ossZL3xc46ufq5QckQHP7zkD2XDAcmP5GvdkM1sBFN9AWaCkQfNnWmfERsOOKNTMFEwHQYDVR0OBBYEFFFc5uyCyglQoZiKhzXzMcQ3BKORMB8GA1UdIwQYMBaAFFFc5uyCyglQoZiKhzXzMcQ3BKORMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIhANbA9CuhoOifZMMmqkpuld+65CR+ItKdXeRAhLMZuccuAiB0FSQB34zMutXrZj1g8Gl5OkE7YryFHbei1z0SveHR8g== -----END CERTIFICATE-----\"\n }\n}\n```\n\n- Credentials type: **\"MQTT_BASIC\"** with **device profile ID** below: \n\n```json\n{\n \"device\": {\n \"name\":\"Name_DeviceWithCredantial_MQTT_Basic\",\n \"label\":\"Label_DeviceWithCredantial_MQTT_Basic\",\n \"deviceProfileId\":{\n \"id\":\"9d9588c0-06c9-11ee-b618-19be30fdeb60\",\n \"entityType\":\"DEVICE_PROFILE\"\n }\n },\n \"credentials\": {\n \"credentialsType\": \"MQTT_BASIC\",\n \"credentialsValue\": \"{\\\"clientId\\\":\\\"5euh5nzm34bjjh1efmlt\\\",\\\"userName\\\":\\\"onasd1lgwasmjl7v2v7h\\\",\\\"password\\\":\\\"b9xtm4ny8kt9zewaga5o\\\"}\"\n }\n}\n```\n\n- You may find the example of **LwM2M** device and **RPK** credentials below: \n\nNote: LwM2M device - only existing device profile ID (Transport configuration -\u003E Transport type: \"LWM2M\".\n\n```json\n{\n \"device\": {\n \"name\":\"Name_LwRpk00000000\",\n \"label\":\"Label_LwRpk00000000\",\n \"deviceProfileId\":{\n \"id\":\"a660bd50-10ef-11ee-8737-b5634e73c779\",\n \"entityType\":\"DEVICE_PROFILE\"\n }\n },\n \"credentials\": {\n \"credentialsType\": \"LWM2M_CREDENTIALS\",\n \"credentialsId\": \"LwRpk00000000\",\n \"credentialsValue\":\n \"{\\\"client\\\":{ \\\"endpoint\\\":\\\"LwRpk00000000\\\", \\\"securityConfigClientMode\\\":\\\"RPK\\\", \\\"key\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\\\" }, \\\"bootstrap\\\":{ \\\"bootstrapServer\\\":{ \\\"securityMode\\\":\\\"RPK\\\", \\\"clientPublicKeyOrId\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\\\", \\\"clientSecretKey\\\":\\\"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgd9GAx7yZW37autew5KZykn4IgRpge/tZSjnudnZJnMahRANCAARQQHE2X9Fxgk2byaT3ULJVeggmJE5gOVdxJKorp7lsMfA5bhmI3aU2ddqXIXQnHDwxsDK2cMwRFfICNrlUQx5V\\\"}, \\\"lwm2mServer\\\":{ \\\"securityMode\\\":\\\"RPK\\\", \\\"clientPublicKeyOrId\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\\\", \\\"clientSecretKey\\\":\\\"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgd9GAx7yZW37autew5KZykn4IgRpge/tZSjnudnZJnMahRANCAARQQHE2X9Fxgk2byaT3ULJVeggmJE5gOVdxJKorp7lsMfA5bhmI3aU2ddqXIXQnHDwxsDK2cMwRFfICNrlUQx5V\\\"}} }\"\n }\n}\n```\n\nRemove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Device entity. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "saveDeviceWithCredentials", + "summary": "Assign device to edge (assignDeviceToEdge)", + "description": "Creates assignment of an existing device to an instance of The Edge. Assignment works in async way - first, notification event pushed to edge service queue on platform. Second, remote edge service will receive a copy of assignment device (Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform). Third, once device will be delivered to edge service, it's going to be available for usage on remote edge instance.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "assignDeviceToEdge", "parameters": [ { - "name": "nameConflictPolicy", - "in": "query", - "description": "Optional value of name conflict policy. Possible values: FAIL or UNIQUIFY. If omitted, FAIL policy is applied. FAIL policy implies exception will be thrown if an entity with the same name already exists. UNIQUIFY policy appends a suffix to the entity name, if a name conflict occurs.", - "required": false, - "schema": { - "$ref": "#/components/schemas/NameConflictPolicy", - "default": "FAIL" - } - }, - { - "name": "uniquifySeparator", - "in": "query", - "description": "Optional value of name suffix separator used by UNIQUIFY policy. By default, underscore separator is used. For example, strategy is UNIQUIFY, separator is '-'; if a name conflict occurs for entity name 'test-name', created entity will have name like 'test-name-7fsh4f'.", - "required": false, + "name": "edgeId", + "in": "path", + "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, "schema": { - "type": "string", - "default": "_" + "type": "string" } }, { - "name": "uniquifyStrategy", - "in": "query", - "description": "Optional value of uniquify strategy used by UNIQUIFY policy. Possible values: RANDOM or INCREMENTAL. By default, RANDOM strategy is used, which means random alphanumeric string will be added as a suffix to entity name. INCREMENTAL implies the first possible number starting from 1 will be added as a name suffix. For example, strategy is UNIQUIFY, uniquify strategy is INCREMENTAL; if a name conflict occurs for entity name 'test-name', created entity will have name like 'test-name-1.", - "required": false, + "name": "deviceId", + "in": "path", + "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, "schema": { - "$ref": "#/components/schemas/UniquifyStrategy", - "default": "RANDOM" + "type": "string" } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SaveDeviceWithCredentialsRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", @@ -25720,33 +25640,41 @@ "ApiKeyForm": [] } ] - } - }, - "/api/device/bulk_import": { - "post": { + }, + "delete": { "tags": [ "device-controller" ], - "summary": "Import the bulk of devices (processDevicesBulkImport)", - "description": "There's an ability to import the bulk of devices using the only .csv file.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "processDevicesBulkImport", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BulkImportRequest" - } + "summary": "Unassign device from edge (unassignDeviceFromEdge)", + "description": "Clears assignment of the device to the edge. Unassignment works in async way - first, 'unassign' notification event pushed to edge queue on platform. Second, remote edge service will receive an 'unassign' command to remove device (Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform). Third, once 'unassign' command will be delivered to edge service, it's going to remove device locally.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "unassignDeviceFromEdge", + "parameters": [ + { + "name": "edgeId", + "in": "path", + "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" } }, - "required": true - }, + { + "name": "deviceId", + "in": "path", + "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BulkImportResultDevice" + "$ref": "#/components/schemas/Device" } } } @@ -25763,7 +25691,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -25867,31 +25795,137 @@ ] } }, - "/api/device/credentials": { - "post": { + "/api/edge/{edgeId}/devices": { + "get": { "tags": [ "device-controller" ], - "summary": "Update device credentials (updateDeviceCredentials)", - "description": "During device creation, platform generates random 'ACCESS_TOKEN' credentials. \" +\nUse this method to update the device credentials. First use 'getDeviceCredentialsByDeviceId' to get the credentials id and value.\nThen use current method to update the credentials type and value. It is not possible to create multiple device credentials for the same device.\nThe structure of device credentials id and value is simple for the 'ACCESS_TOKEN' but is much more complex for the 'MQTT_BASIC' or 'LWM2M_CREDENTIALS'.\nYou may find the example of device with different type of credentials below: \n\n- Credentials type: **\"Access token\"** with **device ID** and with **device ID** below: \n\n```json\n{\n \"id\": {\n \"id\":\"c886a090-168d-11ee-87c9-6f157dbc816a\"\n },\n \"deviceId\": {\n \"id\":\"c5fb3ac0-168d-11ee-87c9-6f157dbc816a\",\n \"entityType\":\"DEVICE\"\n },\n \"credentialsType\": \"ACCESS_TOKEN\",\n \"credentialsId\": \"6hmxew8pmmzng4e3une4\"\n}\n```\n\n- Credentials type: **\"X509\"** with **device profile ID** below: \n\nNote: **credentialsId** - format **Sha3Hash**, **certificateValue** - format **PEM** (with \"--BEGIN CERTIFICATE----\" and -\"----END CERTIFICATE-\").\n\n```json\n{\n \"id\": {\n \"id\":\"309bd9c0-14f4-11ee-9fc9-d9b7463abb63\"\n },\n \"deviceId\": {\n \"id\":\"3092b200-14f4-11ee-9fc9-d9b7463abb63\",\n \"entityType\":\"DEVICE\"\n },\n \"credentialsType\": \"X509_CERTIFICATE\",\n \"credentialsId\": \"6b8adb49015500e51a527acd332b51684ab9b49b4ade03a9582a44c455e2e9b6\",\n \"credentialsValue\": \"-----BEGIN CERTIFICATE----- MIICMTCCAdegAwIBAgIUUEKxS9hTz4l+oLUMF0LV6TC/gCIwCgYIKoZIzj0EAwIwbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGluZ3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlUHJvZmlsZUNlcnRAWDUwOVByb3Zpc2lvblN0cmF0ZWd5MB4XDTIzMDMyOTE0NTczNloXDTI0MDMyODE0NTczNlowbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGluZ3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlUHJvZmlsZUNlcnRAWDUwOVByb3Zpc2lvblN0cmF0ZWd5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECMlWO72krDoUL9FQjUmSCetkhaEGJUfQkdSfkLSNa0GyAEIMbfmzI4zITeapunu4rGet3EMyLydQzuQanBicp6NTMFEwHQYDVR0OBBYEFHpZ78tPnztNii4Da/yCw6mhEIL3MB8GA1UdIwQYMBaAFHpZ78tPnztNii4Da/yCw6mhEIL3MA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgJ7qyMFqNcwSYkH6o+UlQXzLWfwZbNjVk+aR7foAZNGsCIQDsd7v3WQIGHiArfZeDs1DLEDuV/2h6L+ZNoGNhEKL+1A== -----END CERTIFICATE-----\"\n}\n```\n\n- Credentials type: **\"MQTT_BASIC\"** with **device profile ID** below: \n\n```json\n{\n \"id\": {\n \"id\":\"d877ffb0-14f5-11ee-9fc9-d9b7463abb63\"\n },\n \"deviceId\": {\n \"id\":\"d875dcd0-14f5-11ee-9fc9-d9b7463abb63\",\n \"entityType\":\"DEVICE\"\n },\n \"credentialsType\": \"MQTT_BASIC\",\n \"credentialsValue\": \"{\\\"clientId\\\":\\\"juy03yv4owqxcmqhqtvk\\\",\\\"userName\\\":\\\"ov19fxca0cyjn7lm7w7u\\\",\\\"password\\\":\\\"twy94he114dfi9usyk1o\\\"}\"\n}\n```\n\n- You may find the example of **LwM2M** device and **RPK** credentials below: \n\nNote: LwM2M device - only existing device profile ID (Transport configuration -\u003E Transport type: \"LWM2M\".\n\n```json\n{\n \"id\": {\n \"id\":\"e238d4d0-1689-11ee-98c6-1713c1be5a8e\"\n },\n \"deviceId\": {\n \"id\":\"e232e160-1689-11ee-98c6-1713c1be5a8e\",\n \"entityType\":\"DEVICE\"\n },\n \"credentialsType\": \"LWM2M_CREDENTIALS\",\n \"credentialsId\": \"LwRpk00000000\",\n \"credentialsValue\":\n \"{\\\"client\\\":{ \\\"endpoint\\\":\\\"LwRpk00000000\\\", \\\"securityConfigClientMode\\\":\\\"RPK\\\", \\\"key\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEdvBZZ2vQRK9wgDhctj6B1c7bxR3Z0wYg1+YdoYFnVUKWb+rIfTTyYK9tmQJx5Vlb5fxdLnVv1RJOPiwsLIQbAA==\\\" }, \\\"bootstrap\\\":{ \\\"bootstrapServer\\\":{ \\\"securityMode\\\":\\\"RPK\\\", \\\"clientPublicKeyOrId\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\\\", \\\"clientSecretKey\\\":\\\"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgd9GAx7yZW37autew5KZykn4IgRpge/tZSjnudnZJnMahRANCAARQQHE2X9Fxgk2byaT3ULJVeggmJE5gOVdxJKorp7lsMfA5bhmI3aU2ddqXIXQnHDwxsDK2cMwRFfICNrlUQx5V\\\"}, \\\"lwm2mServer\\\":{ \\\"securityMode\\\":\\\"RPK\\\", \\\"clientPublicKeyOrId\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\\\", \\\"clientSecretKey\\\":\\\"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgd9GAx7yZW37autew5KZykn4IgRpge/tZSjnudnZJnMahRANCAARQQHE2X9Fxgk2byaT3ULJVeggmJE5gOVdxJKorp7lsMfA5bhmI3aU2ddqXIXQnHDwxsDK2cMwRFfICNrlUQx5V\\\"}} }\"\n}\n```\n\nUpdate to real value:\n - 'id' (this is id of Device Credentials -\u003E \"Get Device Credentials (getDeviceCredentialsByDeviceId)\",\n - 'deviceId.id' (this is id of Device).\nRemove 'tenantId' and optionally 'customerId' from the request body example (below) to create new Device entity.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "updateDeviceCredentials", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeviceCredentials" - } + "summary": "Get devices assigned to edge (getEdgeDevices)", + "description": "Returns a page of devices assigned to edge. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getEdgeDevices", + "parameters": [ + { + "name": "edgeId", + "in": "path", + "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" } }, - "required": true - }, + { + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "type", + "in": "query", + "description": "Device type as the name of the device profile", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "deviceProfileId", + "in": "query", + "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "active", + "in": "query", + "description": "A boolean value representing the device active flag.", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'substring' filter based on the device name.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string", + "enum": [ + "createdTime", + "name", + "deviceProfileName", + "label", + "customerTitle" + ] + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ASC", + "DESC" + ] + } + }, + { + "name": "startTime", + "in": "query", + "description": "Timestamp. Devices with creation time before it won't be queried", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "endTime", + "in": "query", + "description": "Timestamp. Devices with creation time after it won't be queried", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeviceCredentials" + "$ref": "#/components/schemas/PageDataDeviceInfo" } } } @@ -25908,7 +25942,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -26012,19 +26046,19 @@ ] } }, - "/api/device/info/{deviceId}": { + "/api/tenant/device": { "get": { "tags": [ "device-controller" ], - "summary": "Get Device Info (getDeviceInfoById)", - "description": "Fetch the Device Info object based on the provided Device Id. If the user has the authority of 'Tenant Administrator', the server checks that the device is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the device is assigned to the same customer. Device Info is an extension of the default Device object that contains information about the assigned customer name and device profile name. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getDeviceInfoById", + "summary": "Get Tenant Device (getTenantDeviceByName)", + "description": "Requested device must be owned by tenant that the user belongs to. Device name is an unique property of device. So it can be used to identify the device.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getTenantDeviceByName", "parameters": [ { - "name": "deviceId", - "in": "path", - "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "name": "deviceName", + "in": "query", + "description": "A string value representing the Device name.", "required": true, "schema": { "type": "string" @@ -26037,7 +26071,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeviceInfo" + "$ref": "#/components/schemas/Device" } } } @@ -26158,24 +26192,108 @@ ] } }, - "/api/device/types": { + "/api/tenant/deviceInfos": { "get": { "tags": [ "device-controller" ], - "summary": "Get Device Types (getDeviceTypes)", - "description": "Deprecated. See 'getDeviceProfileNames' API from Device Profile Controller instead.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getDeviceTypes", + "summary": "Get Tenant Device Infos (getTenantDeviceInfos)", + "description": "Returns a page of devices info objects owned by tenant. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. Device Info is an extension of the default Device object that contains information about the assigned customer name and device profile name. \n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getTenantDeviceInfos", + "parameters": [ + { + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "type", + "in": "query", + "description": "Device type as the name of the device profile", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "deviceProfileId", + "in": "query", + "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "active", + "in": "query", + "description": "A boolean value representing the device active flag.", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'substring' filter based on the device name.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string", + "enum": [ + "createdTime", + "name", + "deviceProfileName", + "label", + "customerTitle" + ] + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ASC", + "DESC" + ] + } + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntitySubtype" - } + "$ref": "#/components/schemas/PageDataDeviceInfo" } } } @@ -26286,7 +26404,6 @@ } } }, - "deprecated": true, "security": [ { "HttpLoginForm": [] @@ -26297,23 +26414,81 @@ ] } }, - "/api/device/{deviceId}": { + "/api/tenant/devices": { "get": { "tags": [ "device-controller" ], - "summary": "Get Device (getDeviceById)", - "description": "Fetch the Device object based on the provided Device Id. If the user has the authority of 'TENANT_ADMIN', the server checks that the device is owned by the same tenant. If the user has the authority of 'CUSTOMER_USER', the server checks that the device is assigned to the same customer.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getDeviceById", + "summary": "Get Tenant Devices (getTenantDevices)", + "description": "Returns a page of devices owned by tenant. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getTenantDevices", "parameters": [ { - "name": "deviceId", - "in": "path", - "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "type", + "in": "query", + "description": "Device type as the name of the device profile", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'substring' filter based on the device name.", + "required": false, "schema": { "type": "string" } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string", + "enum": [ + "createdTime", + "name", + "deviceProfileName", + "label", + "customerTitle" + ] + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ASC", + "DESC" + ] + } } ], "responses": { @@ -26322,7 +26497,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Device" + "$ref": "#/components/schemas/PageDataDevice" } } } @@ -26441,15 +26616,26 @@ "ApiKeyForm": [] } ] - }, - "delete": { + } + }, + "/api/tenant/{tenantId}/device/{deviceId}": { + "post": { "tags": [ "device-controller" ], - "summary": "Delete device (deleteDevice)", - "description": "Deletes the device, it's credentials and all the relations (from and to the device). Referencing non-existing device Id will cause an error.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "deleteDevice", + "summary": "Assign device to tenant (assignDeviceToTenant)", + "description": "Creates assignment of the device to tenant. Thereafter tenant will be able to reassign the device to a customer.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "assignDeviceToTenant", "parameters": [ + { + "name": "tenantId", + "in": "path", + "description": "A string value representing the tenant id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, { "name": "deviceId", "in": "path", @@ -26462,7 +26648,14 @@ ], "responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Device" + } + } + } }, "400": { "description": "Bad Request", @@ -26476,7 +26669,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -26580,32 +26773,31 @@ ] } }, - "/api/device/{deviceId}/credentials": { - "get": { + "/api/deviceProfile": { + "post": { "tags": [ - "device-controller" + "device-profile-controller" ], - "summary": "Get Device Credentials (getDeviceCredentialsByDeviceId)", - "description": "If during device creation there wasn't specified any credentials, platform generates random 'ACCESS_TOKEN' credentials.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getDeviceCredentialsByDeviceId", - "parameters": [ - { - "name": "deviceId", - "in": "path", - "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" + "summary": "Create Or Update Device Profile (saveDeviceProfile)", + "description": "Create or update the Device Profile. When creating device profile, platform generates device profile id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)). The newly created device profile id will be present in the response. Specify existing device profile id to update the device profile. Referencing non-existing device profile Id will cause 'Not Found' error. \n\nDevice profile name is unique in the scope of tenant. Only one 'default' device profile may exist in scope of tenant.\n\n# Device profile data definition\n\nDevice profile data object contains alarm rules configuration, device provision strategy and transport type configuration for device connectivity. Let's review some examples. First one is the default device profile data configuration and second one - the custom one. \n\n```json\n{\n \"alarms\":[\n ],\n \"configuration\":{\n \"type\":\"DEFAULT\"\n },\n \"provisionConfiguration\":{\n \"type\":\"DISABLED\",\n \"provisionDeviceSecret\":null\n },\n \"transportConfiguration\":{\n \"type\":\"DEFAULT\"\n }\n}\n```\n\n```json\n{\n \"alarms\":[\n {\n \"id\":\"2492b935-1226-59e9-8615-17d8978a4f93\",\n \"alarmType\":\"Temperature Alarm\",\n \"clearRule\":{\n \"schedule\":null,\n \"condition\":{\n \"spec\":{\n \"type\":\"SIMPLE\"\n },\n \"condition\":[\n {\n \"key\":{\n \"key\":\"temperature\",\n \"type\":\"TIME_SERIES\"\n },\n \"value\":null,\n \"predicate\":{\n \"type\":\"NUMERIC\",\n \"value\":{\n \"userValue\":null,\n \"defaultValue\":30.0,\n \"dynamicValue\":null\n },\n \"operation\":\"LESS\"\n },\n \"valueType\":\"NUMERIC\"\n }\n ]\n },\n \"dashboardId\":null,\n \"alarmDetails\":null\n },\n \"propagate\":false,\n \"createRules\":{\n \"MAJOR\":{\n \"schedule\":{\n \"type\":\"SPECIFIC_TIME\",\n \"endsOn\":64800000,\n \"startsOn\":43200000,\n \"timezone\":\"Europe/Kiev\",\n \"daysOfWeek\":[\n 1,\n 3,\n 5\n ]\n },\n \"condition\":{\n \"spec\":{\n \"type\":\"DURATION\",\n \"unit\":\"MINUTES\",\n \"predicate\":{\n \"userValue\":null,\n \"defaultValue\":30,\n \"dynamicValue\":null\n }\n },\n \"condition\":[\n {\n \"key\":{\n \"key\":\"temperature\",\n \"type\":\"TIME_SERIES\"\n },\n \"value\":null,\n \"predicate\":{\n \"type\":\"COMPLEX\",\n \"operation\":\"OR\",\n \"predicates\":[\n {\n \"type\":\"NUMERIC\",\n \"value\":{\n \"userValue\":null,\n \"defaultValue\":50.0,\n \"dynamicValue\":null\n },\n \"operation\":\"LESS_OR_EQUAL\"\n },\n {\n \"type\":\"NUMERIC\",\n \"value\":{\n \"userValue\":null,\n \"defaultValue\":30.0,\n \"dynamicValue\":null\n },\n \"operation\":\"GREATER\"\n }\n ]\n },\n \"valueType\":\"NUMERIC\"\n }\n ]\n },\n \"dashboardId\":null,\n \"alarmDetails\":null\n },\n \"WARNING\":{\n \"schedule\":{\n \"type\":\"CUSTOM\",\n \"items\":[\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":1\n },\n {\n \"endsOn\":64800000,\n \"enabled\":true,\n \"startsOn\":43200000,\n \"dayOfWeek\":2\n },\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":3\n },\n {\n \"endsOn\":57600000,\n \"enabled\":true,\n \"startsOn\":36000000,\n \"dayOfWeek\":4\n },\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":5\n },\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":6\n },\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":7\n }\n ],\n \"timezone\":\"Europe/Kiev\"\n },\n \"condition\":{\n \"spec\":{\n \"type\":\"REPEATING\",\n \"predicate\":{\n \"userValue\":null,\n \"defaultValue\":5,\n \"dynamicValue\":null\n }\n },\n \"condition\":[\n {\n \"key\":{\n \"key\":\"tempConstant\",\n \"type\":\"CONSTANT\"\n },\n \"value\":30,\n \"predicate\":{\n \"type\":\"NUMERIC\",\n \"value\":{\n \"userValue\":null,\n \"defaultValue\":0.0,\n \"dynamicValue\":{\n \"inherit\":false,\n \"sourceType\":\"CURRENT_DEVICE\",\n \"sourceAttribute\":\"tempThreshold\"\n }\n },\n \"operation\":\"EQUAL\"\n },\n \"valueType\":\"NUMERIC\"\n }\n ]\n },\n \"dashboardId\":null,\n \"alarmDetails\":null\n },\n \"CRITICAL\":{\n \"schedule\":null,\n \"condition\":{\n \"spec\":{\n \"type\":\"SIMPLE\"\n },\n \"condition\":[\n {\n \"key\":{\n \"key\":\"temperature\",\n \"type\":\"TIME_SERIES\"\n },\n \"value\":null,\n \"predicate\":{\n \"type\":\"NUMERIC\",\n \"value\":{\n \"userValue\":null,\n \"defaultValue\":50.0,\n \"dynamicValue\":null\n },\n \"operation\":\"GREATER\"\n },\n \"valueType\":\"NUMERIC\"\n }\n ]\n },\n \"dashboardId\":null,\n \"alarmDetails\":null\n }\n },\n \"propagateRelationTypes\":null\n }\n ],\n \"configuration\":{\n \"type\":\"DEFAULT\"\n },\n \"provisionConfiguration\":{\n \"type\":\"ALLOW_CREATE_NEW_DEVICES\",\n \"provisionDeviceSecret\":\"vaxb9hzqdbz3oqukvomg\"\n },\n \"transportConfiguration\":{\n \"type\":\"MQTT\",\n \"deviceTelemetryTopic\":\"v1/devices/me/telemetry\",\n \"deviceAttributesTopic\":\"v1/devices/me/attributes\",\n \"transportPayloadTypeConfiguration\":{\n \"transportPayloadType\":\"PROTOBUF\",\n \"deviceTelemetryProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage telemetry;\\n\\nmessage SensorDataReading {\\n\\n optional double temperature = 1;\\n optional double humidity = 2;\\n InnerObject innerObject = 3;\\n\\n message InnerObject {\\n optional string key1 = 1;\\n optional bool key2 = 2;\\n optional double key3 = 3;\\n optional int32 key4 = 4;\\n optional string key5 = 5;\\n }\\n}\",\n \"deviceAttributesProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage attributes;\\n\\nmessage SensorConfiguration {\\n optional string firmwareVersion = 1;\\n optional string serialNumber = 2;\\n}\",\n \"deviceRpcRequestProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage rpc;\\n\\nmessage RpcRequestMsg {\\n optional string method = 1;\\n optional int32 requestId = 2;\\n optional string params = 3;\\n}\",\n \"deviceRpcResponseProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage rpc;\\n\\nmessage RpcResponseMsg {\\n optional string payload = 1;\\n}\"\n }\n }\n}\n```\n\nLet's review some specific objects examples related to the device profile configuration:\n\n# Alarm Schedule\n\nAlarm Schedule JSON object represents the time interval during which the alarm rule is active. Note, \n\n```json\n\"schedule\": null\n```\n\nmeans alarm rule is active all the time. **'daysOfWeek'** field represents Monday as 1, Tuesday as 2 and so on. **'startsOn'** and **'endsOn'** fields represent hours in millis (e.g. 64800000 = 18:00 or 6pm). **'enabled'** flag specifies if item in a custom rule is active for specific day of the week:\n\n## Specific Time Schedule\n\n```json\n{\n \"schedule\":{\n \"type\":\"SPECIFIC_TIME\",\n \"endsOn\":64800000,\n \"startsOn\":43200000,\n \"timezone\":\"Europe/Kiev\",\n \"daysOfWeek\":[\n 1,\n 3,\n 5\n ]\n }\n}\n```\n\n## Custom Schedule\n\n```json\n{\n \"schedule\":{\n \"type\":\"CUSTOM\",\n \"items\":[\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":1\n },\n {\n \"endsOn\":64800000,\n \"enabled\":true,\n \"startsOn\":43200000,\n \"dayOfWeek\":2\n },\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":3\n },\n {\n \"endsOn\":57600000,\n \"enabled\":true,\n \"startsOn\":36000000,\n \"dayOfWeek\":4\n },\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":5\n },\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":6\n },\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":7\n }\n ],\n \"timezone\":\"Europe/Kiev\"\n }\n}\n```\n\n# Alarm condition type (**'spec'**)\n\nAlarm condition type can be either simple, duration, or repeating. For example, 5 times in a row or during 5 minutes.\n\nNote, **'userValue'** field is not used and reserved for future usage, **'dynamicValue'** is used for condition appliance by using the value of the **'sourceAttribute'** or else **'defaultValue'** is used (if **'sourceAttribute'** is absent).\n\n**'sourceType'** of the **'sourceAttribute'** can be: \n * 'CURRENT_DEVICE';\n * 'CURRENT_CUSTOMER';\n * 'CURRENT_TENANT'.\n\n**'sourceAttribute'** can be inherited from the owner if **'inherit'** is set to true (for CURRENT_DEVICE and CURRENT_CUSTOMER).\n\n## Repeating alarm condition\n\n```json\n{\n \"spec\":{\n \"type\":\"REPEATING\",\n \"predicate\":{\n \"userValue\":null,\n \"defaultValue\":5,\n \"dynamicValue\":{\n \"inherit\":true,\n \"sourceType\":\"CURRENT_DEVICE\",\n \"sourceAttribute\":\"tempAttr\"\n }\n }\n }\n}\n```\n\n## Duration alarm condition\n\n```json\n{\n \"spec\":{\n \"type\":\"DURATION\",\n \"unit\":\"MINUTES\",\n \"predicate\":{\n \"userValue\":null,\n \"defaultValue\":30,\n \"dynamicValue\":null\n }\n }\n}\n```\n\n**'unit'** can be: \n * 'SECONDS';\n * 'MINUTES';\n * 'HOURS';\n * 'DAYS'.\n\n# Key Filters\n\nKey filter objects are created under the **'condition'** array. They allow you to define complex logical expressions over entity field, attribute, latest time series value or constant. The filter is defined using 'key', 'valueType', 'value' (refers to the value of the 'CONSTANT' alarm filter key type) and 'predicate' objects. Let's review each object:\n\n## Alarm Filter Key\n\nFilter Key defines either entity field, attribute, telemetry or constant. It is a JSON object that consists the key name and type. The following filter key types are supported:\n * 'ATTRIBUTE' - used for attributes values;\n * 'TIME_SERIES' - used for time series values;\n * 'ENTITY_FIELD' - used for accessing entity fields like 'name', 'label', etc. The list of available fields depends on the entity type;\n * 'CONSTANT' - constant value specified.\n\nLet's review the example:\n\n```json\n{\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n}\n```\n\n## Value Type and Operations\n\nProvides a hint about the data type of the entity field that is defined in the filter key. The value type impacts the list of possible operations that you may use in the corresponding predicate. For example, you may use 'STARTS_WITH' or 'END_WITH', but you can't use 'GREATER_OR_EQUAL' for string values.The following filter value types and corresponding predicate operations are supported: \n\n * 'STRING' - used to filter any 'String' or 'JSON' values. Operations: EQUAL, NOT_EQUAL, STARTS_WITH, ENDS_WITH, CONTAINS, NOT_CONTAINS; \n * 'NUMERIC' - used for 'Long' and 'Double' values. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n * 'BOOLEAN' - used for boolean values. Operations: EQUAL, NOT_EQUAL;\n * 'DATE_TIME' - similar to numeric, transforms value to milliseconds since epoch. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n\n\n\n\n## Filter Predicate\n\nFilter Predicate defines the logical expression to evaluate. The list of available operations depends on the filter value type, see above. Platform supports 4 predicate types: 'STRING', 'NUMERIC', 'BOOLEAN' and 'COMPLEX'. The last one allows to combine multiple operations over one filter key.\n\nSimple predicate example to check 'value < 100': \n\n```json\n{\n \"operation\": \"LESS\",\n \"value\": {\n \"userValue\": null,\n \"defaultValue\": 100,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n}\n```\n\nComplex predicate example, to check 'value < 10 or value > 20': \n\n```json\n{\n \"type\": \"COMPLEX\",\n \"operation\": \"OR\",\n \"predicates\": [\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"userValue\": null,\n \"defaultValue\": 10,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"operation\": \"GREATER\",\n \"value\": {\n \"userValue\": null,\n \"defaultValue\": 20,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n ]\n}\n```\n\nMore complex predicate example, to check 'value < 10 or (value > 50 && value < 60)': \n\n```json\n{\n \"type\": \"COMPLEX\",\n \"operation\": \"OR\",\n \"predicates\": [\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"userValue\": null,\n \"defaultValue\": 10,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"type\": \"COMPLEX\",\n \"operation\": \"AND\",\n \"predicates\": [\n {\n \"operation\": \"GREATER\",\n \"value\": {\n \"userValue\": null,\n \"defaultValue\": 50,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"userValue\": null,\n \"defaultValue\": 60,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n ]\n }\n ]\n}\n```\n\nYou may also want to replace hardcoded values (for example, temperature > 20) with the more dynamic expression (for example, temperature > value of the tenant attribute with key 'temperatureThreshold'). It is possible to use 'dynamicValue' to define attribute of the tenant, customer or device. See example below:\n\n```json\n{\n \"operation\": \"GREATER\",\n \"value\": {\n \"userValue\": null,\n \"defaultValue\": 0,\n \"dynamicValue\": {\n \"inherit\": false,\n \"sourceType\": \"CURRENT_TENANT\",\n \"sourceAttribute\": \"temperatureThreshold\"\n }\n },\n \"type\": \"NUMERIC\"\n}\n```\n\nNote that you may use 'CURRENT_DEVICE', 'CURRENT_CUSTOMER' and 'CURRENT_TENANT' as a 'sourceType'. The 'defaultValue' is used when the attribute with such a name is not defined for the chosen source. The 'sourceAttribute' can be inherited from the owner of the specified 'sourceType' if 'inherit' is set to true.\n\n# Provision Configuration\n\nThere are 3 types of device provision configuration for the device profile: \n * 'DISABLED';\n * 'ALLOW_CREATE_NEW_DEVICES';\n * 'CHECK_PRE_PROVISIONED_DEVICES'.\n\nPlease refer to the [docs](https://thingsboard.io/docs/user-guide/device-provisioning/) for more details.\n\n# Transport Configuration\n\n5 transport configuration types are available:\n * 'DEFAULT';\n * 'MQTT';\n * 'LWM2M';\n * 'COAP';\n * 'SNMP'.\n\nDefault type supports basic MQTT, HTTP, CoAP and LwM2M transports. Please refer to the [docs](https://thingsboard.io/docs/user-guide/device-profiles/#transport-configuration) for more details about other types.\n\nSee another example of COAP transport configuration below:\n\n```json\n{\n \"type\":\"COAP\",\n \"clientSettings\":{\n \"edrxCycle\":null,\n \"powerMode\":\"DRX\",\n \"psmActivityTimer\":null,\n \"pagingTransmissionWindow\":null\n },\n \"coapDeviceTypeConfiguration\":{\n \"coapDeviceType\":\"DEFAULT\",\n \"transportPayloadTypeConfiguration\":{\n \"transportPayloadType\":\"JSON\"\n }\n }\n}\n```Remove 'id', 'tenantId' from the request body example (below) to create new Device Profile entity. \n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "saveDeviceProfile", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceProfile" + } } - } - ], + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeviceCredentials" + "$ref": "#/components/schemas/DeviceProfile" } } } @@ -26622,7 +26814,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -26726,25 +26918,22 @@ ] } }, - "/api/devices": { + "/api/deviceProfile/devices/keys/attributes": { "get": { "tags": [ - "device-controller" + "device-profile-controller" ], - "summary": "Get Devices By Ids (getDevicesByIds)", - "description": "Requested devices must be owned by tenant or assigned to customer which user is performing the request. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getDevicesByIds", + "summary": "Get attribute keys (getAttributesKeys)", + "description": "Get a set of unique attribute keys used by devices that belong to specified profile. If profile is not set returns a list of unique keys among all profiles. The call is used for auto-complete in the UI forms. The implementation limits the number of devices that participate in search to 100 as a trade of between accurate results and time-consuming queries. \n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getAttributesKeys", "parameters": [ { - "name": "deviceIds", + "name": "deviceProfileId", "in": "query", - "description": "A list of devices ids, separated by comma ','", - "required": true, + "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": false, "schema": { - "type": "array", - "items": { - "type": "string" - } + "type": "string" } } ], @@ -26756,7 +26945,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/Device" + "type": "string" } } } @@ -26876,181 +27065,22 @@ "ApiKeyForm": [] } ] - }, - "post": { - "tags": [ - "device-controller" - ], - "summary": "Find related devices (findDevicesByQuery)", - "description": "Returns all devices that are related to the specific entity. The entity id, relation type, device types, depth of the search, and other query parameters defined using complex 'DeviceSearchQuery' object. See 'Model' tab of the Parameters for more info.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "findDevicesByQuery", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeviceSearchQuery" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Device" - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-400": { - "summary": "Bad Request", - "value": { - "status": 400, - "message": "Invalid request body", - "errorCode": 31, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-401": { - "summary": "Unauthorized", - "value": { - "status": 401, - "message": "Authentication failed", - "errorCode": 10, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-403": { - "summary": "Forbidden", - "value": { - "status": 403, - "message": "You don't have permission to perform this operation!", - "errorCode": 20, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-404": { - "summary": "Not Found", - "value": { - "status": 404, - "message": "Requested item wasn't found!", - "errorCode": 32, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "429": { - "description": "Too Many Requests", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-429": { - "summary": "Too Many Requests", - "value": { - "status": 429, - "message": "Too many requests for current tenant!", - "errorCode": 33, - "timestamp": 1609459200000 - } - } - } - } - } - } - }, - "security": [ - { - "HttpLoginForm": [] - }, - { - "ApiKeyForm": [] - } - ] } }, - "/api/devices/count/{otaPackageType}/{deviceProfileId}": { + "/api/deviceProfile/devices/keys/timeseries": { "get": { "tags": [ - "device-controller" + "device-profile-controller" ], - "summary": "Count devices by device profile (countByDeviceProfileAndEmptyOtaPackage)", - "description": "The platform gives an ability to load OTA (over-the-air) packages to devices. It can be done in two different ways: device scope or device profile scope.In the response you will find the number of devices with specified device profile, but without previously defined device scope OTA package. It can be useful when you want to define number of devices that will be affected with future OTA package\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "countByDeviceProfileAndEmptyOtaPackage", + "summary": "Get time series keys (getDeviceProfileTimeseriesKeys)", + "description": "Get a set of unique time series keys used by devices that belong to specified profile. If profile is not set returns a list of unique keys among all profiles. The call is used for auto-complete in the UI forms. The implementation limits the number of devices that participate in search to 100 as a trade of between accurate results and time-consuming queries. \n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getDeviceProfileTimeseriesKeys", "parameters": [ - { - "name": "otaPackageType", - "in": "path", - "description": "OTA package type", - "required": true, - "schema": { - "type": "string", - "enum": [ - "FIRMWARE", - "SOFTWARE" - ] - } - }, { "name": "deviceProfileId", - "in": "path", - "description": "Device Profile Id. I.g. '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, + "in": "query", + "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": false, "schema": { "type": "string" } @@ -27062,8 +27092,10 @@ "content": { "application/json": { "schema": { - "type": "integer", - "format": "int64" + "type": "array", + "items": { + "type": "string" + } } } } @@ -27184,31 +27216,23 @@ ] } }, - "/api/edge/{edgeId}/device/{deviceId}": { - "post": { + "/api/deviceProfile/names": { + "get": { "tags": [ - "device-controller" + "device-profile-controller" ], - "summary": "Assign device to edge (assignDeviceToEdge)", - "description": "Creates assignment of an existing device to an instance of The Edge. Assignment works in async way - first, notification event pushed to edge service queue on platform. Second, remote edge service will receive a copy of assignment device (Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform). Third, once device will be delivered to edge service, it's going to be available for usage on remote edge instance.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "assignDeviceToEdge", + "summary": "Get Device Profile names (getDeviceProfileNames)", + "description": "Returns a set of unique device profile names owned by the tenant.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getDeviceProfileNames", "parameters": [ { - "name": "edgeId", - "in": "path", - "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "deviceId", - "in": "path", - "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, + "name": "activeOnly", + "in": "query", + "description": "Flag indicating whether to retrieve exclusively the names of device profiles that are referenced by tenant's devices.", + "required": false, "schema": { - "type": "string" + "type": "boolean", + "default": false } } ], @@ -27218,7 +27242,10 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Device" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityInfo" + } } } } @@ -27235,7 +27262,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -27337,31 +27364,33 @@ "ApiKeyForm": [] } ] - }, - "delete": { + } + }, + "/api/deviceProfile/{deviceProfileId}": { + "get": { "tags": [ - "device-controller" + "device-profile-controller" ], - "summary": "Unassign device from edge (unassignDeviceFromEdge)", - "description": "Clears assignment of the device to the edge. Unassignment works in async way - first, 'unassign' notification event pushed to edge queue on platform. Second, remote edge service will receive an 'unassign' command to remove device (Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform). Third, once 'unassign' command will be delivered to edge service, it's going to remove device locally.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "unassignDeviceFromEdge", + "summary": "Get Device Profile (getDeviceProfileById)", + "description": "Fetch the Device Profile object based on the provided Device Profile Id. The server checks that the device profile is owned by the same tenant. \n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getDeviceProfileById", "parameters": [ { - "name": "edgeId", + "name": "deviceProfileId", "in": "path", - "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" } }, { - "name": "deviceId", - "in": "path", - "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, + "name": "inlineImages", + "in": "query", + "description": "Inline images as a data URL (Base64)", + "required": false, "schema": { - "type": "string" + "type": "boolean" } } ], @@ -27371,7 +27400,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Device" + "$ref": "#/components/schemas/DeviceProfile" } } } @@ -27490,129 +27519,161 @@ "ApiKeyForm": [] } ] - } - }, - "/api/edge/{edgeId}/devices": { - "get": { + }, + "delete": { "tags": [ - "device-controller" + "device-profile-controller" ], - "summary": "Get devices assigned to edge (getEdgeDevices)", - "description": "Returns a page of devices assigned to edge. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getEdgeDevices", + "summary": "Delete device profile (deleteDeviceProfile)", + "description": "Deletes the device profile. Referencing non-existing device profile Id will cause an error. Can't delete the device profile if it is referenced by existing devices.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "deleteDeviceProfile", "parameters": [ { - "name": "edgeId", + "name": "deviceProfileId", "in": "path", - "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" } + } + ], + "responses": { + "200": { + "description": "OK" }, - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "type", - "in": "query", - "description": "Device type as the name of the device profile", - "required": false, - "schema": { - "type": "string" + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingsboardErrorResponse" + }, + "examples": { + "error-code-400": { + "summary": "Bad Request", + "value": { + "status": 400, + "message": "Invalid UUID string: 123", + "errorCode": 31, + "timestamp": 1609459200000 + } + } + } + } } }, - { - "name": "deviceProfileId", - "in": "query", - "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": false, - "schema": { - "type": "string" + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingsboardErrorResponse" + }, + "examples": { + "error-code-401": { + "summary": "Unauthorized", + "value": { + "status": 401, + "message": "Authentication failed", + "errorCode": 10, + "timestamp": 1609459200000 + } + } + } + } } }, - { - "name": "active", - "in": "query", - "description": "A boolean value representing the device active flag.", - "required": false, - "schema": { - "type": "boolean" + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingsboardErrorResponse" + }, + "examples": { + "error-code-403": { + "summary": "Forbidden", + "value": { + "status": 403, + "message": "You don't have permission to perform this operation!", + "errorCode": 20, + "timestamp": 1609459200000 + } + } + } + } } }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'substring' filter based on the device name.", - "required": false, - "schema": { - "type": "string" + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingsboardErrorResponse" + }, + "examples": { + "error-code-404": { + "summary": "Not Found", + "value": { + "status": 404, + "message": "Requested item wasn't found!", + "errorCode": 32, + "timestamp": 1609459200000 + } + } + } + } } }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string", - "enum": [ - "createdTime", - "name", - "deviceProfileName", - "label", - "customerTitle" - ] + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingsboardErrorResponse" + }, + "examples": { + "error-code-429": { + "summary": "Too Many Requests", + "value": { + "status": 429, + "message": "Too many requests for current tenant!", + "errorCode": 33, + "timestamp": 1609459200000 + } + } + } + } } - }, + } + }, + "security": [ { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] - } + "HttpLoginForm": [] }, { - "name": "startTime", - "in": "query", - "description": "Timestamp. Devices with creation time before it won't be queried", - "required": false, - "schema": { - "type": "integer", - "format": "int64" - } - }, + "ApiKeyForm": [] + } + ] + } + }, + "/api/deviceProfile/{deviceProfileId}/default": { + "post": { + "tags": [ + "device-profile-controller" + ], + "summary": "Make Device Profile Default (setDefaultDeviceProfile)", + "description": "Marks device profile as default within a tenant scope.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "setDefaultDeviceProfile", + "parameters": [ { - "name": "endTime", - "in": "query", - "description": "Timestamp. Devices with creation time after it won't be queried", - "required": false, + "name": "deviceProfileId", + "in": "path", + "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, "schema": { - "type": "integer", - "format": "int64" + "type": "string" } } ], @@ -27622,7 +27683,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataDeviceInfo" + "$ref": "#/components/schemas/DeviceProfile" } } } @@ -27639,7 +27700,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -27743,32 +27804,21 @@ ] } }, - "/api/tenant/device": { + "/api/deviceProfileInfo/default": { "get": { "tags": [ - "device-controller" - ], - "summary": "Get Tenant Device (getTenantDeviceByName)", - "description": "Requested device must be owned by tenant that the user belongs to. Device name is an unique property of device. So it can be used to identify the device.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getTenantDeviceByName", - "parameters": [ - { - "name": "deviceName", - "in": "query", - "description": "A string value representing the Device name.", - "required": true, - "schema": { - "type": "string" - } - } + "device-profile-controller" ], + "summary": "Get Default Device Profile (getDefaultDeviceProfileInfo)", + "description": "Fetch the Default Device Profile Info object. Device Profile Info is a lightweight object that includes main information about Device Profile excluding the heavyweight configuration object. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getDefaultDeviceProfileInfo", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Device" + "$ref": "#/components/schemas/DeviceProfileInfo" } } } @@ -27889,99 +27939,23 @@ ] } }, - "/api/tenant/deviceInfos": { + "/api/deviceProfileInfo/{deviceProfileId}": { "get": { "tags": [ - "device-controller" + "device-profile-controller" ], - "summary": "Get Tenant Device Infos (getTenantDeviceInfos)", - "description": "Returns a page of devices info objects owned by tenant. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. Device Info is an extension of the default Device object that contains information about the assigned customer name and device profile name. \n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getTenantDeviceInfos", + "summary": "Get Device Profile Info (getDeviceProfileInfoById)", + "description": "Fetch the Device Profile Info object based on the provided Device Profile Id. Device Profile Info is a lightweight object that includes main information about Device Profile excluding the heavyweight configuration object. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getDeviceProfileInfoById", "parameters": [ - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "type", - "in": "query", - "description": "Device type as the name of the device profile", - "required": false, - "schema": { - "type": "string" - } - }, { "name": "deviceProfileId", - "in": "query", + "in": "path", "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "active", - "in": "query", - "description": "A boolean value representing the device active flag.", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'substring' filter based on the device name.", - "required": false, + "required": true, "schema": { "type": "string" } - }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string", - "enum": [ - "createdTime", - "name", - "deviceProfileName", - "label", - "customerTitle" - ] - } - }, - { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] - } } ], "responses": { @@ -27990,7 +27964,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataDeviceInfo" + "$ref": "#/components/schemas/DeviceProfileInfo" } } } @@ -28111,14 +28085,14 @@ ] } }, - "/api/tenant/devices": { + "/api/deviceProfileInfos": { "get": { "tags": [ - "device-controller" + "device-profile-controller" ], - "summary": "Get Tenant Devices (getTenantDevices)", - "description": "Returns a page of devices owned by tenant. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getTenantDevices", + "summary": "Get Device Profiles for transport type (getDeviceProfileInfos)", + "description": "Returns a page of devices profile info objects owned by tenant. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. Device Profile Info is a lightweight object that includes main information about Device Profile excluding the heavyweight configuration object. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getDeviceProfileInfos", "parameters": [ { "name": "pageSize", @@ -28140,19 +28114,10 @@ "format": "int32" } }, - { - "name": "type", - "in": "query", - "description": "Device type as the name of the device profile", - "required": false, - "schema": { - "type": "string" - } - }, { "name": "textSearch", "in": "query", - "description": "The case insensitive 'substring' filter based on the device name.", + "description": "The case insensitive 'substring' filter based on the device profile name.", "required": false, "schema": { "type": "string" @@ -28168,9 +28133,10 @@ "enum": [ "createdTime", "name", - "deviceProfileName", - "label", - "customerTitle" + "type", + "transportType", + "description", + "isDefault" ] } }, @@ -28186,6 +28152,22 @@ "DESC" ] } + }, + { + "name": "transportType", + "in": "query", + "description": "Type of the transport", + "required": false, + "schema": { + "type": "string", + "enum": [ + "DEFAULT", + "MQTT", + "COAP", + "LWM2M", + "SNMP" + ] + } } ], "responses": { @@ -28194,7 +28176,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataDevice" + "$ref": "#/components/schemas/PageDataDeviceProfileInfo" } } } @@ -28315,31 +28297,25 @@ ] } }, - "/api/tenant/{tenantId}/device/{deviceId}": { - "post": { + "/api/deviceProfileInfos/list": { + "get": { "tags": [ - "device-controller" + "device-profile-controller" ], - "summary": "Assign device to tenant (assignDeviceToTenant)", - "description": "Creates assignment of the device to tenant. Thereafter tenant will be able to reassign the device to a customer.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "assignDeviceToTenant", + "summary": "Get Device Profile Infos By Ids (getDeviceProfileInfosByIds)", + "description": "Requested device profiles must be owned by tenant which is performing the request. \n\n", + "operationId": "getDeviceProfileInfosByIds", "parameters": [ { - "name": "tenantId", - "in": "path", - "description": "A string value representing the tenant id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "deviceId", - "in": "path", - "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "name": "deviceProfileIds", + "in": "query", + "description": "A list of device profile ids, separated by comma ','", "required": true, "schema": { - "type": "string" + "type": "array", + "items": { + "type": "string" + } } } ], @@ -28349,7 +28325,10 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Device" + "type": "array", + "items": { + "$ref": "#/components/schemas/DeviceProfileInfo" + } } } } @@ -28366,7 +28345,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -28470,31 +28449,82 @@ ] } }, - "/api/deviceProfile": { - "post": { + "/api/deviceProfiles": { + "get": { "tags": [ "device-profile-controller" ], - "summary": "Create Or Update Device Profile (saveDeviceProfile)", - "description": "Create or update the Device Profile. When creating device profile, platform generates device profile id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)). The newly created device profile id will be present in the response. Specify existing device profile id to update the device profile. Referencing non-existing device profile Id will cause 'Not Found' error. \n\nDevice profile name is unique in the scope of tenant. Only one 'default' device profile may exist in scope of tenant.\n\n# Device profile data definition\n\nDevice profile data object contains alarm rules configuration, device provision strategy and transport type configuration for device connectivity. Let's review some examples. First one is the default device profile data configuration and second one - the custom one. \n\n```json\n{\n \"alarms\":[\n ],\n \"configuration\":{\n \"type\":\"DEFAULT\"\n },\n \"provisionConfiguration\":{\n \"type\":\"DISABLED\",\n \"provisionDeviceSecret\":null\n },\n \"transportConfiguration\":{\n \"type\":\"DEFAULT\"\n }\n}\n```\n\n```json\n{\n \"alarms\":[\n {\n \"id\":\"2492b935-1226-59e9-8615-17d8978a4f93\",\n \"alarmType\":\"Temperature Alarm\",\n \"clearRule\":{\n \"schedule\":null,\n \"condition\":{\n \"spec\":{\n \"type\":\"SIMPLE\"\n },\n \"condition\":[\n {\n \"key\":{\n \"key\":\"temperature\",\n \"type\":\"TIME_SERIES\"\n },\n \"value\":null,\n \"predicate\":{\n \"type\":\"NUMERIC\",\n \"value\":{\n \"userValue\":null,\n \"defaultValue\":30.0,\n \"dynamicValue\":null\n },\n \"operation\":\"LESS\"\n },\n \"valueType\":\"NUMERIC\"\n }\n ]\n },\n \"dashboardId\":null,\n \"alarmDetails\":null\n },\n \"propagate\":false,\n \"createRules\":{\n \"MAJOR\":{\n \"schedule\":{\n \"type\":\"SPECIFIC_TIME\",\n \"endsOn\":64800000,\n \"startsOn\":43200000,\n \"timezone\":\"Europe/Kiev\",\n \"daysOfWeek\":[\n 1,\n 3,\n 5\n ]\n },\n \"condition\":{\n \"spec\":{\n \"type\":\"DURATION\",\n \"unit\":\"MINUTES\",\n \"predicate\":{\n \"userValue\":null,\n \"defaultValue\":30,\n \"dynamicValue\":null\n }\n },\n \"condition\":[\n {\n \"key\":{\n \"key\":\"temperature\",\n \"type\":\"TIME_SERIES\"\n },\n \"value\":null,\n \"predicate\":{\n \"type\":\"COMPLEX\",\n \"operation\":\"OR\",\n \"predicates\":[\n {\n \"type\":\"NUMERIC\",\n \"value\":{\n \"userValue\":null,\n \"defaultValue\":50.0,\n \"dynamicValue\":null\n },\n \"operation\":\"LESS_OR_EQUAL\"\n },\n {\n \"type\":\"NUMERIC\",\n \"value\":{\n \"userValue\":null,\n \"defaultValue\":30.0,\n \"dynamicValue\":null\n },\n \"operation\":\"GREATER\"\n }\n ]\n },\n \"valueType\":\"NUMERIC\"\n }\n ]\n },\n \"dashboardId\":null,\n \"alarmDetails\":null\n },\n \"WARNING\":{\n \"schedule\":{\n \"type\":\"CUSTOM\",\n \"items\":[\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":1\n },\n {\n \"endsOn\":64800000,\n \"enabled\":true,\n \"startsOn\":43200000,\n \"dayOfWeek\":2\n },\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":3\n },\n {\n \"endsOn\":57600000,\n \"enabled\":true,\n \"startsOn\":36000000,\n \"dayOfWeek\":4\n },\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":5\n },\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":6\n },\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":7\n }\n ],\n \"timezone\":\"Europe/Kiev\"\n },\n \"condition\":{\n \"spec\":{\n \"type\":\"REPEATING\",\n \"predicate\":{\n \"userValue\":null,\n \"defaultValue\":5,\n \"dynamicValue\":null\n }\n },\n \"condition\":[\n {\n \"key\":{\n \"key\":\"tempConstant\",\n \"type\":\"CONSTANT\"\n },\n \"value\":30,\n \"predicate\":{\n \"type\":\"NUMERIC\",\n \"value\":{\n \"userValue\":null,\n \"defaultValue\":0.0,\n \"dynamicValue\":{\n \"inherit\":false,\n \"sourceType\":\"CURRENT_DEVICE\",\n \"sourceAttribute\":\"tempThreshold\"\n }\n },\n \"operation\":\"EQUAL\"\n },\n \"valueType\":\"NUMERIC\"\n }\n ]\n },\n \"dashboardId\":null,\n \"alarmDetails\":null\n },\n \"CRITICAL\":{\n \"schedule\":null,\n \"condition\":{\n \"spec\":{\n \"type\":\"SIMPLE\"\n },\n \"condition\":[\n {\n \"key\":{\n \"key\":\"temperature\",\n \"type\":\"TIME_SERIES\"\n },\n \"value\":null,\n \"predicate\":{\n \"type\":\"NUMERIC\",\n \"value\":{\n \"userValue\":null,\n \"defaultValue\":50.0,\n \"dynamicValue\":null\n },\n \"operation\":\"GREATER\"\n },\n \"valueType\":\"NUMERIC\"\n }\n ]\n },\n \"dashboardId\":null,\n \"alarmDetails\":null\n }\n },\n \"propagateRelationTypes\":null\n }\n ],\n \"configuration\":{\n \"type\":\"DEFAULT\"\n },\n \"provisionConfiguration\":{\n \"type\":\"ALLOW_CREATE_NEW_DEVICES\",\n \"provisionDeviceSecret\":\"vaxb9hzqdbz3oqukvomg\"\n },\n \"transportConfiguration\":{\n \"type\":\"MQTT\",\n \"deviceTelemetryTopic\":\"v1/devices/me/telemetry\",\n \"deviceAttributesTopic\":\"v1/devices/me/attributes\",\n \"transportPayloadTypeConfiguration\":{\n \"transportPayloadType\":\"PROTOBUF\",\n \"deviceTelemetryProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage telemetry;\\n\\nmessage SensorDataReading {\\n\\n optional double temperature = 1;\\n optional double humidity = 2;\\n InnerObject innerObject = 3;\\n\\n message InnerObject {\\n optional string key1 = 1;\\n optional bool key2 = 2;\\n optional double key3 = 3;\\n optional int32 key4 = 4;\\n optional string key5 = 5;\\n }\\n}\",\n \"deviceAttributesProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage attributes;\\n\\nmessage SensorConfiguration {\\n optional string firmwareVersion = 1;\\n optional string serialNumber = 2;\\n}\",\n \"deviceRpcRequestProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage rpc;\\n\\nmessage RpcRequestMsg {\\n optional string method = 1;\\n optional int32 requestId = 2;\\n optional string params = 3;\\n}\",\n \"deviceRpcResponseProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage rpc;\\n\\nmessage RpcResponseMsg {\\n optional string payload = 1;\\n}\"\n }\n }\n}\n```\n\nLet's review some specific objects examples related to the device profile configuration:\n\n# Alarm Schedule\n\nAlarm Schedule JSON object represents the time interval during which the alarm rule is active. Note, \n\n```json\n\"schedule\": null\n```\n\nmeans alarm rule is active all the time. **'daysOfWeek'** field represents Monday as 1, Tuesday as 2 and so on. **'startsOn'** and **'endsOn'** fields represent hours in millis (e.g. 64800000 = 18:00 or 6pm). **'enabled'** flag specifies if item in a custom rule is active for specific day of the week:\n\n## Specific Time Schedule\n\n```json\n{\n \"schedule\":{\n \"type\":\"SPECIFIC_TIME\",\n \"endsOn\":64800000,\n \"startsOn\":43200000,\n \"timezone\":\"Europe/Kiev\",\n \"daysOfWeek\":[\n 1,\n 3,\n 5\n ]\n }\n}\n```\n\n## Custom Schedule\n\n```json\n{\n \"schedule\":{\n \"type\":\"CUSTOM\",\n \"items\":[\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":1\n },\n {\n \"endsOn\":64800000,\n \"enabled\":true,\n \"startsOn\":43200000,\n \"dayOfWeek\":2\n },\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":3\n },\n {\n \"endsOn\":57600000,\n \"enabled\":true,\n \"startsOn\":36000000,\n \"dayOfWeek\":4\n },\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":5\n },\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":6\n },\n {\n \"endsOn\":0,\n \"enabled\":false,\n \"startsOn\":0,\n \"dayOfWeek\":7\n }\n ],\n \"timezone\":\"Europe/Kiev\"\n }\n}\n```\n\n# Alarm condition type (**'spec'**)\n\nAlarm condition type can be either simple, duration, or repeating. For example, 5 times in a row or during 5 minutes.\n\nNote, **'userValue'** field is not used and reserved for future usage, **'dynamicValue'** is used for condition appliance by using the value of the **'sourceAttribute'** or else **'defaultValue'** is used (if **'sourceAttribute'** is absent).\n\n**'sourceType'** of the **'sourceAttribute'** can be: \n * 'CURRENT_DEVICE';\n * 'CURRENT_CUSTOMER';\n * 'CURRENT_TENANT'.\n\n**'sourceAttribute'** can be inherited from the owner if **'inherit'** is set to true (for CURRENT_DEVICE and CURRENT_CUSTOMER).\n\n## Repeating alarm condition\n\n```json\n{\n \"spec\":{\n \"type\":\"REPEATING\",\n \"predicate\":{\n \"userValue\":null,\n \"defaultValue\":5,\n \"dynamicValue\":{\n \"inherit\":true,\n \"sourceType\":\"CURRENT_DEVICE\",\n \"sourceAttribute\":\"tempAttr\"\n }\n }\n }\n}\n```\n\n## Duration alarm condition\n\n```json\n{\n \"spec\":{\n \"type\":\"DURATION\",\n \"unit\":\"MINUTES\",\n \"predicate\":{\n \"userValue\":null,\n \"defaultValue\":30,\n \"dynamicValue\":null\n }\n }\n}\n```\n\n**'unit'** can be: \n * 'SECONDS';\n * 'MINUTES';\n * 'HOURS';\n * 'DAYS'.\n\n# Key Filters\n\nKey filter objects are created under the **'condition'** array. They allow you to define complex logical expressions over entity field, attribute, latest time series value or constant. The filter is defined using 'key', 'valueType', 'value' (refers to the value of the 'CONSTANT' alarm filter key type) and 'predicate' objects. Let's review each object:\n\n## Alarm Filter Key\n\nFilter Key defines either entity field, attribute, telemetry or constant. It is a JSON object that consists the key name and type. The following filter key types are supported:\n * 'ATTRIBUTE' - used for attributes values;\n * 'TIME_SERIES' - used for time series values;\n * 'ENTITY_FIELD' - used for accessing entity fields like 'name', 'label', etc. The list of available fields depends on the entity type;\n * 'CONSTANT' - constant value specified.\n\nLet's review the example:\n\n```json\n{\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n}\n```\n\n## Value Type and Operations\n\nProvides a hint about the data type of the entity field that is defined in the filter key. The value type impacts the list of possible operations that you may use in the corresponding predicate. For example, you may use 'STARTS_WITH' or 'END_WITH', but you can't use 'GREATER_OR_EQUAL' for string values.The following filter value types and corresponding predicate operations are supported: \n\n * 'STRING' - used to filter any 'String' or 'JSON' values. Operations: EQUAL, NOT_EQUAL, STARTS_WITH, ENDS_WITH, CONTAINS, NOT_CONTAINS; \n * 'NUMERIC' - used for 'Long' and 'Double' values. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n * 'BOOLEAN' - used for boolean values. Operations: EQUAL, NOT_EQUAL;\n * 'DATE_TIME' - similar to numeric, transforms value to milliseconds since epoch. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n\n\n\n\n## Filter Predicate\n\nFilter Predicate defines the logical expression to evaluate. The list of available operations depends on the filter value type, see above. Platform supports 4 predicate types: 'STRING', 'NUMERIC', 'BOOLEAN' and 'COMPLEX'. The last one allows to combine multiple operations over one filter key.\n\nSimple predicate example to check 'value \u003C 100': \n\n```json\n{\n \"operation\": \"LESS\",\n \"value\": {\n \"userValue\": null,\n \"defaultValue\": 100,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n}\n```\n\nComplex predicate example, to check 'value \u003C 10 or value \u003E 20': \n\n```json\n{\n \"type\": \"COMPLEX\",\n \"operation\": \"OR\",\n \"predicates\": [\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"userValue\": null,\n \"defaultValue\": 10,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"operation\": \"GREATER\",\n \"value\": {\n \"userValue\": null,\n \"defaultValue\": 20,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n ]\n}\n```\n\nMore complex predicate example, to check 'value \u003C 10 or (value \u003E 50 && value \u003C 60)': \n\n```json\n{\n \"type\": \"COMPLEX\",\n \"operation\": \"OR\",\n \"predicates\": [\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"userValue\": null,\n \"defaultValue\": 10,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"type\": \"COMPLEX\",\n \"operation\": \"AND\",\n \"predicates\": [\n {\n \"operation\": \"GREATER\",\n \"value\": {\n \"userValue\": null,\n \"defaultValue\": 50,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"userValue\": null,\n \"defaultValue\": 60,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n ]\n }\n ]\n}\n```\n\nYou may also want to replace hardcoded values (for example, temperature \u003E 20) with the more dynamic expression (for example, temperature \u003E value of the tenant attribute with key 'temperatureThreshold'). It is possible to use 'dynamicValue' to define attribute of the tenant, customer or device. See example below:\n\n```json\n{\n \"operation\": \"GREATER\",\n \"value\": {\n \"userValue\": null,\n \"defaultValue\": 0,\n \"dynamicValue\": {\n \"inherit\": false,\n \"sourceType\": \"CURRENT_TENANT\",\n \"sourceAttribute\": \"temperatureThreshold\"\n }\n },\n \"type\": \"NUMERIC\"\n}\n```\n\nNote that you may use 'CURRENT_DEVICE', 'CURRENT_CUSTOMER' and 'CURRENT_TENANT' as a 'sourceType'. The 'defaultValue' is used when the attribute with such a name is not defined for the chosen source. The 'sourceAttribute' can be inherited from the owner of the specified 'sourceType' if 'inherit' is set to true.\n\n# Provision Configuration\n\nThere are 3 types of device provision configuration for the device profile: \n * 'DISABLED';\n * 'ALLOW_CREATE_NEW_DEVICES';\n * 'CHECK_PRE_PROVISIONED_DEVICES'.\n\nPlease refer to the [docs](https://thingsboard.io/docs/user-guide/device-provisioning/) for more details.\n\n# Transport Configuration\n\n5 transport configuration types are available:\n * 'DEFAULT';\n * 'MQTT';\n * 'LWM2M';\n * 'COAP';\n * 'SNMP'.\n\nDefault type supports basic MQTT, HTTP, CoAP and LwM2M transports. Please refer to the [docs](https://thingsboard.io/docs/user-guide/device-profiles/#transport-configuration) for more details about other types.\n\nSee another example of COAP transport configuration below:\n\n```json\n{\n \"type\":\"COAP\",\n \"clientSettings\":{\n \"edrxCycle\":null,\n \"powerMode\":\"DRX\",\n \"psmActivityTimer\":null,\n \"pagingTransmissionWindow\":null\n },\n \"coapDeviceTypeConfiguration\":{\n \"coapDeviceType\":\"DEFAULT\",\n \"transportPayloadTypeConfiguration\":{\n \"transportPayloadType\":\"JSON\"\n }\n }\n}\n```Remove 'id', 'tenantId' from the request body example (below) to create new Device Profile entity. \n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "saveDeviceProfile", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeviceProfile" - } + "summary": "Get Device Profiles (getDeviceProfiles)", + "description": "Returns a page of devices profile objects owned by tenant. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getDeviceProfiles", + "parameters": [ + { + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", + "required": true, + "schema": { + "type": "integer", + "format": "int32" } }, - "required": true - }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'substring' filter based on the device profile name.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string", + "enum": [ + "createdTime", + "name", + "type", + "transportType", + "description", + "isDefault" + ] + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ASC", + "DESC" + ] + } + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeviceProfile" + "$ref": "#/components/schemas/PageDataDeviceProfile" } } } @@ -28511,7 +28541,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -28615,35 +28645,45 @@ ] } }, - "/api/deviceProfile/devices/keys/attributes": { - "get": { + "/api/domain": { + "post": { "tags": [ - "device-profile-controller" + "domain-controller" ], - "summary": "Get attribute keys (getAttributesKeys)", - "description": "Get a set of unique attribute keys used by devices that belong to specified profile. If profile is not set returns a list of unique keys among all profiles. The call is used for auto-complete in the UI forms. The implementation limits the number of devices that participate in search to 100 as a trade of between accurate results and time-consuming queries. \n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getAttributesKeys", + "summary": "Save or Update Domain (saveDomain)", + "description": "Create or update the Domain. When creating domain, platform generates Domain Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)). The newly created Domain Id will be present in the response. Specify existing Domain Id to update the domain. Referencing non-existing Domain Id will cause 'Not Found' error.\n\nDomain name is unique for entire platform setup.\n\n\n\nAvailable for users with 'SYS_ADMIN' authority.", + "operationId": "saveDomain", "parameters": [ { - "name": "deviceProfileId", + "name": "oauth2ClientIds", "in": "query", - "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "A list of oauth2 client registration ids, separated by comma ','", "required": false, "schema": { - "type": "string" + "type": "array", + "items": { + "type": "string" + } } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Domain" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "type": "string" - } + "$ref": "#/components/schemas/Domain" } } } @@ -28660,7 +28700,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -28764,22 +28804,22 @@ ] } }, - "/api/deviceProfile/devices/keys/timeseries": { + "/api/domain/info/{id}": { "get": { "tags": [ - "device-profile-controller" + "domain-controller" ], - "summary": "Get time series keys (getDeviceProfileTimeseriesKeys)", - "description": "Get a set of unique time series keys used by devices that belong to specified profile. If profile is not set returns a list of unique keys among all profiles. The call is used for auto-complete in the UI forms. The implementation limits the number of devices that participate in search to 100 as a trade of between accurate results and time-consuming queries. \n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getDeviceProfileTimeseriesKeys", + "summary": "Get Domain info by Id (getDomainInfoById)", + "description": "\n\nAvailable for users with 'SYS_ADMIN' authority.", + "operationId": "getDomainInfoById", "parameters": [ { - "name": "deviceProfileId", - "in": "query", - "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": false, + "name": "id", + "in": "path", + "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" } } ], @@ -28789,10 +28829,7 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "type": "string" - } + "$ref": "#/components/schemas/DomainInfo" } } } @@ -28913,23 +28950,60 @@ ] } }, - "/api/deviceProfile/names": { + "/api/domain/infos": { "get": { "tags": [ - "device-profile-controller" + "domain-controller" ], - "summary": "Get Device Profile names (getDeviceProfileNames)", - "description": "Returns a set of unique device profile names owned by the tenant.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getDeviceProfileNames", + "summary": "Get Domain infos (getTenantDomainInfos)", + "description": "\n\nAvailable for users with 'SYS_ADMIN' authority.", + "operationId": "getTenantDomainInfos", "parameters": [ { - "name": "activeOnly", + "name": "pageSize", "in": "query", - "description": "Flag indicating whether to retrieve exclusively the names of device profiles that are referenced by tenant's devices.", + "description": "Maximum amount of entities in a one page", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "textSearch", + "in": "query", + "description": "Case-insensitive 'substring' filter based on domain's name", "required": false, "schema": { - "type": "boolean", - "default": false + "type": "string" + } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string" } } ], @@ -28939,10 +29013,7 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityInfo" - } + "$ref": "#/components/schemas/PageDataDomainInfo" } } } @@ -29063,44 +29134,28 @@ ] } }, - "/api/deviceProfile/{deviceProfileId}": { - "get": { + "/api/domain/{id}": { + "delete": { "tags": [ - "device-profile-controller" + "domain-controller" ], - "summary": "Get Device Profile (getDeviceProfileById)", - "description": "Fetch the Device Profile object based on the provided Device Profile Id. The server checks that the device profile is owned by the same tenant. \n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getDeviceProfileById", + "summary": "Delete Domain by ID (deleteDomain)", + "description": "Deletes Domain by ID. Referencing non-existing domain Id will cause an error.\n\nAvailable for users with 'SYS_ADMIN' authority.", + "operationId": "deleteDomain", "parameters": [ { - "name": "deviceProfileId", + "name": "id", "in": "path", - "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { - "type": "string" - } - }, - { - "name": "inlineImages", - "in": "query", - "description": "Inline images as a data URL (Base64)", - "required": false, - "schema": { - "type": "boolean" + "type": "string", + "format": "uuid" } } ], "responses": { "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeviceProfile" - } - } - } + "description": "OK" }, "400": { "description": "Bad Request", @@ -29216,25 +29271,41 @@ "ApiKeyForm": [] } ] - }, - "delete": { + } + }, + "/api/domain/{id}/oauth2Clients": { + "put": { "tags": [ - "device-profile-controller" + "domain-controller" ], - "summary": "Delete device profile (deleteDeviceProfile)", - "description": "Deletes the device profile. Referencing non-existing device profile Id will cause an error. Can't delete the device profile if it is referenced by existing devices.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "deleteDeviceProfile", + "summary": "Update oauth2 clients (updateDomainOauth2Clients)", + "description": "Update oauth2 clients for the specified domain. ", + "operationId": "updateDomainOauth2Clients", "parameters": [ { - "name": "deviceProfileId", + "name": "id", "in": "path", - "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK" @@ -29355,19 +29426,19 @@ ] } }, - "/api/deviceProfile/{deviceProfileId}/default": { - "post": { + "/api/customer/edge/{edgeId}": { + "delete": { "tags": [ - "device-profile-controller" + "edge-controller" ], - "summary": "Make Device Profile Default (setDefaultDeviceProfile)", - "description": "Marks device profile as default within a tenant scope.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "setDefaultDeviceProfile", + "summary": "Unassign edge from customer (unassignEdgeFromCustomer)", + "description": "Clears assignment of the edge to customer. Customer will not be able to query edge afterwards.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "unassignEdgeFromCustomer", "parameters": [ { - "name": "deviceProfileId", + "name": "edgeId", "in": "path", - "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" @@ -29380,7 +29451,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeviceProfile" + "$ref": "#/components/schemas/Edge" } } } @@ -29397,7 +29468,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -29501,21 +29572,32 @@ ] } }, - "/api/deviceProfileInfo/default": { - "get": { + "/api/customer/public/edge/{edgeId}": { + "post": { "tags": [ - "device-profile-controller" + "edge-controller" + ], + "summary": "Make edge publicly available (assignEdgeToPublicCustomer)", + "description": "Edge will be available for non-authorized (not logged-in) users. This is useful to create dashboards that you plan to share/embed on a publicly available website. However, users that are logged-in and belong to different tenant will not be able to access the edge.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "assignEdgeToPublicCustomer", + "parameters": [ + { + "name": "edgeId", + "in": "path", + "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + } ], - "summary": "Get Default Device Profile (getDefaultDeviceProfileInfo)", - "description": "Fetch the Default Device Profile Info object. Device Profile Info is a lightweight object that includes main information about Device Profile excluding the heavyweight configuration object. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getDefaultDeviceProfileInfo", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeviceProfileInfo" + "$ref": "#/components/schemas/Edge" } } } @@ -29532,7 +29614,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -29636,19 +29718,28 @@ ] } }, - "/api/deviceProfileInfo/{deviceProfileId}": { - "get": { + "/api/customer/{customerId}/edge/{edgeId}": { + "post": { "tags": [ - "device-profile-controller" + "edge-controller" ], - "summary": "Get Device Profile Info (getDeviceProfileInfoById)", - "description": "Fetch the Device Profile Info object based on the provided Device Profile Id. Device Profile Info is a lightweight object that includes main information about Device Profile excluding the heavyweight configuration object. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getDeviceProfileInfoById", + "summary": "Assign edge to customer (assignEdgeToCustomer)", + "description": "Creates assignment of the edge to customer. Customer will be able to query edge afterwards.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "assignEdgeToCustomer", "parameters": [ { - "name": "deviceProfileId", + "name": "customerId", "in": "path", - "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "edgeId", + "in": "path", + "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" @@ -29661,7 +29752,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeviceProfileInfo" + "$ref": "#/components/schemas/Edge" } } } @@ -29678,7 +29769,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -29782,15 +29873,24 @@ ] } }, - "/api/deviceProfileInfos": { + "/api/customer/{customerId}/edgeInfos": { "get": { "tags": [ - "device-profile-controller" + "edge-controller" ], - "summary": "Get Device Profiles for transport type (getDeviceProfileInfos)", - "description": "Returns a page of devices profile info objects owned by tenant. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. Device Profile Info is a lightweight object that includes main information about Device Profile excluding the heavyweight configuration object. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getDeviceProfileInfos", + "summary": "Get Customer Edge Infos (getCustomerEdgeInfos)", + "description": "Returns a page of edges info objects assigned to customer. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. Edge Info is an extension of the default Edge object that contains information about the assigned customer name. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getCustomerEdgeInfos", "parameters": [ + { + "name": "customerId", + "in": "path", + "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, { "name": "pageSize", "in": "query", @@ -29811,10 +29911,19 @@ "format": "int32" } }, + { + "name": "type", + "in": "query", + "description": "A string value representing the edge type. For example, 'default'", + "required": false, + "schema": { + "type": "string" + } + }, { "name": "textSearch", "in": "query", - "description": "The case insensitive 'substring' filter based on the device profile name.", + "description": "The case insensitive 'substring' filter based on the edge name.", "required": false, "schema": { "type": "string" @@ -29831,9 +29940,8 @@ "createdTime", "name", "type", - "transportType", - "description", - "isDefault" + "label", + "customerTitle" ] } }, @@ -29849,22 +29957,6 @@ "DESC" ] } - }, - { - "name": "transportType", - "in": "query", - "description": "Type of the transport", - "required": false, - "schema": { - "type": "string", - "enum": [ - "DEFAULT", - "MQTT", - "COAP", - "LWM2M", - "SNMP" - ] - } } ], "responses": { @@ -29873,159 +29965,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataDeviceProfileInfo" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-400": { - "summary": "Bad Request", - "value": { - "status": 400, - "message": "Invalid UUID string: 123", - "errorCode": 31, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-401": { - "summary": "Unauthorized", - "value": { - "status": 401, - "message": "Authentication failed", - "errorCode": 10, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-403": { - "summary": "Forbidden", - "value": { - "status": 403, - "message": "You don't have permission to perform this operation!", - "errorCode": 20, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-404": { - "summary": "Not Found", - "value": { - "status": 404, - "message": "Requested item wasn't found!", - "errorCode": 32, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "429": { - "description": "Too Many Requests", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-429": { - "summary": "Too Many Requests", - "value": { - "status": 429, - "message": "Too many requests for current tenant!", - "errorCode": 33, - "timestamp": 1609459200000 - } - } - } - } - } - } - }, - "security": [ - { - "HttpLoginForm": [] - }, - { - "ApiKeyForm": [] - } - ] - } - }, - "/api/deviceProfileInfos/list": { - "get": { - "tags": [ - "device-profile-controller" - ], - "summary": "Get Device Profile Infos By Ids (getDeviceProfileInfosByIds)", - "description": "Requested device profiles must be owned by tenant which is performing the request. \n\n", - "operationId": "getDeviceProfileInfosByIds", - "parameters": [ - { - "name": "deviceProfileIds", - "in": "query", - "description": "A list of device profile ids, separated by comma ','", - "required": true, - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/DeviceProfileInfo" - } + "$ref": "#/components/schemas/PageDataEdgeInfo" } } } @@ -30146,15 +30086,24 @@ ] } }, - "/api/deviceProfiles": { + "/api/customer/{customerId}/edges": { "get": { "tags": [ - "device-profile-controller" + "edge-controller" ], - "summary": "Get Device Profiles (getDeviceProfiles)", - "description": "Returns a page of devices profile objects owned by tenant. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getDeviceProfiles", + "summary": "Get Customer Edges (getCustomerEdges)", + "description": "Returns a page of edges objects assigned to customer. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getCustomerEdges", "parameters": [ + { + "name": "customerId", + "in": "path", + "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, { "name": "pageSize", "in": "query", @@ -30175,10 +30124,19 @@ "format": "int32" } }, + { + "name": "type", + "in": "query", + "description": "A string value representing the edge type. For example, 'default'", + "required": false, + "schema": { + "type": "string" + } + }, { "name": "textSearch", "in": "query", - "description": "The case insensitive 'substring' filter based on the device profile name.", + "description": "The case insensitive 'substring' filter based on the edge name.", "required": false, "schema": { "type": "string" @@ -30195,9 +30153,8 @@ "createdTime", "name", "type", - "transportType", - "description", - "isDefault" + "label", + "customerTitle" ] } }, @@ -30221,7 +30178,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataDeviceProfile" + "$ref": "#/components/schemas/PageDataEdge" } } } @@ -30342,33 +30299,19 @@ ] } }, - "/api/domain": { + "/api/edge": { "post": { "tags": [ - "domain-controller" - ], - "summary": "Save or Update Domain (saveDomain)", - "description": "Create or update the Domain. When creating domain, platform generates Domain Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)). The newly created Domain Id will be present in the response. Specify existing Domain Id to update the domain. Referencing non-existing Domain Id will cause 'Not Found' error.\n\nDomain name is unique for entire platform setup.\n\n\n\nAvailable for users with 'SYS_ADMIN' authority.", - "operationId": "saveDomain", - "parameters": [ - { - "name": "oauth2ClientIds", - "in": "query", - "description": "A list of oauth2 client registration ids, separated by comma ','", - "required": false, - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - } + "edge-controller" ], + "summary": "Create Or Update Edge (saveEdge)", + "description": "Create or update the Edge. When creating edge, platform generates Edge Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)). The newly created edge id will be present in the response. Specify existing Edge id to update the edge. Referencing non-existing Edge Id will cause 'Not Found' error.\n\nEdge name is unique in the scope of tenant. Use unique identifiers like MAC or IMEI for the edge names and non-unique 'label' field for user-friendly visualization purposes.Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Edge entity. \n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "saveEdge", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Domain" + "$ref": "#/components/schemas/Edge" } } }, @@ -30380,7 +30323,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Domain" + "$ref": "#/components/schemas/Edge" } } } @@ -30501,32 +30444,31 @@ ] } }, - "/api/domain/info/{id}": { - "get": { + "/api/edge/bulk_import": { + "post": { "tags": [ - "domain-controller" + "edge-controller" ], - "summary": "Get Domain info by Id (getDomainInfoById)", - "description": "\n\nAvailable for users with 'SYS_ADMIN' authority.", - "operationId": "getDomainInfoById", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" + "summary": "Import the bulk of edges (processEdgesBulkImport)", + "description": "There's an ability to import the bulk of edges using the only .csv file.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "processEdgesBulkImport", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkImportRequest" + } } - } - ], + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DomainInfo" + "$ref": "#/components/schemas/BulkImportResultEdge" } } } @@ -30543,7 +30485,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -30647,58 +30589,20 @@ ] } }, - "/api/domain/infos": { + "/api/edge/info/{edgeId}": { "get": { "tags": [ - "domain-controller" + "edge-controller" ], - "summary": "Get Domain infos (getTenantDomainInfos)", - "description": "\n\nAvailable for users with 'SYS_ADMIN' authority.", - "operationId": "getTenantDomainInfos", + "summary": "Get Edge Info (getEdgeInfoById)", + "description": "Get the Edge Info object based on the provided Edge Id. If the user has the authority of 'Tenant Administrator', the server checks that the edge is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the edge is assigned to the same customer.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getEdgeInfoById", "parameters": [ { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", + "name": "edgeId", + "in": "path", + "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "textSearch", - "in": "query", - "description": "Case-insensitive 'substring' filter based on domain's name", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, "schema": { "type": "string" } @@ -30710,7 +30614,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataDomainInfo" + "$ref": "#/components/schemas/EdgeInfo" } } } @@ -30831,28 +30735,49 @@ ] } }, - "/api/domain/{id}": { - "delete": { + "/api/edge/instructions/install/{edgeId}/{method}": { + "get": { "tags": [ - "domain-controller" + "edge-controller" ], - "summary": "Delete Domain by ID (deleteDomain)", - "description": "Deletes Domain by ID. Referencing non-existing domain Id will cause an error.\n\nAvailable for users with 'SYS_ADMIN' authority.", - "operationId": "deleteDomain", + "summary": "Get Edge Install Instructions (getEdgeInstallInstructions)", + "description": "Get an install instructions for provided edge id.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getEdgeInstallInstructions", "parameters": [ { - "name": "id", + "name": "edgeId", + "in": "path", + "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "method", "in": "path", + "description": "Installation method ('docker', 'ubuntu' or 'centos')", "required": true, "schema": { "type": "string", - "format": "uuid" + "enum": [ + "docker", + "ubuntu", + "centos" + ] } } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EdgeInstructions" + } + } + } }, "400": { "description": "Bad Request", @@ -30970,43 +30895,50 @@ ] } }, - "/api/domain/{id}/oauth2Clients": { - "put": { + "/api/edge/instructions/upgrade/{edgeVersion}/{method}": { + "get": { "tags": [ - "domain-controller" + "edge-controller" ], - "summary": "Update oauth2 clients (updateDomainOauth2Clients)", - "description": "Update oauth2 clients for the specified domain. ", - "operationId": "updateDomainOauth2Clients", + "summary": "Get Edge Upgrade Instructions (getEdgeUpgradeInstructions)", + "description": "Get an upgrade instructions for provided edge version.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getEdgeUpgradeInstructions", "parameters": [ { - "name": "id", + "name": "edgeVersion", + "in": "path", + "description": "Edge version", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "method", "in": "path", + "description": "Upgrade method ('docker', 'ubuntu' or 'centos')", "required": true, "schema": { "type": "string", - "format": "uuid" + "enum": [ + "docker", + "ubuntu", + "centos" + ] } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "string", - "format": "uuid" + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EdgeInstructions" } } } }, - "required": true - }, - "responses": { - "200": { - "description": "OK" - }, "400": { "description": "Bad Request", "content": { @@ -31123,14 +31055,14 @@ ] } }, - "/api/customer/edge/{edgeId}": { - "delete": { + "/api/edge/missingToRelatedRuleChains/{edgeId}": { + "get": { "tags": [ "edge-controller" ], - "summary": "Unassign edge from customer (unassignEdgeFromCustomer)", - "description": "Clears assignment of the edge to customer. Customer will not be able to query edge afterwards.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "unassignEdgeFromCustomer", + "summary": "Find missing rule chains (findMissingToRelatedRuleChains)", + "description": "Returns list of rule chains ids that are not assigned to particular edge, but these rule chains are present in the already assigned rule chains to edge.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "findMissingToRelatedRuleChains", "parameters": [ { "name": "edgeId", @@ -31148,7 +31080,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Edge" + "type": "string" } } } @@ -31269,14 +31201,14 @@ ] } }, - "/api/customer/public/edge/{edgeId}": { + "/api/edge/sync/{edgeId}": { "post": { "tags": [ "edge-controller" ], - "summary": "Make edge publicly available (assignEdgeToPublicCustomer)", - "description": "Edge will be available for non-authorized (not logged-in) users. This is useful to create dashboards that you plan to share/embed on a publicly available website. However, users that are logged-in and belong to different tenant will not be able to access the edge.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "assignEdgeToPublicCustomer", + "summary": "Sync edge (syncEdge)", + "description": "Starts synchronization process between edge and cloud. \nAll entities that are assigned to particular edge are going to be send to remote edge service.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "syncEdge", "parameters": [ { "name": "edgeId", @@ -31294,7 +31226,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Edge" + "type": "string" } } } @@ -31415,41 +31347,24 @@ ] } }, - "/api/customer/{customerId}/edge/{edgeId}": { - "post": { + "/api/edge/types": { + "get": { "tags": [ "edge-controller" ], - "summary": "Assign edge to customer (assignEdgeToCustomer)", - "description": "Creates assignment of the edge to customer. Customer will be able to query edge afterwards.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "assignEdgeToCustomer", - "parameters": [ - { - "name": "customerId", - "in": "path", - "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "edgeId", - "in": "path", - "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - } - ], + "summary": "Get Edge Types (getEdgeTypes)", + "description": "Returns a set of unique edge types based on edges that are either owned by the tenant or assigned to the customer which user is performing the request.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getEdgeTypes", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Edge" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntitySubtype" + } } } } @@ -31466,7 +31381,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -31570,90 +31485,23 @@ ] } }, - "/api/customer/{customerId}/edgeInfos": { + "/api/edge/{edgeId}": { "get": { "tags": [ "edge-controller" ], - "summary": "Get Customer Edge Infos (getCustomerEdgeInfos)", - "description": "Returns a page of edges info objects assigned to customer. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. Edge Info is an extension of the default Edge object that contains information about the assigned customer name. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getCustomerEdgeInfos", + "summary": "Get Edge (getEdgeById)", + "description": "Get the Edge object based on the provided Edge Id. If the user has the authority of 'Tenant Administrator', the server checks that the edge is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the edge is assigned to the same customer.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getEdgeById", "parameters": [ { - "name": "customerId", + "name": "edgeId", "in": "path", - "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", + "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "type", - "in": "query", - "description": "A string value representing the edge type. For example, 'default'", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'substring' filter based on the edge name.", - "required": false, "schema": { "type": "string" } - }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string", - "enum": [ - "createdTime", - "name", - "type", - "label", - "customerTitle" - ] - } - }, - { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] - } } ], "responses": { @@ -31662,7 +31510,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEdgeInfo" + "$ref": "#/components/schemas/Edge" } } } @@ -31781,104 +31629,28 @@ "ApiKeyForm": [] } ] - } - }, - "/api/customer/{customerId}/edges": { - "get": { + }, + "delete": { "tags": [ "edge-controller" ], - "summary": "Get Customer Edges (getCustomerEdges)", - "description": "Returns a page of edges objects assigned to customer. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getCustomerEdges", + "summary": "Delete edge (deleteEdge)", + "description": "Deletes the edge. Referencing non-existing edge Id will cause an error.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "deleteEdge", "parameters": [ { - "name": "customerId", + "name": "edgeId", "in": "path", - "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", + "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "type", - "in": "query", - "description": "A string value representing the edge type. For example, 'default'", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'substring' filter based on the edge name.", - "required": false, "schema": { "type": "string" } - }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string", - "enum": [ - "createdTime", - "name", - "type", - "label", - "customerTitle" - ] - } - }, - { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] - } } ], "responses": { "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PageDataEdge" - } - } - } + "description": "OK" }, "400": { "description": "Bad Request", @@ -31996,31 +31768,32 @@ ] } }, - "/api/edge": { - "post": { + "/api/edge/{edgeId}/upgrade/available": { + "get": { "tags": [ "edge-controller" ], - "summary": "Create Or Update Edge (saveEdge)", - "description": "Create or update the Edge. When creating edge, platform generates Edge Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)). The newly created edge id will be present in the response. Specify existing Edge id to update the edge. Referencing non-existing Edge Id will cause 'Not Found' error.\n\nEdge name is unique in the scope of tenant. Use unique identifiers like MAC or IMEI for the edge names and non-unique 'label' field for user-friendly visualization purposes.Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Edge entity. \n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "saveEdge", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Edge" - } + "summary": "Is edge upgrade enabled (isEdgeUpgradeAvailable)", + "description": "Returns 'true' if upgrade available for connected edge, 'false' - otherwise.", + "operationId": "isEdgeUpgradeAvailable", + "parameters": [ + { + "name": "edgeId", + "in": "path", + "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" } - }, - "required": true - }, + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Edge" + "type": "boolean" } } } @@ -32037,7 +31810,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -32141,31 +31914,41 @@ ] } }, - "/api/edge/bulk_import": { + "/api/edge/{edgeId}/{ruleChainId}/root": { "post": { "tags": [ "edge-controller" ], - "summary": "Import the bulk of edges (processEdgesBulkImport)", - "description": "There's an ability to import the bulk of edges using the only .csv file.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "processEdgesBulkImport", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BulkImportRequest" - } + "summary": "Set root rule chain for provided edge (setEdgeRootRuleChain)", + "description": "Change root rule chain of the edge to the new provided rule chain. \nThis operation will send a notification to update root rule chain on remote edge service.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "setEdgeRootRuleChain", + "parameters": [ + { + "name": "edgeId", + "in": "path", + "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" } }, - "required": true - }, + { + "name": "ruleChainId", + "in": "path", + "description": "A string value representing the rule chain id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BulkImportResultEdge" + "$ref": "#/components/schemas/Edge" } } } @@ -32286,23 +32069,72 @@ ] } }, - "/api/edge/info/{edgeId}": { + "/api/edges": { "get": { "tags": [ "edge-controller" ], - "summary": "Get Edge Info (getEdgeInfoById)", - "description": "Get the Edge Info object based on the provided Edge Id. If the user has the authority of 'Tenant Administrator', the server checks that the edge is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the edge is assigned to the same customer.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getEdgeInfoById", + "summary": "Get Tenant Edges (getEdges)", + "description": "Returns a page of edges owned by tenant. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getEdges", "parameters": [ { - "name": "edgeId", - "in": "path", - "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'substring' filter based on the edge name.", + "required": false, "schema": { "type": "string" } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string", + "enum": [ + "createdTime", + "name", + "type", + "label", + "customerTitle" + ] + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ASC", + "DESC" + ] + } } ], "responses": { @@ -32311,7 +32143,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EdgeInfo" + "$ref": "#/components/schemas/PageDataEdge" } } } @@ -32430,48 +32262,34 @@ "ApiKeyForm": [] } ] - } - }, - "/api/edge/instructions/install/{edgeId}/{method}": { - "get": { + }, + "post": { "tags": [ "edge-controller" ], - "summary": "Get Edge Install Instructions (getEdgeInstallInstructions)", - "description": "Get an install instructions for provided edge id.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getEdgeInstallInstructions", - "parameters": [ - { - "name": "edgeId", - "in": "path", - "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" + "summary": "Find related edges (findEdgesByQuery)", + "description": "Returns all edges that are related to the specific entity. The entity id, relation type, edge types, depth of the search, and other query parameters defined using complex 'EdgeSearchQuery' object. See 'Model' tab of the Parameters for more info.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "findEdgesByQuery", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EdgeSearchQuery" + } } }, - { - "name": "method", - "in": "path", - "description": "Installation method ('docker', 'ubuntu' or 'centos')", - "required": true, - "schema": { - "type": "string", - "enum": [ - "docker", - "ubuntu", - "centos" - ] - } - } - ], + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EdgeInstructions" + "type": "array", + "items": { + "$ref": "#/components/schemas/Edge" + } } } } @@ -32488,7 +32306,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -32592,46 +32410,21 @@ ] } }, - "/api/edge/instructions/upgrade/{edgeVersion}/{method}": { + "/api/edges/enabled": { "get": { "tags": [ "edge-controller" ], - "summary": "Get Edge Upgrade Instructions (getEdgeUpgradeInstructions)", - "description": "Get an upgrade instructions for provided edge version.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getEdgeUpgradeInstructions", - "parameters": [ - { - "name": "edgeVersion", - "in": "path", - "description": "Edge version", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "method", - "in": "path", - "description": "Upgrade method ('docker', 'ubuntu' or 'centos')", - "required": true, - "schema": { - "type": "string", - "enum": [ - "docker", - "ubuntu", - "centos" - ] - } - } - ], + "summary": "Is edges support enabled (isEdgesSupportEnabled)", + "description": "Returns 'true' if edges support enabled on server, 'false' - otherwise.", + "operationId": "isEdgesSupportEnabled", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EdgeInstructions" + "type": "boolean" } } } @@ -32752,22 +32545,25 @@ ] } }, - "/api/edge/missingToRelatedRuleChains/{edgeId}": { + "/api/edges/list": { "get": { "tags": [ "edge-controller" ], - "summary": "Find missing rule chains (findMissingToRelatedRuleChains)", - "description": "Returns list of rule chains ids that are not assigned to particular edge, but these rule chains are present in the already assigned rule chains to edge.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "findMissingToRelatedRuleChains", + "summary": "Get Edges By Ids (getEdgeList)", + "description": "Requested edges must be owned by tenant or assigned to customer which user is performing the request.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getEdgeList", "parameters": [ { - "name": "edgeId", - "in": "path", - "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "name": "edgeIds", + "in": "query", + "description": "A list of edges ids, separated by comma ','", "required": true, "schema": { - "type": "string" + "type": "array", + "items": { + "type": "string" + } } } ], @@ -32777,7 +32573,10 @@ "content": { "application/json": { "schema": { - "type": "string" + "type": "array", + "items": { + "$ref": "#/components/schemas/Edge" + } } } } @@ -32898,19 +32697,19 @@ ] } }, - "/api/edge/sync/{edgeId}": { - "post": { + "/api/tenant/edge": { + "get": { "tags": [ "edge-controller" ], - "summary": "Sync edge (syncEdge)", - "description": "Starts synchronization process between edge and cloud. \nAll entities that are assigned to particular edge are going to be send to remote edge service.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "syncEdge", + "summary": "Get Tenant Edge by name (getTenantEdgeByName)", + "description": "Requested edge must be owned by tenant or customer that the user belongs to. Edge name is an unique property of edge. So it can be used to identify the edge.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getTenantEdgeByName", "parameters": [ { - "name": "edgeId", - "in": "path", - "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "name": "edgeName", + "in": "query", + "description": "Unique name of the edge", "required": true, "schema": { "type": "string" @@ -32923,7 +32722,7 @@ "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/Edge" } } } @@ -32940,7 +32739,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -33044,24 +32843,90 @@ ] } }, - "/api/edge/types": { + "/api/tenant/edgeInfos": { "get": { "tags": [ "edge-controller" ], - "summary": "Get Edge Types (getEdgeTypes)", - "description": "Returns a set of unique edge types based on edges that are either owned by the tenant or assigned to the customer which user is performing the request.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getEdgeTypes", + "summary": "Get Tenant Edge Infos (getTenantEdgeInfos)", + "description": "Returns a page of edges info objects owned by tenant. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. Edge Info is an extension of the default Edge object that contains information about the assigned customer name. \n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getTenantEdgeInfos", + "parameters": [ + { + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "type", + "in": "query", + "description": "A string value representing the edge type. For example, 'default'", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'substring' filter based on the edge name.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string", + "enum": [ + "createdTime", + "name", + "type", + "label", + "customerTitle" + ] + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ASC", + "DESC" + ] + } + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntitySubtype" - } + "$ref": "#/components/schemas/PageDataEdgeInfo" } } } @@ -33182,23 +33047,81 @@ ] } }, - "/api/edge/{edgeId}": { + "/api/tenant/edges": { "get": { "tags": [ "edge-controller" ], - "summary": "Get Edge (getEdgeById)", - "description": "Get the Edge object based on the provided Edge Id. If the user has the authority of 'Tenant Administrator', the server checks that the edge is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the edge is assigned to the same customer.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getEdgeById", + "summary": "Get Tenant Edges (getTenantEdges)", + "description": "Returns a page of edges owned by tenant. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getTenantEdges", "parameters": [ { - "name": "edgeId", - "in": "path", - "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "type", + "in": "query", + "description": "A string value representing the edge type. For example, 'default'", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'substring' filter based on the edge name.", + "required": false, "schema": { "type": "string" } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string", + "enum": [ + "createdTime", + "name", + "type", + "label", + "customerTitle" + ] + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ASC", + "DESC" + ] + } } ], "responses": { @@ -33207,7 +33130,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Edge" + "$ref": "#/components/schemas/PageDataEdge" } } } @@ -33326,14 +33249,16 @@ "ApiKeyForm": [] } ] - }, - "delete": { + } + }, + "/api/edge/{edgeId}/events": { + "get": { "tags": [ - "edge-controller" + "edge-event-controller" ], - "summary": "Delete edge (deleteEdge)", - "description": "Deletes the edge. Referencing non-existing edge Id will cause an error.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "deleteEdge", + "summary": "Get Edge Events (getEdgeEvents)", + "description": "Returns a page of edge events for the requested edge. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. ", + "operationId": "getEdgeEvents", "parameters": [ { "name": "edgeId", @@ -33343,11 +33268,96 @@ "schema": { "type": "string" } + }, + { + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'substring' filter based on the edge event type name.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string", + "enum": [ + "createdTime", + "name", + "type", + "label", + "customerTitle" + ] + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ASC", + "DESC" + ] + } + }, + { + "name": "startTime", + "in": "query", + "description": "Timestamp. Edge events with creation time before it won't be queried", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "endTime", + "in": "query", + "description": "Timestamp. Edge events with creation time after it won't be queried", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageDataEdgeEvent" + } + } + } }, "400": { "description": "Bad Request", @@ -33465,32 +33475,24 @@ ] } }, - "/api/edge/{edgeId}/upgrade/available": { + "/api/entities/vc/branches": { "get": { "tags": [ - "edge-controller" - ], - "summary": "Is edge upgrade enabled (isEdgeUpgradeAvailable)", - "description": "Returns 'true' if upgrade available for connected edge, 'false' - otherwise.", - "operationId": "isEdgeUpgradeAvailable", - "parameters": [ - { - "name": "edgeId", - "in": "path", - "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - } + "entities-version-control-controller" ], + "summary": "List branches (listBranches)", + "description": "Lists branches available in the remote repository. \n\nResponse example: \n```json\n[\n {\n \"name\": \"master\",\n \"default\": true\n },\n {\n \"name\": \"dev\",\n \"default\": false\n },\n {\n \"name\": \"dev-2\",\n \"default\": false\n }\n]\n```", + "operationId": "listBranches", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "boolean" + "type": "array", + "items": { + "$ref": "#/components/schemas/BranchInfo" + } } } } @@ -33611,28 +33613,38 @@ ] } }, - "/api/edge/{edgeId}/{ruleChainId}/root": { - "post": { + "/api/entities/vc/diff/{entityType}/{internalEntityUuid}": { + "get": { "tags": [ - "edge-controller" + "entities-version-control-controller" ], - "summary": "Set root rule chain for provided edge (setEdgeRootRuleChain)", - "description": "Change root rule chain of the edge to the new provided rule chain. \nThis operation will send a notification to update root rule chain on remote edge service.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "setEdgeRootRuleChain", + "summary": "Compare entity data to version (compareEntityDataToVersion)", + "description": "Returns an object with current entity data and the one at a specific version. Entity data structure is the same as stored in a repository. \n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "compareEntityDataToVersion", "parameters": [ { - "name": "edgeId", + "name": "entityType", "in": "path", - "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "A string value representing the entity type. For example, 'DEVICE'", "required": true, "schema": { - "type": "string" + "$ref": "#/components/schemas/EntityType" } }, { - "name": "ruleChainId", + "name": "internalEntityUuid", "in": "path", - "description": "A string value representing the rule chain id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "versionId", + "in": "query", + "description": "Version id, for example fd82625bdd7d6131cf8027b44ee967012ecaf990. Represents commit hash.", "required": true, "schema": { "type": "string" @@ -33645,7 +33657,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Edge" + "$ref": "#/components/schemas/EntityDataDiff" } } } @@ -33662,7 +33674,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -33766,81 +33778,32 @@ ] } }, - "/api/edges": { - "get": { + "/api/entities/vc/entity": { + "post": { "tags": [ - "edge-controller" + "entities-version-control-controller" ], - "summary": "Get Tenant Edges (getEdges)", - "description": "Returns a page of edges owned by tenant. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getEdges", - "parameters": [ - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'substring' filter based on the edge name.", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string", - "enum": [ - "createdTime", - "name", - "type", - "label", - "customerTitle" - ] + "summary": "Load entities version (loadEntitiesVersion)", + "description": "Loads specific version of remote entities (or single entity) by request. Supported entity types: CUSTOMER, ASSET, RULE_CHAIN, DASHBOARD, DEVICE_PROFILE, DEVICE, ENTITY_VIEW, WIDGETS_BUNDLE.\n\nThere are multiple types of request. Each of them requires branch name (`branch`) and version id (`versionId`). Request of type `SINGLE_ENTITY` is needed to restore a concrete version of a specific entity. It contains id of a remote entity (`externalEntityId`) and additional configuration (`config`):\n- `loadRelations` - to update relations list (in case `saveRelations` option was enabled during version creation);\n- `loadAttributes` - to load entity attributes (if `saveAttributes` config option was enabled);\n- `loadCredentials` - to update device credentials (if `saveCredentials` option was enabled during version creation).\n\nAn example of such request:\n```json\n{\n \"type\": \"SINGLE_ENTITY\",\n \n \"branch\": \"dev\",\n \"versionId\": \"b3c28d722d328324c7c15b0b30047b0c40011cf7\",\n \n \"externalEntityId\": {\n \"entityType\": \"DEVICE\",\n \"id\": \"b7944123-d4f4-11ec-847b-0f432358ab48\"\n },\n \"config\": {\n \"loadRelations\": false,\n \"loadAttributes\": true,\n \"loadCredentials\": true\n }\n}\n```\n\nAnother request type (`ENTITY_TYPE`) is needed to load specific version of the whole entity types. It contains a structure with entity types to load and configs for each entity type (`entityTypes`). For each specified entity type, the method will load all remote entities of this type that are present at the version. A config for each entity type contains the same options as in `SINGLE_ENTITY` request type, and additionally contains following options:\n- `removeOtherEntities` - to remove local entities that are not present on the remote - basically to overwrite local entity type with the remote one;\n- `findExistingEntityByName` - when you are loading some remote entities that are not yet present at this tenant, try to find existing entity by name and update it rather than create new.\n\nHere is an example of the request to completely restore version of the whole device entity type:\n```json\n{\n \"type\": \"ENTITY_TYPE\",\n\n \"branch\": \"dev\",\n \"versionId\": \"b3c28d722d328324c7c15b0b30047b0c40011cf7\",\n\n \"entityTypes\": {\n \"DEVICE\": {\n \"removeOtherEntities\": true,\n \"findExistingEntityByName\": false,\n \"loadRelations\": true,\n \"loadAttributes\": true,\n \"loadCredentials\": true\n }\n }\n}\n```\n\nThe response will contain generated request UUID that is to be used to check the status of operation via `getVersionLoadRequestStatus`.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "loadEntitiesVersion", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VersionLoadRequest" + } } }, - { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] - } - } - ], + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEdge" + "type": "string", + "format": "uuid" } } } @@ -33857,7 +33820,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -33959,24 +33922,36 @@ "ApiKeyForm": [] } ] - }, - "post": { + } + }, + "/api/entities/vc/entity/{entityType}/{versionId}": { + "get": { "tags": [ - "edge-controller" + "entities-version-control-controller" ], - "summary": "Find related edges (findEdgesByQuery)", - "description": "Returns all edges that are related to the specific entity. The entity id, relation type, edge types, depth of the search, and other query parameters defined using complex 'EdgeSearchQuery' object. See 'Model' tab of the Parameters for more info.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "findEdgesByQuery", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EdgeSearchQuery" - } + "summary": "List entities at version (listEntitiesAtVersion)", + "description": "Returns a list of remote entities of a specific entity type that are available at a concrete version. \nEach entity item in the result has `externalId` property. Entities order will be the same as in the repository.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "listEntitiesAtVersion", + "parameters": [ + { + "name": "entityType", + "in": "path", + "description": "A string value representing the entity type. For example, 'DEVICE'", + "required": true, + "schema": { + "$ref": "#/components/schemas/EntityType" } }, - "required": true - }, + { + "name": "versionId", + "in": "path", + "description": "Version id, for example fd82625bdd7d6131cf8027b44ee967012ecaf990. Represents commit hash.", + "required": true, + "schema": { + "type": "string" + } + } + ], "responses": { "200": { "description": "OK", @@ -33985,7 +33960,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/Edge" + "$ref": "#/components/schemas/VersionedEntityInfo" } } } @@ -34003,7 +33978,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -34107,21 +34082,33 @@ ] } }, - "/api/edges/enabled": { + "/api/entities/vc/entity/{requestId}/status": { "get": { "tags": [ - "edge-controller" + "entities-version-control-controller" + ], + "summary": "Get version load request status (getVersionLoadRequestStatus)", + "description": "Returns the status of previously made version load request. The structure contains following parameters:\n- `done` - if the request was successfully processed;\n- `result` - a list of load results for each entity type:\n - `created` - created entities count;\n - `updated` - updated entities count;\n - `deleted` - removed entities count.\n- `error` - if an error occurred during processing, error info:\n - `type` - error type;\n - `source` - an external id of remote entity;\n - `target` - if failed to find referenced entity by external id - this external id;\n - `message` - error message.\n\nAn example of successfully processed request status:\n```json\n{\n \"done\": true,\n \"result\": [\n {\n \"entityType\": \"DEVICE\",\n \"created\": 10,\n \"updated\": 5,\n \"deleted\": 5\n },\n {\n \"entityType\": \"ASSET\",\n \"created\": 4,\n \"updated\": 0,\n \"deleted\": 8\n }\n ]\n}\n```\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getVersionLoadRequestStatus", + "parameters": [ + { + "name": "requestId", + "in": "path", + "description": "A string value representing the version control request id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } ], - "summary": "Is edges support enabled (isEdgesSupportEnabled)", - "description": "Returns 'true' if edges support enabled on server, 'false' - otherwise.", - "operationId": "isEdgesSupportEnabled", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "boolean" + "$ref": "#/components/schemas/VersionLoadResult" } } } @@ -34242,25 +34229,22 @@ ] } }, - "/api/edges/list": { + "/api/entities/vc/entity/{versionId}": { "get": { "tags": [ - "edge-controller" + "entities-version-control-controller" ], - "summary": "Get Edges By Ids (getEdgeList)", - "description": "Requested edges must be owned by tenant or assigned to customer which user is performing the request.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getEdgeList", + "summary": "List all entities at version (listAllEntitiesAtVersion)", + "description": "Returns a list of all remote entities available in a specific version. Response type is the same as for listAllEntitiesAtVersion API method. \nReturned entities order will be the same as in the repository.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "listAllEntitiesAtVersion", "parameters": [ { - "name": "edgeIds", - "in": "query", - "description": "A list of edges ids, separated by comma ','", + "name": "versionId", + "in": "path", + "description": "Version id, for example fd82625bdd7d6131cf8027b44ee967012ecaf990. Represents commit hash.", "required": true, "schema": { - "type": "array", - "items": { - "type": "string" - } + "type": "string" } } ], @@ -34272,7 +34256,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/Edge" + "$ref": "#/components/schemas/VersionedEntityInfo" } } } @@ -34394,23 +34378,42 @@ ] } }, - "/api/tenant/edge": { + "/api/entities/vc/info/{versionId}/{entityType}/{externalEntityUuid}": { "get": { "tags": [ - "edge-controller" + "entities-version-control-controller" ], - "summary": "Get Tenant Edge by name (getTenantEdgeByName)", - "description": "Requested edge must be owned by tenant or customer that the user belongs to. Edge name is an unique property of edge. So it can be used to identify the edge.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getTenantEdgeByName", + "summary": "Get entity data info (getEntityDataInfo)", + "description": "Retrieves short info about the remote entity by external id at a concrete version. \nReturned entity data info contains following properties: `hasRelations` (whether stored entity data contains relations), `hasAttributes` (contains attributes) and `hasCredentials` (whether stored device data has credentials).\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getEntityDataInfo", "parameters": [ { - "name": "edgeName", - "in": "query", - "description": "Unique name of the edge", + "name": "versionId", + "in": "path", + "description": "Version id, for example fd82625bdd7d6131cf8027b44ee967012ecaf990. Represents commit hash.", "required": true, "schema": { "type": "string" } + }, + { + "name": "entityType", + "in": "path", + "description": "A string value representing the entity type. For example, 'DEVICE'", + "required": true, + "schema": { + "$ref": "#/components/schemas/EntityType" + } + }, + { + "name": "externalEntityUuid", + "in": "path", + "description": "A string value representing external entity id", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], "responses": { @@ -34419,7 +34422,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Edge" + "$ref": "#/components/schemas/EntityDataInfo" } } } @@ -34540,15 +34543,24 @@ ] } }, - "/api/tenant/edgeInfos": { + "/api/entities/vc/version": { "get": { "tags": [ - "edge-controller" + "entities-version-control-controller" ], - "summary": "Get Tenant Edge Infos (getTenantEdgeInfos)", - "description": "Returns a page of edges info objects owned by tenant. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. Edge Info is an extension of the default Edge object that contains information about the assigned customer name. \n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getTenantEdgeInfos", + "summary": "List all versions (listVersions)", + "description": "Lists all available versions in a branch for all entity types. \nIf specified branch does not exist - empty page data will be returned. The response format is the same as for `listEntityVersions` API method.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "listVersions", "parameters": [ + { + "name": "branch", + "in": "query", + "description": "The name of the working branch, for example 'master'", + "required": true, + "schema": { + "type": "string" + } + }, { "name": "pageSize", "in": "query", @@ -34569,19 +34581,10 @@ "format": "int32" } }, - { - "name": "type", - "in": "query", - "description": "A string value representing the edge type. For example, 'default'", - "required": false, - "schema": { - "type": "string" - } - }, { "name": "textSearch", "in": "query", - "description": "The case insensitive 'substring' filter based on the edge name.", + "description": "The case insensitive 'substring' filter based on the entity version name.", "required": false, "schema": { "type": "string" @@ -34595,11 +34598,7 @@ "schema": { "type": "string", "enum": [ - "createdTime", - "name", - "type", - "label", - "customerTitle" + "timestamp" ] } }, @@ -34623,7 +34622,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEdgeInfo" + "$ref": "#/components/schemas/PageDataEntityVersion" } } } @@ -34742,92 +34741,32 @@ "ApiKeyForm": [] } ] - } - }, - "/api/tenant/edges": { - "get": { + }, + "post": { "tags": [ - "edge-controller" + "entities-version-control-controller" ], - "summary": "Get Tenant Edges (getTenantEdges)", - "description": "Returns a page of edges owned by tenant. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getTenantEdges", - "parameters": [ - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "type", - "in": "query", - "description": "A string value representing the edge type. For example, 'default'", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'substring' filter based on the edge name.", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string", - "enum": [ - "createdTime", - "name", - "type", - "label", - "customerTitle" - ] + "summary": "Save entities version (saveEntitiesVersion)", + "description": "Creates a new version of entities (or a single entity) by request.\nSupported entity types: CUSTOMER, ASSET, RULE_CHAIN, DASHBOARD, DEVICE_PROFILE, DEVICE, ENTITY_VIEW, WIDGETS_BUNDLE.\n\nThere are two available types of request: `SINGLE_ENTITY` and `COMPLEX`. Each of them contains version name (`versionName`) and name of a branch (`branch`) to create version (commit) in. If specified branch does not exists in a remote repo, then new empty branch will be created. Request of the `SINGLE_ENTITY` type has id of an entity (`entityId`) and additional configuration (`config`) which has following options: \n- `saveRelations` - whether to add inbound and outbound relations of type COMMON to created entity version;\n- `saveAttributes` - to save attributes of server scope (and also shared scope for devices);\n- `saveCredentials` - when saving a version of a device, to add its credentials to the version.\n\nAn example of a `SINGLE_ENTITY` version create request:\n```json\n{\n \"type\": \"SINGLE_ENTITY\",\n\n \"versionName\": \"Version 1.0\",\n \"branch\": \"dev\",\n\n \"entityId\": {\n \"entityType\": \"DEVICE\",\n \"id\": \"b79448e0-d4f4-11ec-847b-0f432358ab48\"\n },\n \"config\": {\n \"saveRelations\": true,\n \"saveAttributes\": true,\n \"saveCredentials\": false\n }\n}\n```\n\nSecond request type (`COMPLEX`), additionally to `branch` and `versionName`, contains following properties:\n- `entityTypes` - a structure with entity types to export and configuration for each entity type; this configuration has all the options available for `SINGLE_ENTITY` and additionally has these ones: \n - `allEntities` and `entityIds` - if you want to save the version of all entities of the entity type then set `allEntities` param to true, otherwise set it to false and specify the list of specific entities (`entityIds`);\n - `syncStrategy` - synchronization strategy to use for this entity type: when set to `OVERWRITE` then the list of remote entities of this type will be overwritten by newly added entities. If set to `MERGE` - existing remote entities of this entity type will not be removed, new entities will just be added on top (or existing remote entities will be updated).\n- `syncStrategy` - default synchronization strategy to use when it is not specified for an entity type.\n\nExample for this type of request:\n```json\n{\n \"type\": \"COMPLEX\",\n\n \"versionName\": \"Devices and profiles: release 2\",\n \"branch\": \"master\",\n\n \"syncStrategy\": \"OVERWRITE\",\n \"entityTypes\": {\n \"DEVICE\": {\n \"syncStrategy\": null,\n \"allEntities\": true,\n \"saveRelations\": true,\n \"saveAttributes\": true,\n \"saveCredentials\": true\n },\n \"DEVICE_PROFILE\": {\n \"syncStrategy\": \"MERGE\",\n \"allEntities\": false,\n \"entityIds\": [\n \"b79448e0-d4f4-11ec-847b-0f432358ab48\"\n ],\n \"saveRelations\": true\n }\n }\n}\n```\n\nResponse wil contain generated request UUID, that can be then used to retrieve status of operation via `getVersionCreateRequestStatus`.\n\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "saveEntitiesVersion", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VersionCreateRequest" + } } }, - { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] - } - } - ], + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEdge" + "type": "string", + "format": "uuid" } } } @@ -34844,7 +34783,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -34948,19 +34887,28 @@ ] } }, - "/api/edge/{edgeId}/events": { + "/api/entities/vc/version/{entityType}": { "get": { "tags": [ - "edge-event-controller" + "entities-version-control-controller" ], - "summary": "Get Edge Events (getEdgeEvents)", - "description": "Returns a page of edge events for the requested edge. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. ", - "operationId": "getEdgeEvents", + "summary": "List entity type versions (listEntityTypeVersions)", + "description": "Returns list of versions of an entity type in a branch. This is a collected list of versions that were created for entities of this type in a remote branch. \nIf specified branch does not exist - empty page data will be returned. The response structure is the same as for `listEntityVersions` API method.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "listEntityTypeVersions", "parameters": [ { - "name": "edgeId", + "name": "entityType", "in": "path", - "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "A string value representing the entity type. For example, 'DEVICE'", + "required": true, + "schema": { + "$ref": "#/components/schemas/EntityType" + } + }, + { + "name": "branch", + "in": "query", + "description": "The name of the working branch, for example 'master'", "required": true, "schema": { "type": "string" @@ -34989,7 +34937,7 @@ { "name": "textSearch", "in": "query", - "description": "The case insensitive 'substring' filter based on the edge event type name.", + "description": "The case insensitive 'substring' filter based on the entity version name.", "required": false, "schema": { "type": "string" @@ -35003,11 +34951,7 @@ "schema": { "type": "string", "enum": [ - "createdTime", - "name", - "type", - "label", - "customerTitle" + "timestamp" ] } }, @@ -35023,26 +34967,6 @@ "DESC" ] } - }, - { - "name": "startTime", - "in": "query", - "description": "Timestamp. Edge events with creation time before it won't be queried", - "required": false, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "endTime", - "in": "query", - "description": "Timestamp. Edge events with creation time after it won't be queried", - "required": false, - "schema": { - "type": "integer", - "format": "int64" - } } ], "responses": { @@ -35051,7 +34975,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEdgeEvent" + "$ref": "#/components/schemas/PageDataEntityVersion" } } } @@ -35172,24 +35096,105 @@ ] } }, - "/api/entities/vc/branches": { + "/api/entities/vc/version/{entityType}/{externalEntityUuid}": { "get": { "tags": [ "entities-version-control-controller" ], - "summary": "List branches (listBranches)", - "description": "Lists branches available in the remote repository. \n\nResponse example: \n```json\n[\n {\n \"name\": \"master\",\n \"default\": true\n },\n {\n \"name\": \"dev\",\n \"default\": false\n },\n {\n \"name\": \"dev-2\",\n \"default\": false\n }\n]\n```", - "operationId": "listBranches", + "summary": "List entity versions (listEntityVersions)", + "description": "Returns list of versions for a specific entity in a concrete branch. \nYou need to specify external id of an entity to list versions for. This is `externalId` property of an entity, or otherwise if not set - simply id of this entity. \nIf specified branch does not exist - empty page data will be returned. \n\nEach version info item has timestamp, id, name and author. Version id can then be used to restore the version. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nResponse example: \n```json\n{\n \"data\": [\n {\n \"timestamp\": 1655198593000,\n \"id\": \"fd82625bdd7d6131cf8027b44ee967012ecaf990\",\n \"name\": \"Devices and assets - v2.0\",\n \"author\": \"John Doe (johndoe@gmail.com)\"\n },\n {\n \"timestamp\": 1655198528000,\n \"id\": \"682adcffa9c8a2f863af6f00c4850323acbd4219\",\n \"name\": \"Update my device\",\n \"author\": \"John Doe (johndoe@gmail.com)\"\n },\n {\n \"timestamp\": 1655198280000,\n \"id\": \"d2a6087c2b30e18cc55e7cdda345a8d0dfb959a4\",\n \"name\": \"Devices and assets - v1.0\",\n \"author\": \"John Doe (johndoe@gmail.com)\"\n }\n ],\n \"totalPages\": 1,\n \"totalElements\": 3,\n \"hasNext\": false\n}\n```\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "listEntityVersions", + "parameters": [ + { + "name": "entityType", + "in": "path", + "description": "A string value representing the entity type. For example, 'DEVICE'", + "required": true, + "schema": { + "$ref": "#/components/schemas/EntityType" + } + }, + { + "name": "externalEntityUuid", + "in": "path", + "description": "A string value representing external entity id. This is `externalId` property of an entity, or otherwise if not set - simply id of this entity.", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "branch", + "in": "query", + "description": "The name of the working branch, for example 'master'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'substring' filter based on the entity version name.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string", + "enum": [ + "timestamp" + ] + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ASC", + "DESC" + ] + } + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/BranchInfo" - } + "$ref": "#/components/schemas/PageDataEntityVersion" } } } @@ -35310,42 +35315,24 @@ ] } }, - "/api/entities/vc/diff/{entityType}/{internalEntityUuid}": { + "/api/entities/vc/version/{requestId}/status": { "get": { "tags": [ "entities-version-control-controller" ], - "summary": "Compare entity data to version (compareEntityDataToVersion)", - "description": "Returns an object with current entity data and the one at a specific version. Entity data structure is the same as stored in a repository. \n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "compareEntityDataToVersion", + "summary": "Get version create request status (getVersionCreateRequestStatus)", + "description": "Returns the status of previously made version create request. \n\nThis status contains following properties:\n- `done` - whether request processing is finished;\n- `version` - created version info: timestamp, version id (commit hash), commit name and commit author;\n- `added` - count of items that were created in the remote repo;\n- `modified` - modified items count;\n- `removed` - removed items count;\n- `error` - error message, if an error occurred while handling the request.\n\nAn example of successful status:\n```json\n{\n \"done\": true,\n \"added\": 10,\n \"modified\": 2,\n \"removed\": 5,\n \"version\": {\n \"timestamp\": 1655198528000,\n \"id\":\"8a834dd389ed80e0759ba8ee338b3f1fd160a114\",\n \"name\": \"My devices v2.0\",\n \"author\": \"John Doe\"\n },\n \"error\": null\n}\n```\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getVersionCreateRequestStatus", "parameters": [ { - "name": "entityType", - "in": "path", - "description": "A string value representing the entity type. For example, 'DEVICE'", - "required": true, - "schema": { - "$ref": "#/components/schemas/EntityType" - } - }, - { - "name": "internalEntityUuid", + "name": "requestId", "in": "path", - "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "A string value representing the version control request id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string", "format": "uuid" } - }, - { - "name": "versionId", - "in": "query", - "description": "Version id, for example fd82625bdd7d6131cf8027b44ee967012ecaf990. Represents commit hash.", - "required": true, - "schema": { - "type": "string" - } } ], "responses": { @@ -35354,7 +35341,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EntityDataDiff" + "$ref": "#/components/schemas/VersionCreationResult" } } } @@ -35475,19 +35462,19 @@ ] } }, - "/api/entities/vc/entity": { + "/api/alarmsQuery/count": { "post": { "tags": [ - "entities-version-control-controller" + "entity-query-controller" ], - "summary": "Load entities version (loadEntitiesVersion)", - "description": "Loads specific version of remote entities (or single entity) by request. Supported entity types: CUSTOMER, ASSET, RULE_CHAIN, DASHBOARD, DEVICE_PROFILE, DEVICE, ENTITY_VIEW, WIDGETS_BUNDLE.\n\nThere are multiple types of request. Each of them requires branch name (`branch`) and version id (`versionId`). Request of type `SINGLE_ENTITY` is needed to restore a concrete version of a specific entity. It contains id of a remote entity (`externalEntityId`) and additional configuration (`config`):\n- `loadRelations` - to update relations list (in case `saveRelations` option was enabled during version creation);\n- `loadAttributes` - to load entity attributes (if `saveAttributes` config option was enabled);\n- `loadCredentials` - to update device credentials (if `saveCredentials` option was enabled during version creation).\n\nAn example of such request:\n```json\n{\n \"type\": \"SINGLE_ENTITY\",\n \n \"branch\": \"dev\",\n \"versionId\": \"b3c28d722d328324c7c15b0b30047b0c40011cf7\",\n \n \"externalEntityId\": {\n \"entityType\": \"DEVICE\",\n \"id\": \"b7944123-d4f4-11ec-847b-0f432358ab48\"\n },\n \"config\": {\n \"loadRelations\": false,\n \"loadAttributes\": true,\n \"loadCredentials\": true\n }\n}\n```\n\nAnother request type (`ENTITY_TYPE`) is needed to load specific version of the whole entity types. It contains a structure with entity types to load and configs for each entity type (`entityTypes`). For each specified entity type, the method will load all remote entities of this type that are present at the version. A config for each entity type contains the same options as in `SINGLE_ENTITY` request type, and additionally contains following options:\n- `removeOtherEntities` - to remove local entities that are not present on the remote - basically to overwrite local entity type with the remote one;\n- `findExistingEntityByName` - when you are loading some remote entities that are not yet present at this tenant, try to find existing entity by name and update it rather than create new.\n\nHere is an example of the request to completely restore version of the whole device entity type:\n```json\n{\n \"type\": \"ENTITY_TYPE\",\n\n \"branch\": \"dev\",\n \"versionId\": \"b3c28d722d328324c7c15b0b30047b0c40011cf7\",\n\n \"entityTypes\": {\n \"DEVICE\": {\n \"removeOtherEntities\": true,\n \"findExistingEntityByName\": false,\n \"loadRelations\": true,\n \"loadAttributes\": true,\n \"loadCredentials\": true\n }\n }\n}\n```\n\nThe response will contain generated request UUID that is to be used to check the status of operation via `getVersionLoadRequestStatus`.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "loadEntitiesVersion", + "summary": "Count Alarms by Query (countAlarmsByQuery)", + "description": "Returns the number of alarms that match the query definition.", + "operationId": "countAlarmsByQuery", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/VersionLoadRequest" + "$ref": "#/components/schemas/AlarmCountQuery" } } }, @@ -35499,8 +35486,8 @@ "content": { "application/json": { "schema": { - "type": "string", - "format": "uuid" + "type": "integer", + "format": "int64" } } } @@ -35621,44 +35608,31 @@ ] } }, - "/api/entities/vc/entity/{entityType}/{versionId}": { - "get": { + "/api/alarmsQuery/find": { + "post": { "tags": [ - "entities-version-control-controller" + "entity-query-controller" ], - "summary": "List entities at version (listEntitiesAtVersion)", - "description": "Returns a list of remote entities of a specific entity type that are available at a concrete version. \nEach entity item in the result has `externalId` property. Entities order will be the same as in the repository.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "listEntitiesAtVersion", - "parameters": [ - { - "name": "entityType", - "in": "path", - "description": "A string value representing the entity type. For example, 'DEVICE'", - "required": true, - "schema": { - "$ref": "#/components/schemas/EntityType" + "summary": "Find Alarms by Query", + "description": "This method description defines how Alarm Data Query extends the Entity Data Query. See method 'Find Entity Data by Query' first to get the info about 'Entity Data Query'.\n\n The platform will first search the entities that match the entity and key filters. Then, the platform will use 'Alarm Page Link' to filter the alarms related to those entities. Finally, platform fetch the properties of alarm that are defined in the **'alarmFields'** and combine them with the other entity, attribute and latest time series fields to return the result. \n\n See example of the alarm query below. The query will search first 100 active alarms with type 'Temperature Alarm' or 'Fire Alarm' for any device with current temperature > 0. The query will return combination of the entity fields: name of the device, device model and latest temperature reading and alarms fields: createdTime, type, severity and status: \n\n```json\n{\n \"entityFilter\": {\n \"type\": \"entityType\",\n \"resolveMultiple\": true,\n \"entityType\": \"DEVICE\"\n },\n \"pageLink\": {\n \"page\": 0,\n \"pageSize\": 100,\n \"textSearch\": null,\n \"searchPropagatedAlarms\": false,\n \"statusList\": [\n \"ACTIVE\"\n ],\n \"severityList\": [\n \"CRITICAL\",\n \"MAJOR\"\n ],\n \"typeList\": [\n \"Temperature Alarm\",\n \"Fire Alarm\"\n ],\n \"sortOrder\": {\n \"key\": {\n \"key\": \"createdTime\",\n \"type\": \"ALARM_FIELD\"\n },\n \"direction\": \"DESC\"\n },\n \"timeWindow\": 86400000\n },\n \"keyFilters\": [\n {\n \"key\": {\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n },\n \"valueType\": \"NUMERIC\",\n \"predicate\": {\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 0,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n }\n ],\n \"alarmFields\": [\n {\n \"type\": \"ALARM_FIELD\",\n \"key\": \"createdTime\"\n },\n {\n \"type\": \"ALARM_FIELD\",\n \"key\": \"type\"\n },\n {\n \"type\": \"ALARM_FIELD\",\n \"key\": \"severity\"\n },\n {\n \"type\": \"ALARM_FIELD\",\n \"key\": \"status\"\n }\n ],\n \"entityFields\": [\n {\n \"type\": \"ENTITY_FIELD\",\n \"key\": \"name\"\n }\n ],\n \"latestValues\": [\n {\n \"type\": \"ATTRIBUTE\",\n \"key\": \"model\"\n },\n {\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n }\n ]\n}\n```", + "operationId": "findAlarmDataByQuery", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AlarmDataQuery" + } } }, - { - "name": "versionId", - "in": "path", - "description": "Version id, for example fd82625bdd7d6131cf8027b44ee967012ecaf990. Represents commit hash.", - "required": true, - "schema": { - "type": "string" - } - } - ], + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/VersionedEntityInfo" - } + "$ref": "#/components/schemas/PageDataAlarmData" } } } @@ -35675,7 +35649,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -35779,33 +35753,20 @@ ] } }, - "/api/entities/vc/entity/{requestId}/status": { + "/api/edqs/state": { "get": { "tags": [ - "entities-version-control-controller" - ], - "summary": "Get version load request status (getVersionLoadRequestStatus)", - "description": "Returns the status of previously made version load request. The structure contains following parameters:\n- `done` - if the request was successfully processed;\n- `result` - a list of load results for each entity type:\n - `created` - created entities count;\n - `updated` - updated entities count;\n - `deleted` - removed entities count.\n- `error` - if an error occurred during processing, error info:\n - `type` - error type;\n - `source` - an external id of remote entity;\n - `target` - if failed to find referenced entity by external id - this external id;\n - `message` - error message.\n\nAn example of successfully processed request status:\n```json\n{\n \"done\": true,\n \"result\": [\n {\n \"entityType\": \"DEVICE\",\n \"created\": 10,\n \"updated\": 5,\n \"deleted\": 5\n },\n {\n \"entityType\": \"ASSET\",\n \"created\": 4,\n \"updated\": 0,\n \"deleted\": 8\n }\n ]\n}\n```\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getVersionLoadRequestStatus", - "parameters": [ - { - "name": "requestId", - "in": "path", - "description": "A string value representing the version control request id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } + "entity-query-controller" ], + "summary": "getEdqsState", + "operationId": "getEdqsState", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/VersionLoadResult" + "$ref": "#/components/schemas/EdqsState" } } } @@ -35926,38 +35887,26 @@ ] } }, - "/api/entities/vc/entity/{versionId}": { - "get": { + "/api/edqs/system/request": { + "post": { "tags": [ - "entities-version-control-controller" + "entity-query-controller" ], - "summary": "List all entities at version (listAllEntitiesAtVersion)", - "description": "Returns a list of all remote entities available in a specific version. Response type is the same as for listAllEntitiesAtVersion API method. \nReturned entities order will be the same as in the repository.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "listAllEntitiesAtVersion", - "parameters": [ - { - "name": "versionId", - "in": "path", - "description": "Version id, for example fd82625bdd7d6131cf8027b44ee967012ecaf990. Represents commit hash.", - "required": true, - "schema": { - "type": "string" + "summary": "processSystemEdqsRequest", + "operationId": "processSystemEdqsRequest", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ToCoreEdqsRequest" + } } - } - ], + }, + "required": true + }, "responses": { "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/VersionedEntityInfo" - } - } - } - } + "description": "OK" }, "400": { "description": "Bad Request", @@ -35971,7 +35920,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -36075,51 +36024,32 @@ ] } }, - "/api/entities/vc/info/{versionId}/{entityType}/{externalEntityUuid}": { - "get": { + "/api/entitiesQuery/count": { + "post": { "tags": [ - "entities-version-control-controller" + "entity-query-controller" ], - "summary": "Get entity data info (getEntityDataInfo)", - "description": "Retrieves short info about the remote entity by external id at a concrete version. \nReturned entity data info contains following properties: `hasRelations` (whether stored entity data contains relations), `hasAttributes` (contains attributes) and `hasCredentials` (whether stored device data has credentials).\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getEntityDataInfo", - "parameters": [ - { - "name": "versionId", - "in": "path", - "description": "Version id, for example fd82625bdd7d6131cf8027b44ee967012ecaf990. Represents commit hash.", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "entityType", - "in": "path", - "description": "A string value representing the entity type. For example, 'DEVICE'", - "required": true, - "schema": { - "$ref": "#/components/schemas/EntityType" + "summary": "Count Entities by Query", + "description": "Allows to run complex queries to search the count of platform entities (devices, assets, customers, etc) based on the combination of main entity filter and multiple key filters. Returns the number of entities that match the query definition.\n\n# Query Definition\n\n\n\nMain **entity filter** is mandatory and defines generic search criteria. For example, \"find all devices with profile 'Moisture Sensor'\" or \"Find all devices related to asset 'Building A'\"\n\nOptional **key filters** allow to filter results of the entity filter by complex criteria against main entity fields (name, label, type, etc), attributes and telemetry. For example, \"temperature > 20 or temperature< 10\" or \"name starts with 'T', and attribute 'model' is 'T1000', and time series field 'batteryLevel' > 40\".\n\nLet's review the example:\n\n```json\n{\n \"entityFilter\": {\n \"type\": \"entityType\",\n \"entityType\": \"DEVICE\"\n },\n \"keyFilters\": [\n {\n \"key\": {\n \"type\": \"ATTRIBUTE\",\n \"key\": \"active\"\n },\n \"valueType\": \"BOOLEAN\",\n \"predicate\": {\n \"operation\": \"EQUAL\",\n \"value\": {\n \"defaultValue\": true,\n \"dynamicValue\": null\n },\n \"type\": \"BOOLEAN\"\n }\n }\n ]\n}\n```\n\n Example mentioned above search all devices which have attribute 'active' set to 'true'. Now let's review available entity filters and key filters syntax:\n\n # Entity Filters\nEntity Filter body depends on the 'type' parameter. Let's review available entity filter types. In fact, they do correspond to available dashboard aliases.\n\n## Single Entity\n\nAllows to filter only one entity based on the id. For example, this entity filter selects certain device:\n\n```json\n{\n \"type\": \"singleEntity\",\n \"singleEntity\": {\n \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n \"entityType\": \"DEVICE\"\n }\n}\n```\n\n## Entity List Filter\n\nAllows to filter entities of the same type using their ids. For example, this entity filter selects two devices:\n\n```json\n{\n \"type\": \"entityList\",\n \"entityType\": \"DEVICE\",\n \"entityList\": [\n \"e6501f30-2a7a-11ec-94eb-213c95f54092\",\n \"e6657bf0-2a7a-11ec-94eb-213c95f54092\"\n ]\n}\n```\n\n## Entity Name Filter\n\nAllows to filter entities of the same type using the **'starts with'** expression over entity name. For example, this entity filter selects all devices which name starts with 'Air Quality':\n\n```json\n{\n \"type\": \"entityName\",\n \"entityType\": \"DEVICE\",\n \"entityNameFilter\": \"Air Quality\"\n}\n```\n\n## Entity Type Filter\n\nAllows to filter entities based on their type (CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, etc)For example, this entity filter selects all tenant customers:\n\n```json\n{\n \"type\": \"entityType\",\n \"entityType\": \"CUSTOMER\"\n}\n```\n\n## Asset Type Filter\n\nAllows to filter assets based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'charging station' assets which name starts with 'Tesla':\n\n```json\n{\n \"type\": \"assetType\",\n \"assetType\": \"charging station\",\n \"assetNameFilter\": \"Tesla\"\n}\n```\n\n## Device Type Filter\n\nAllows to filter devices based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Temperature Sensor' devices which name starts with 'ABC':\n\n```json\n{\n \"type\": \"deviceType\",\n \"deviceType\": \"Temperature Sensor\",\n \"deviceNameFilter\": \"ABC\"\n}\n```\n\n## Edge Type Filter\n\nAllows to filter edge instances based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Factory' edge instances which name starts with 'Nevada':\n\n```json\n{\n \"type\": \"edgeType\",\n \"edgeType\": \"Factory\",\n \"edgeNameFilter\": \"Nevada\"\n}\n```\n\n## Entity View Filter\n\nAllows to filter entity views based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Concrete Mixer' entity views which name starts with 'CAT':\n\n```json\n{\n \"type\": \"entityViewType\",\n \"entityViewType\": \"Concrete Mixer\",\n \"entityViewNameFilter\": \"CAT\"\n}\n```\n\n## Api Usage Filter\n\nAllows to query for Api Usage based on optional customer id. If the customer id is not set, returns current tenant API usage.For example, this entity filter selects the 'Api Usage' entity for customer with id 'e6501f30-2a7a-11ec-94eb-213c95f54092':\n\n```json\n{\n \"type\": \"apiUsageState\",\n \"customerId\": {\n \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n \"entityType\": \"CUSTOMER\"\n }\n}\n```\n\n## Relations Query Filter\n\nAllows to filter entities that are related to the provided root entity. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is > 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'filter' object allows you to define the relation type and set of acceptable entity types to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only those who match the 'filters'.\n\nFor example, this entity filter selects all devices and assets which are related to the asset with id 'e51de0c0-2a7a-11ec-94eb-213c95f54092':\n\n```json\n{\n \"type\": \"relationsQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e51de0c0-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 1,\n \"fetchLastLevelOnly\": false,\n \"filters\": [\n {\n \"relationType\": \"Contains\",\n \"entityTypes\": [\n \"DEVICE\",\n \"ASSET\"\n ]\n }\n ]\n}\n```\n\n## Asset Search Query\n\nAllows to filter assets that are related to the provided root entity. Filters related assets based on the relation type and set of asset types. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is > 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'relationType' defines the type of the relation to search for. The 'assetTypes' defines the type of the asset to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only assets that match 'relationType' and 'assetTypes' conditions.\n\nFor example, this entity filter selects 'charging station' assets which are related to the asset with id 'e51de0c0-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n```json\n{\n \"type\": \"assetSearchQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e51de0c0-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 1,\n \"fetchLastLevelOnly\": false,\n \"relationType\": \"Contains\",\n \"assetTypes\": [\n \"charging station\"\n ]\n}\n```\n\n## Device Search Query\n\nAllows to filter devices that are related to the provided root entity. Filters related devices based on the relation type and set of device types. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is > 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'relationType' defines the type of the relation to search for. The 'deviceTypes' defines the type of the device to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\nFor example, this entity filter selects 'Charging port' and 'Air Quality Sensor' devices which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n```json\n{\n \"type\": \"deviceSearchQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 2,\n \"fetchLastLevelOnly\": true,\n \"relationType\": \"Contains\",\n \"deviceTypes\": [\n \"Air Quality Sensor\",\n \"Charging port\"\n ]\n}\n```\n\n## Entity View Query\n\nAllows to filter entity views that are related to the provided root entity. Filters related entity views based on the relation type and set of entity view types. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is > 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'relationType' defines the type of the relation to search for. The 'entityViewTypes' defines the type of the entity view to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\nFor example, this entity filter selects 'Concrete mixer' entity views which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n```json\n{\n \"type\": \"entityViewSearchQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 1,\n \"fetchLastLevelOnly\": false,\n \"relationType\": \"Contains\",\n \"entityViewTypes\": [\n \"Concrete mixer\"\n ]\n}\n```\n\n## Edge Search Query\n\nAllows to filter edge instances that are related to the provided root entity. Filters related edge instances based on the relation type and set of edge types. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is > 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'relationType' defines the type of the relation to search for. The 'deviceTypes' defines the type of the device to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\nFor example, this entity filter selects 'Factory' edge instances which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n```json\n{\n \"type\": \"deviceSearchQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 2,\n \"fetchLastLevelOnly\": true,\n \"relationType\": \"Contains\",\n \"edgeTypes\": [\n \"Factory\"\n ]\n}\n```\n\n # Key Filters\nKey Filter allows you to define complex logical expressions over entity field, attribute or latest time series value. The filter is defined using 'key', 'valueType' and 'predicate' objects. Single Entity Query may have zero, one or multiple predicates. If multiple filters are defined, they are evaluated using logical 'AND'. The example below checks that temperature of the entity is above 20 degrees:\n\n```json\n{\n \"key\": {\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n },\n \"valueType\": \"NUMERIC\",\n \"predicate\": {\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 20,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n}\n```\n\n Now let's review 'key', 'valueType' and 'predicate' objects in detail.\n\n## Filter Key\n\nFilter Key defines either entity field, attribute or telemetry. It is a JSON object that consists the key name and type. The following filter key types are supported: \n\n * 'CLIENT_ATTRIBUTE' - used for client attributes; \n * 'SHARED_ATTRIBUTE' - used for shared attributes; \n * 'SERVER_ATTRIBUTE' - used for server attributes; \n * 'ATTRIBUTE' - used for any of the above; \n * 'TIME_SERIES' - used for time series values; \n * 'ENTITY_FIELD' - used for accessing entity fields like 'name', 'label', etc. The list of available fields depends on the entity type; \n * 'ALARM_FIELD' - similar to entity field, but is used in alarm queries only; \n\n\n Let's review the example:\n\n```json\n{\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n}\n```\n\n## Value Type and Operations\n\nProvides a hint about the data type of the entity field that is defined in the filter key. The value type impacts the list of possible operations that you may use in the corresponding predicate. For example, you may use 'STARTS_WITH' or 'END_WITH', but you can't use 'GREATER_OR_EQUAL' for string values.The following filter value types and corresponding predicate operations are supported: \n\n * 'STRING' - used to filter any 'String' or 'JSON' values. Operations: EQUAL, NOT_EQUAL, STARTS_WITH, ENDS_WITH, CONTAINS, NOT_CONTAINS; \n * 'NUMERIC' - used for 'Long' and 'Double' values. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n * 'BOOLEAN' - used for boolean values. Operations: EQUAL, NOT_EQUAL;\n * 'DATE_TIME' - similar to numeric, transforms value to milliseconds since epoch. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n\n\n## Filter Predicate\n\nFilter Predicate defines the logical expression to evaluate. The list of available operations depends on the filter value type, see above. Platform supports 4 predicate types: 'STRING', 'NUMERIC', 'BOOLEAN' and 'COMPLEX'. The last one allows to combine multiple operations over one filter key.\n\nSimple predicate example to check 'value < 100': \n\n```json\n{\n \"operation\": \"LESS\",\n \"value\": {\n \"defaultValue\": 100,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n}\n```\n\nComplex predicate example, to check 'value < 10 or value > 20': \n\n```json\n{\n \"type\": \"COMPLEX\",\n \"operation\": \"OR\",\n \"predicates\": [\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"defaultValue\": 10,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 20,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n ]\n}\n```\n\nMore complex predicate example, to check 'value < 10 or (value > 50 && value < 60)': \n\n```json\n{\n \"type\": \"COMPLEX\",\n \"operation\": \"OR\",\n \"predicates\": [\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"defaultValue\": 10,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"type\": \"COMPLEX\",\n \"operation\": \"AND\",\n \"predicates\": [\n {\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 50,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"defaultValue\": 60,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n ]\n }\n ]\n}\n```\n\n You may also want to replace hardcoded values (for example, temperature > 20) with the more dynamic expression (for example, temperature > 'value of the tenant attribute with key 'temperatureThreshold'). It is possible to use 'dynamicValue' to define attribute of the tenant, customer or user that is performing the API call. See example below: \n\n```json\n{\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 0,\n \"dynamicValue\": {\n \"sourceType\": \"CURRENT_USER\",\n \"sourceAttribute\": \"temperatureThreshold\"\n }\n },\n \"type\": \"NUMERIC\"\n}\n```\n\n Note that you may use 'CURRENT_USER', 'CURRENT_CUSTOMER' and 'CURRENT_TENANT' as a 'sourceType'. The 'defaultValue' is used when the attribute with such a name is not defined for the chosen source.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "countEntitiesByQuery", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityCountQuery" + } } }, - { - "name": "externalEntityUuid", - "in": "path", - "description": "A string value representing external entity id", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } - ], + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EntityDataInfo" + "type": "integer", + "format": "int64" } } } @@ -36136,7 +36066,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -36240,86 +36170,31 @@ ] } }, - "/api/entities/vc/version": { - "get": { + "/api/entitiesQuery/find": { + "post": { "tags": [ - "entities-version-control-controller" + "entity-query-controller" ], - "summary": "List all versions (listVersions)", - "description": "Lists all available versions in a branch for all entity types. \nIf specified branch does not exist - empty page data will be returned. The response format is the same as for `listEntityVersions` API method.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "listVersions", - "parameters": [ - { - "name": "branch", - "in": "query", - "description": "The name of the working branch, for example 'master'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'substring' filter based on the entity version name.", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string", - "enum": [ - "timestamp" - ] + "summary": "Find Entity Data by Query", + "description": "Allows to run complex queries over platform entities (devices, assets, customers, etc) based on the combination of main entity filter and multiple key filters. Returns the paginated result of the query that contains requested entity fields and latest values of requested attributes and time series data.\n\n# Query Definition\n\n\n\nMain **entity filter** is mandatory and defines generic search criteria. For example, \"find all devices with profile 'Moisture Sensor'\" or \"Find all devices related to asset 'Building A'\"\n\nOptional **key filters** allow to filter results of the **entity filter** by complex criteria against main entity fields (name, label, type, etc), attributes and telemetry. For example, \"temperature > 20 or temperature< 10\" or \"name starts with 'T', and attribute 'model' is 'T1000', and time series field 'batteryLevel' > 40\".\n\nThe **entity fields** and **latest values** contains list of entity fields and latest attribute/telemetry fields to fetch for each entity.\n\nThe **page link** contains information about the page to fetch and the sort ordering.\n\nLet's review the example:\n\n```json\n{\n \"entityFilter\": {\n \"type\": \"entityType\",\n \"resolveMultiple\": true,\n \"entityType\": \"DEVICE\"\n },\n \"keyFilters\": [\n {\n \"key\": {\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n },\n \"valueType\": \"NUMERIC\",\n \"predicate\": {\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 0,\n \"dynamicValue\": {\n \"sourceType\": \"CURRENT_USER\",\n \"sourceAttribute\": \"temperatureThreshold\",\n \"inherit\": false\n }\n },\n \"type\": \"NUMERIC\"\n }\n }\n ],\n \"entityFields\": [\n {\n \"type\": \"ENTITY_FIELD\",\n \"key\": \"name\"\n },\n {\n \"type\": \"ENTITY_FIELD\",\n \"key\": \"label\"\n },\n {\n \"type\": \"ENTITY_FIELD\",\n \"key\": \"additionalInfo\"\n }\n ],\n \"latestValues\": [\n {\n \"type\": \"ATTRIBUTE\",\n \"key\": \"model\"\n },\n {\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n }\n ],\n \"pageLink\": {\n \"page\": 0,\n \"pageSize\": 10,\n \"sortOrder\": {\n \"key\": {\n \"key\": \"name\",\n \"type\": \"ENTITY_FIELD\"\n },\n \"direction\": \"ASC\"\n }\n }\n}\n```\n\n Example mentioned above search all devices which have attribute 'active' set to 'true'. Now let's review available entity filters and key filters syntax:\n\n # Entity Filters\nEntity Filter body depends on the 'type' parameter. Let's review available entity filter types. In fact, they do correspond to available dashboard aliases.\n\n## Single Entity\n\nAllows to filter only one entity based on the id. For example, this entity filter selects certain device:\n\n```json\n{\n \"type\": \"singleEntity\",\n \"singleEntity\": {\n \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n \"entityType\": \"DEVICE\"\n }\n}\n```\n\n## Entity List Filter\n\nAllows to filter entities of the same type using their ids. For example, this entity filter selects two devices:\n\n```json\n{\n \"type\": \"entityList\",\n \"entityType\": \"DEVICE\",\n \"entityList\": [\n \"e6501f30-2a7a-11ec-94eb-213c95f54092\",\n \"e6657bf0-2a7a-11ec-94eb-213c95f54092\"\n ]\n}\n```\n\n## Entity Name Filter\n\nAllows to filter entities of the same type using the **'starts with'** expression over entity name. For example, this entity filter selects all devices which name starts with 'Air Quality':\n\n```json\n{\n \"type\": \"entityName\",\n \"entityType\": \"DEVICE\",\n \"entityNameFilter\": \"Air Quality\"\n}\n```\n\n## Entity Type Filter\n\nAllows to filter entities based on their type (CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, etc)For example, this entity filter selects all tenant customers:\n\n```json\n{\n \"type\": \"entityType\",\n \"entityType\": \"CUSTOMER\"\n}\n```\n\n## Asset Type Filter\n\nAllows to filter assets based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'charging station' assets which name starts with 'Tesla':\n\n```json\n{\n \"type\": \"assetType\",\n \"assetType\": \"charging station\",\n \"assetNameFilter\": \"Tesla\"\n}\n```\n\n## Device Type Filter\n\nAllows to filter devices based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Temperature Sensor' devices which name starts with 'ABC':\n\n```json\n{\n \"type\": \"deviceType\",\n \"deviceType\": \"Temperature Sensor\",\n \"deviceNameFilter\": \"ABC\"\n}\n```\n\n## Edge Type Filter\n\nAllows to filter edge instances based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Factory' edge instances which name starts with 'Nevada':\n\n```json\n{\n \"type\": \"edgeType\",\n \"edgeType\": \"Factory\",\n \"edgeNameFilter\": \"Nevada\"\n}\n```\n\n## Entity View Filter\n\nAllows to filter entity views based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Concrete Mixer' entity views which name starts with 'CAT':\n\n```json\n{\n \"type\": \"entityViewType\",\n \"entityViewType\": \"Concrete Mixer\",\n \"entityViewNameFilter\": \"CAT\"\n}\n```\n\n## Api Usage Filter\n\nAllows to query for Api Usage based on optional customer id. If the customer id is not set, returns current tenant API usage.For example, this entity filter selects the 'Api Usage' entity for customer with id 'e6501f30-2a7a-11ec-94eb-213c95f54092':\n\n```json\n{\n \"type\": \"apiUsageState\",\n \"customerId\": {\n \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n \"entityType\": \"CUSTOMER\"\n }\n}\n```\n\n## Relations Query Filter\n\nAllows to filter entities that are related to the provided root entity. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is > 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'filter' object allows you to define the relation type and set of acceptable entity types to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only those who match the 'filters'.\n\nFor example, this entity filter selects all devices and assets which are related to the asset with id 'e51de0c0-2a7a-11ec-94eb-213c95f54092':\n\n```json\n{\n \"type\": \"relationsQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e51de0c0-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 1,\n \"fetchLastLevelOnly\": false,\n \"filters\": [\n {\n \"relationType\": \"Contains\",\n \"entityTypes\": [\n \"DEVICE\",\n \"ASSET\"\n ]\n }\n ]\n}\n```\n\n## Asset Search Query\n\nAllows to filter assets that are related to the provided root entity. Filters related assets based on the relation type and set of asset types. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is > 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'relationType' defines the type of the relation to search for. The 'assetTypes' defines the type of the asset to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only assets that match 'relationType' and 'assetTypes' conditions.\n\nFor example, this entity filter selects 'charging station' assets which are related to the asset with id 'e51de0c0-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n```json\n{\n \"type\": \"assetSearchQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e51de0c0-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 1,\n \"fetchLastLevelOnly\": false,\n \"relationType\": \"Contains\",\n \"assetTypes\": [\n \"charging station\"\n ]\n}\n```\n\n## Device Search Query\n\nAllows to filter devices that are related to the provided root entity. Filters related devices based on the relation type and set of device types. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is > 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'relationType' defines the type of the relation to search for. The 'deviceTypes' defines the type of the device to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\nFor example, this entity filter selects 'Charging port' and 'Air Quality Sensor' devices which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n```json\n{\n \"type\": \"deviceSearchQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 2,\n \"fetchLastLevelOnly\": true,\n \"relationType\": \"Contains\",\n \"deviceTypes\": [\n \"Air Quality Sensor\",\n \"Charging port\"\n ]\n}\n```\n\n## Entity View Query\n\nAllows to filter entity views that are related to the provided root entity. Filters related entity views based on the relation type and set of entity view types. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is > 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'relationType' defines the type of the relation to search for. The 'entityViewTypes' defines the type of the entity view to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\nFor example, this entity filter selects 'Concrete mixer' entity views which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n```json\n{\n \"type\": \"entityViewSearchQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 1,\n \"fetchLastLevelOnly\": false,\n \"relationType\": \"Contains\",\n \"entityViewTypes\": [\n \"Concrete mixer\"\n ]\n}\n```\n\n## Edge Search Query\n\nAllows to filter edge instances that are related to the provided root entity. Filters related edge instances based on the relation type and set of edge types. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is > 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'relationType' defines the type of the relation to search for. The 'deviceTypes' defines the type of the device to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\nFor example, this entity filter selects 'Factory' edge instances which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n```json\n{\n \"type\": \"deviceSearchQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 2,\n \"fetchLastLevelOnly\": true,\n \"relationType\": \"Contains\",\n \"edgeTypes\": [\n \"Factory\"\n ]\n}\n```\n\n # Key Filters\nKey Filter allows you to define complex logical expressions over entity field, attribute or latest time series value. The filter is defined using 'key', 'valueType' and 'predicate' objects. Single Entity Query may have zero, one or multiple predicates. If multiple filters are defined, they are evaluated using logical 'AND'. The example below checks that temperature of the entity is above 20 degrees:\n\n```json\n{\n \"key\": {\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n },\n \"valueType\": \"NUMERIC\",\n \"predicate\": {\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 20,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n}\n```\n\n Now let's review 'key', 'valueType' and 'predicate' objects in detail.\n\n## Filter Key\n\nFilter Key defines either entity field, attribute or telemetry. It is a JSON object that consists the key name and type. The following filter key types are supported: \n\n * 'CLIENT_ATTRIBUTE' - used for client attributes; \n * 'SHARED_ATTRIBUTE' - used for shared attributes; \n * 'SERVER_ATTRIBUTE' - used for server attributes; \n * 'ATTRIBUTE' - used for any of the above; \n * 'TIME_SERIES' - used for time series values; \n * 'ENTITY_FIELD' - used for accessing entity fields like 'name', 'label', etc. The list of available fields depends on the entity type; \n * 'ALARM_FIELD' - similar to entity field, but is used in alarm queries only; \n\n\n Let's review the example:\n\n```json\n{\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n}\n```\n\n## Value Type and Operations\n\nProvides a hint about the data type of the entity field that is defined in the filter key. The value type impacts the list of possible operations that you may use in the corresponding predicate. For example, you may use 'STARTS_WITH' or 'END_WITH', but you can't use 'GREATER_OR_EQUAL' for string values.The following filter value types and corresponding predicate operations are supported: \n\n * 'STRING' - used to filter any 'String' or 'JSON' values. Operations: EQUAL, NOT_EQUAL, STARTS_WITH, ENDS_WITH, CONTAINS, NOT_CONTAINS; \n * 'NUMERIC' - used for 'Long' and 'Double' values. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n * 'BOOLEAN' - used for boolean values. Operations: EQUAL, NOT_EQUAL;\n * 'DATE_TIME' - similar to numeric, transforms value to milliseconds since epoch. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n\n\n## Filter Predicate\n\nFilter Predicate defines the logical expression to evaluate. The list of available operations depends on the filter value type, see above. Platform supports 4 predicate types: 'STRING', 'NUMERIC', 'BOOLEAN' and 'COMPLEX'. The last one allows to combine multiple operations over one filter key.\n\nSimple predicate example to check 'value < 100': \n\n```json\n{\n \"operation\": \"LESS\",\n \"value\": {\n \"defaultValue\": 100,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n}\n```\n\nComplex predicate example, to check 'value < 10 or value > 20': \n\n```json\n{\n \"type\": \"COMPLEX\",\n \"operation\": \"OR\",\n \"predicates\": [\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"defaultValue\": 10,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 20,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n ]\n}\n```\n\nMore complex predicate example, to check 'value < 10 or (value > 50 && value < 60)': \n\n```json\n{\n \"type\": \"COMPLEX\",\n \"operation\": \"OR\",\n \"predicates\": [\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"defaultValue\": 10,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"type\": \"COMPLEX\",\n \"operation\": \"AND\",\n \"predicates\": [\n {\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 50,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"defaultValue\": 60,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n ]\n }\n ]\n}\n```\n\n You may also want to replace hardcoded values (for example, temperature > 20) with the more dynamic expression (for example, temperature > 'value of the tenant attribute with key 'temperatureThreshold'). It is possible to use 'dynamicValue' to define attribute of the tenant, customer or user that is performing the API call. See example below: \n\n```json\n{\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 0,\n \"dynamicValue\": {\n \"sourceType\": \"CURRENT_USER\",\n \"sourceAttribute\": \"temperatureThreshold\"\n }\n },\n \"type\": \"NUMERIC\"\n}\n```\n\n Note that you may use 'CURRENT_USER', 'CURRENT_CUSTOMER' and 'CURRENT_TENANT' as a 'sourceType'. The 'defaultValue' is used when the attribute with such a name is not defined for the chosen source.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "findEntityDataByQuery", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityDataQuery" + } } }, - { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] - } - } - ], + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEntityVersion" + "$ref": "#/components/schemas/PageDataEntityData" } } } @@ -36336,7 +36211,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -36438,19 +36313,55 @@ "ApiKeyForm": [] } ] - }, + } + }, + "/api/entitiesQuery/find/keys": { "post": { "tags": [ - "entities-version-control-controller" + "entity-query-controller" + ], + "summary": "Find Available Entity Keys by Query (deprecated)", + "description": "**Deprecated.** Use the V2 endpoint (`POST /api/v2/entitiesQuery/find/keys`) instead.\n\nReturns unique time series and/or attribute key names from entities matching the query.\n\nExecutes the Entity Data Query to find up to 100 entities, then fetches and aggregates all distinct key names.\n\nPrimarily used for UI features like autocomplete suggestions.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "findAvailableEntityKeysByQuery", + "parameters": [ + { + "name": "timeseries", + "in": "query", + "description": "When true, includes unique time series key names in the response.\nWhen false, the 'timeseries' list will be empty.", + "required": true, + "schema": { + "type": "boolean" + } + }, + { + "name": "attributes", + "in": "query", + "description": "When true, includes unique attribute key names in the response.\nWhen false, the 'attribute' list will be empty. Use 'scope' parameter to filter by attribute scope.", + "required": true, + "schema": { + "type": "boolean" + } + }, + { + "name": "scope", + "in": "query", + "description": "Filters attribute keys by scope. Only applies when 'attributes' is true.\nIf not specified, returns attribute keys from all scopes.", + "required": false, + "schema": { + "type": "string", + "enum": [ + "SERVER_SCOPE", + "SHARED_SCOPE", + "CLIENT_SCOPE" + ] + } + } ], - "summary": "Save entities version (saveEntitiesVersion)", - "description": "Creates a new version of entities (or a single entity) by request.\nSupported entity types: CUSTOMER, ASSET, RULE_CHAIN, DASHBOARD, DEVICE_PROFILE, DEVICE, ENTITY_VIEW, WIDGETS_BUNDLE.\n\nThere are two available types of request: `SINGLE_ENTITY` and `COMPLEX`. Each of them contains version name (`versionName`) and name of a branch (`branch`) to create version (commit) in. If specified branch does not exists in a remote repo, then new empty branch will be created. Request of the `SINGLE_ENTITY` type has id of an entity (`entityId`) and additional configuration (`config`) which has following options: \n- `saveRelations` - whether to add inbound and outbound relations of type COMMON to created entity version;\n- `saveAttributes` - to save attributes of server scope (and also shared scope for devices);\n- `saveCredentials` - when saving a version of a device, to add its credentials to the version.\n\nAn example of a `SINGLE_ENTITY` version create request:\n```json\n{\n \"type\": \"SINGLE_ENTITY\",\n\n \"versionName\": \"Version 1.0\",\n \"branch\": \"dev\",\n\n \"entityId\": {\n \"entityType\": \"DEVICE\",\n \"id\": \"b79448e0-d4f4-11ec-847b-0f432358ab48\"\n },\n \"config\": {\n \"saveRelations\": true,\n \"saveAttributes\": true,\n \"saveCredentials\": false\n }\n}\n```\n\nSecond request type (`COMPLEX`), additionally to `branch` and `versionName`, contains following properties:\n- `entityTypes` - a structure with entity types to export and configuration for each entity type; this configuration has all the options available for `SINGLE_ENTITY` and additionally has these ones: \n - `allEntities` and `entityIds` - if you want to save the version of all entities of the entity type then set `allEntities` param to true, otherwise set it to false and specify the list of specific entities (`entityIds`);\n - `syncStrategy` - synchronization strategy to use for this entity type: when set to `OVERWRITE` then the list of remote entities of this type will be overwritten by newly added entities. If set to `MERGE` - existing remote entities of this entity type will not be removed, new entities will just be added on top (or existing remote entities will be updated).\n- `syncStrategy` - default synchronization strategy to use when it is not specified for an entity type.\n\nExample for this type of request:\n```json\n{\n \"type\": \"COMPLEX\",\n\n \"versionName\": \"Devices and profiles: release 2\",\n \"branch\": \"master\",\n\n \"syncStrategy\": \"OVERWRITE\",\n \"entityTypes\": {\n \"DEVICE\": {\n \"syncStrategy\": null,\n \"allEntities\": true,\n \"saveRelations\": true,\n \"saveAttributes\": true,\n \"saveCredentials\": true\n },\n \"DEVICE_PROFILE\": {\n \"syncStrategy\": \"MERGE\",\n \"allEntities\": false,\n \"entityIds\": [\n \"b79448e0-d4f4-11ec-847b-0f432358ab48\"\n ],\n \"saveRelations\": true\n }\n }\n}\n```\n\nResponse wil contain generated request UUID, that can be then used to retrieve status of operation via `getVersionCreateRequestStatus`.\n\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "saveEntitiesVersion", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/VersionCreateRequest" + "$ref": "#/components/schemas/EntityDataQuery" } } }, @@ -36462,8 +36373,7 @@ "content": { "application/json": { "schema": { - "type": "string", - "format": "uuid" + "$ref": "#/components/schemas/AvailableEntityKeys" } } } @@ -36574,6 +36484,7 @@ } } }, + "deprecated": true, "security": [ { "HttpLoginForm": [] @@ -36584,95 +36495,77 @@ ] } }, - "/api/entities/vc/version/{entityType}": { - "get": { + "/api/v2/entitiesQuery/find/keys": { + "post": { "tags": [ - "entities-version-control-controller" + "entity-query-controller" ], - "summary": "List entity type versions (listEntityTypeVersions)", - "description": "Returns list of versions of an entity type in a branch. This is a collected list of versions that were created for entities of this type in a remote branch. \nIf specified branch does not exist - empty page data will be returned. The response structure is the same as for `listEntityVersions` API method.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "listEntityTypeVersions", + "summary": "Find Available Entity Keys By Query", + "description": "Discovers unique time series and/or attribute key names available on entities that match the given query.\nWorks in two steps: first, the request body (an Entity Data Query) is executed to find matching entities\n(page size is capped at 100); then, all distinct key names are collected from those entities.\n\nOptionally, each key can include a sample — the most recent value (by timestamp) for that key\nacross all matched entities.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "findAvailableEntityKeysByQueryV2", "parameters": [ { - "name": "entityType", - "in": "path", - "description": "A string value representing the entity type. For example, 'DEVICE'", - "required": true, - "schema": { - "$ref": "#/components/schemas/EntityType" - } - }, - { - "name": "branch", - "in": "query", - "description": "The name of the working branch, for example 'master'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", + "name": "includeTimeseries", "in": "query", - "description": "Sequence number of page starting from 0", - "required": true, + "description": "When true, includes unique time series keys in the response.\nWhen false, the 'timeseries' field is omitted. At least one of 'includeTimeseries' or 'includeAttributes' must be true.", + "required": false, "schema": { - "type": "integer", - "format": "int32" + "type": "boolean", + "default": true } }, { - "name": "textSearch", + "name": "includeAttributes", "in": "query", - "description": "The case insensitive 'substring' filter based on the entity version name.", + "description": "When true, includes unique attribute keys in the response.\nWhen false, the 'attributes' field is omitted. At least one of 'includeTimeseries' or 'includeAttributes' must be true.", "required": false, "schema": { - "type": "string" + "type": "boolean", + "default": true } }, { - "name": "sortProperty", + "name": "scopes", "in": "query", - "description": "Property of entity to sort by", + "description": "Filters attribute keys by scope. Only applies when 'includeAttributes' is true.\nWhen not specified, scopes are auto-determined: all three scopes (server, client, shared) for device entities,\nserver scope only for other entity types.", "required": false, "schema": { "type": "string", "enum": [ - "timestamp" + "SERVER_SCOPE", + "SHARED_SCOPE", + "CLIENT_SCOPE" ] } }, { - "name": "sortOrder", + "name": "includeSamples", "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "description": "When true, each key entry includes a 'sample' object with the most recent value and timestamp.\nWhen false, only key names are returned (sample is omitted from JSON).", "required": false, "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] + "type": "boolean", + "default": false } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityDataQuery" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEntityVersion" + "$ref": "#/components/schemas/AvailableEntityKeysV2" } } } @@ -36689,7 +36582,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -36793,95 +36686,67 @@ ] } }, - "/api/entities/vc/version/{entityType}/{externalEntityUuid}": { + "/api/relation": { "get": { "tags": [ - "entities-version-control-controller" + "entity-relation-controller" ], - "summary": "List entity versions (listEntityVersions)", - "description": "Returns list of versions for a specific entity in a concrete branch. \nYou need to specify external id of an entity to list versions for. This is `externalId` property of an entity, or otherwise if not set - simply id of this entity. \nIf specified branch does not exist - empty page data will be returned. \n\nEach version info item has timestamp, id, name and author. Version id can then be used to restore the version. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nResponse example: \n```json\n{\n \"data\": [\n {\n \"timestamp\": 1655198593000,\n \"id\": \"fd82625bdd7d6131cf8027b44ee967012ecaf990\",\n \"name\": \"Devices and assets - v2.0\",\n \"author\": \"John Doe (johndoe@gmail.com)\"\n },\n {\n \"timestamp\": 1655198528000,\n \"id\": \"682adcffa9c8a2f863af6f00c4850323acbd4219\",\n \"name\": \"Update my device\",\n \"author\": \"John Doe (johndoe@gmail.com)\"\n },\n {\n \"timestamp\": 1655198280000,\n \"id\": \"d2a6087c2b30e18cc55e7cdda345a8d0dfb959a4\",\n \"name\": \"Devices and assets - v1.0\",\n \"author\": \"John Doe (johndoe@gmail.com)\"\n }\n ],\n \"totalPages\": 1,\n \"totalElements\": 3,\n \"hasNext\": false\n}\n```\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "listEntityVersions", + "summary": "Get Relation (getRelation)", + "description": "Returns relation object between two specified entities if present. Otherwise throws exception. \n\nIf the user has the authority of 'System Administrator', the server checks that 'from' and 'to' entities are owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that 'from' and 'to' entities are owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the 'from' and 'to' entities are assigned to the same customer.", + "operationId": "getRelation", "parameters": [ { - "name": "entityType", - "in": "path", - "description": "A string value representing the entity type. For example, 'DEVICE'", - "required": true, - "schema": { - "$ref": "#/components/schemas/EntityType" - } - }, - { - "name": "externalEntityUuid", - "in": "path", - "description": "A string value representing external entity id. This is `externalId` property of an entity, or otherwise if not set - simply id of this entity.", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "branch", + "name": "fromId", "in": "query", - "description": "The name of the working branch, for example 'master'", + "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" } }, { - "name": "pageSize", + "name": "fromType", "in": "query", - "description": "Maximum amount of entities in a one page", + "description": "A string value representing the entity type. For example, 'DEVICE'", "required": true, "schema": { - "type": "integer", - "format": "int32" + "type": "string" } }, { - "name": "page", + "name": "relationType", "in": "query", - "description": "Sequence number of page starting from 0", + "description": "A string value representing relation type between entities. For example, 'Contains', 'Manages'. It can be any string value.", "required": true, "schema": { - "type": "integer", - "format": "int32" + "type": "string" } }, { - "name": "textSearch", + "name": "relationTypeGroup", "in": "query", - "description": "The case insensitive 'substring' filter based on the entity version name.", + "description": "A string value representing relation type group. For example, 'COMMON'", "required": false, "schema": { "type": "string" } }, { - "name": "sortProperty", + "name": "toId", "in": "query", - "description": "Property of entity to sort by", - "required": false, + "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, "schema": { - "type": "string", - "enum": [ - "timestamp" - ] + "type": "string" } }, { - "name": "sortOrder", + "name": "toType", "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, + "description": "A string value representing the entity type. For example, 'DEVICE'", + "required": true, "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] + "type": "string" } } ], @@ -36891,7 +36756,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEntityVersion" + "$ref": "#/components/schemas/EntityRelation" } } } @@ -37012,33 +36877,34 @@ ] } }, - "/api/entities/vc/version/{requestId}/status": { - "get": { + "/api/relations": { + "post": { "tags": [ - "entities-version-control-controller" + "entity-relation-controller" ], - "summary": "Get version create request status (getVersionCreateRequestStatus)", - "description": "Returns the status of previously made version create request. \n\nThis status contains following properties:\n- `done` - whether request processing is finished;\n- `version` - created version info: timestamp, version id (commit hash), commit name and commit author;\n- `added` - count of items that were created in the remote repo;\n- `modified` - modified items count;\n- `removed` - removed items count;\n- `error` - error message, if an error occurred while handling the request.\n\nAn example of successful status:\n```json\n{\n \"done\": true,\n \"added\": 10,\n \"modified\": 2,\n \"removed\": 5,\n \"version\": {\n \"timestamp\": 1655198528000,\n \"id\":\"8a834dd389ed80e0759ba8ee338b3f1fd160a114\",\n \"name\": \"My devices v2.0\",\n \"author\": \"John Doe\"\n },\n \"error\": null\n}\n```\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getVersionCreateRequestStatus", - "parameters": [ - { - "name": "requestId", - "in": "path", - "description": "A string value representing the version control request id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string", - "format": "uuid" + "summary": "Find related entities (findEntityRelationsByQuery)", + "description": "Returns all entities that are related to the specific entity. The entity id, relation type, entity types, depth of the search, and other query parameters defined using complex 'EntityRelationsQuery' object. See 'Model' tab of the Parameters for more info.", + "operationId": "findEntityRelationsByQuery", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityRelationsQuery" + } } - } - ], + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/VersionCreationResult" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityRelation" + } } } } @@ -37055,7 +36921,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -37157,37 +37023,37 @@ "ApiKeyForm": [] } ] - } - }, - "/api/alarmsQuery/count": { - "post": { + }, + "delete": { "tags": [ - "entity-query-controller" + "entity-relation-controller" ], - "summary": "Count Alarms by Query (countAlarmsByQuery)", - "description": "Returns the number of alarms that match the query definition.", - "operationId": "countAlarmsByQuery", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AlarmCountQuery" - } + "summary": "Delete common relations (deleteRelations)", + "description": "Deletes all the relations ('from' and 'to' direction) for the specified entity and relation type group: 'COMMON'. \n\nIf the user has the authority of 'System Administrator', the server checks that the entity is owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer.", + "operationId": "deleteRelations", + "parameters": [ + { + "name": "entityId", + "in": "query", + "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" } }, - "required": true - }, + { + "name": "entityType", + "in": "query", + "description": "A string value representing the entity type. For example, 'DEVICE'", + "required": true, + "schema": { + "type": "string" + } + } + ], "responses": { "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "integer", - "format": "int64" - } - } - } + "description": "OK" }, "400": { "description": "Bad Request", @@ -37201,7 +37067,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -37305,31 +37171,53 @@ ] } }, - "/api/alarmsQuery/find": { - "post": { + "/api/relations/from/{fromType}/{fromId}": { + "get": { "tags": [ - "entity-query-controller" + "entity-relation-controller" ], - "summary": "Find Alarms by Query", - "description": "This method description defines how Alarm Data Query extends the Entity Data Query. See method 'Find Entity Data by Query' first to get the info about 'Entity Data Query'.\n\n The platform will first search the entities that match the entity and key filters. Then, the platform will use 'Alarm Page Link' to filter the alarms related to those entities. Finally, platform fetch the properties of alarm that are defined in the **'alarmFields'** and combine them with the other entity, attribute and latest time series fields to return the result. \n\n See example of the alarm query below. The query will search first 100 active alarms with type 'Temperature Alarm' or 'Fire Alarm' for any device with current temperature \u003E 0. The query will return combination of the entity fields: name of the device, device model and latest temperature reading and alarms fields: createdTime, type, severity and status: \n\n```json\n{\n \"entityFilter\": {\n \"type\": \"entityType\",\n \"resolveMultiple\": true,\n \"entityType\": \"DEVICE\"\n },\n \"pageLink\": {\n \"page\": 0,\n \"pageSize\": 100,\n \"textSearch\": null,\n \"searchPropagatedAlarms\": false,\n \"statusList\": [\n \"ACTIVE\"\n ],\n \"severityList\": [\n \"CRITICAL\",\n \"MAJOR\"\n ],\n \"typeList\": [\n \"Temperature Alarm\",\n \"Fire Alarm\"\n ],\n \"sortOrder\": {\n \"key\": {\n \"key\": \"createdTime\",\n \"type\": \"ALARM_FIELD\"\n },\n \"direction\": \"DESC\"\n },\n \"timeWindow\": 86400000\n },\n \"keyFilters\": [\n {\n \"key\": {\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n },\n \"valueType\": \"NUMERIC\",\n \"predicate\": {\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 0,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n }\n ],\n \"alarmFields\": [\n {\n \"type\": \"ALARM_FIELD\",\n \"key\": \"createdTime\"\n },\n {\n \"type\": \"ALARM_FIELD\",\n \"key\": \"type\"\n },\n {\n \"type\": \"ALARM_FIELD\",\n \"key\": \"severity\"\n },\n {\n \"type\": \"ALARM_FIELD\",\n \"key\": \"status\"\n }\n ],\n \"entityFields\": [\n {\n \"type\": \"ENTITY_FIELD\",\n \"key\": \"name\"\n }\n ],\n \"latestValues\": [\n {\n \"type\": \"ATTRIBUTE\",\n \"key\": \"model\"\n },\n {\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n }\n ]\n}\n```", - "operationId": "findAlarmDataByQuery", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AlarmDataQuery" - } + "summary": "Get List of Relations (findEntityRelationsByFrom)", + "description": "Returns list of relation objects for the specified entity by the 'from' direction. \n\nIf the user has the authority of 'System Administrator', the server checks that the entity is owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer.", + "operationId": "findEntityRelationsByFrom", + "parameters": [ + { + "name": "fromType", + "in": "path", + "description": "A string value representing the entity type. For example, 'DEVICE'", + "required": true, + "schema": { + "type": "string" } }, - "required": true - }, + { + "name": "fromId", + "in": "path", + "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "relationTypeGroup", + "in": "query", + "description": "A string value representing relation type group. For example, 'COMMON'", + "required": false, + "schema": { + "type": "string" + } + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataAlarmData" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityRelation" + } } } } @@ -37346,7 +37234,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -37450,20 +37338,62 @@ ] } }, - "/api/edqs/state": { + "/api/relations/from/{fromType}/{fromId}/{relationType}": { "get": { "tags": [ - "entity-query-controller" + "entity-relation-controller" + ], + "summary": "Get List of Relations (findEntityRelationsByFromAndRelationType)", + "description": "Returns list of relation objects for the specified entity by the 'from' direction and relation type. \n\nIf the user has the authority of 'System Administrator', the server checks that the entity is owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer.", + "operationId": "findEntityRelationsByFromAndRelationType", + "parameters": [ + { + "name": "fromType", + "in": "path", + "description": "A string value representing the entity type. For example, 'DEVICE'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "fromId", + "in": "path", + "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "relationType", + "in": "path", + "description": "A string value representing relation type between entities. For example, 'Contains', 'Manages'. It can be any string value.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "relationTypeGroup", + "in": "query", + "description": "A string value representing relation type group. For example, 'COMMON'", + "required": false, + "schema": { + "type": "string" + } + } ], - "summary": "getEdqsState", - "operationId": "getEdqsState", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EdqsState" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityRelation" + } } } } @@ -37584,18 +37514,19 @@ ] } }, - "/api/edqs/system/request": { + "/api/relations/info": { "post": { "tags": [ - "entity-query-controller" + "entity-relation-controller" ], - "summary": "processSystemEdqsRequest", - "operationId": "processSystemEdqsRequest", + "summary": "Find related entity infos (findEntityRelationInfosByQuery)", + "description": "Returns all entity infos that are related to the specific entity. The entity id, relation type, entity types, depth of the search, and other query parameters defined using complex 'EntityRelationsQuery' object. See 'Model' tab of the Parameters for more info. Relation Info is an extension of the default Relation object that contains information about the 'from' and 'to' entity names. ", + "operationId": "findEntityRelationInfosByQuery", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ToCoreEdqsRequest" + "$ref": "#/components/schemas/EntityRelationsQuery" } } }, @@ -37603,7 +37534,17 @@ }, "responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityRelationInfo" + } + } + } + } }, "400": { "description": "Bad Request", @@ -37721,32 +37662,53 @@ ] } }, - "/api/entitiesQuery/count": { - "post": { + "/api/relations/info/from/{fromType}/{fromId}": { + "get": { "tags": [ - "entity-query-controller" + "entity-relation-controller" ], - "summary": "Count Entities by Query", - "description": "Allows to run complex queries to search the count of platform entities (devices, assets, customers, etc) based on the combination of main entity filter and multiple key filters. Returns the number of entities that match the query definition.\n\n# Query Definition\n\n\n\nMain **entity filter** is mandatory and defines generic search criteria. For example, \"find all devices with profile 'Moisture Sensor'\" or \"Find all devices related to asset 'Building A'\"\n\nOptional **key filters** allow to filter results of the entity filter by complex criteria against main entity fields (name, label, type, etc), attributes and telemetry. For example, \"temperature \u003E 20 or temperature\u003C 10\" or \"name starts with 'T', and attribute 'model' is 'T1000', and time series field 'batteryLevel' \u003E 40\".\n\nLet's review the example:\n\n```json\n{\n \"entityFilter\": {\n \"type\": \"entityType\",\n \"entityType\": \"DEVICE\"\n },\n \"keyFilters\": [\n {\n \"key\": {\n \"type\": \"ATTRIBUTE\",\n \"key\": \"active\"\n },\n \"valueType\": \"BOOLEAN\",\n \"predicate\": {\n \"operation\": \"EQUAL\",\n \"value\": {\n \"defaultValue\": true,\n \"dynamicValue\": null\n },\n \"type\": \"BOOLEAN\"\n }\n }\n ]\n}\n```\n\n Example mentioned above search all devices which have attribute 'active' set to 'true'. Now let's review available entity filters and key filters syntax:\n\n # Entity Filters\nEntity Filter body depends on the 'type' parameter. Let's review available entity filter types. In fact, they do correspond to available dashboard aliases.\n\n## Single Entity\n\nAllows to filter only one entity based on the id. For example, this entity filter selects certain device:\n\n```json\n{\n \"type\": \"singleEntity\",\n \"singleEntity\": {\n \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n \"entityType\": \"DEVICE\"\n }\n}\n```\n\n## Entity List Filter\n\nAllows to filter entities of the same type using their ids. For example, this entity filter selects two devices:\n\n```json\n{\n \"type\": \"entityList\",\n \"entityType\": \"DEVICE\",\n \"entityList\": [\n \"e6501f30-2a7a-11ec-94eb-213c95f54092\",\n \"e6657bf0-2a7a-11ec-94eb-213c95f54092\"\n ]\n}\n```\n\n## Entity Name Filter\n\nAllows to filter entities of the same type using the **'starts with'** expression over entity name. For example, this entity filter selects all devices which name starts with 'Air Quality':\n\n```json\n{\n \"type\": \"entityName\",\n \"entityType\": \"DEVICE\",\n \"entityNameFilter\": \"Air Quality\"\n}\n```\n\n## Entity Type Filter\n\nAllows to filter entities based on their type (CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, etc)For example, this entity filter selects all tenant customers:\n\n```json\n{\n \"type\": \"entityType\",\n \"entityType\": \"CUSTOMER\"\n}\n```\n\n## Asset Type Filter\n\nAllows to filter assets based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'charging station' assets which name starts with 'Tesla':\n\n```json\n{\n \"type\": \"assetType\",\n \"assetType\": \"charging station\",\n \"assetNameFilter\": \"Tesla\"\n}\n```\n\n## Device Type Filter\n\nAllows to filter devices based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Temperature Sensor' devices which name starts with 'ABC':\n\n```json\n{\n \"type\": \"deviceType\",\n \"deviceType\": \"Temperature Sensor\",\n \"deviceNameFilter\": \"ABC\"\n}\n```\n\n## Edge Type Filter\n\nAllows to filter edge instances based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Factory' edge instances which name starts with 'Nevada':\n\n```json\n{\n \"type\": \"edgeType\",\n \"edgeType\": \"Factory\",\n \"edgeNameFilter\": \"Nevada\"\n}\n```\n\n## Entity View Filter\n\nAllows to filter entity views based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Concrete Mixer' entity views which name starts with 'CAT':\n\n```json\n{\n \"type\": \"entityViewType\",\n \"entityViewType\": \"Concrete Mixer\",\n \"entityViewNameFilter\": \"CAT\"\n}\n```\n\n## Api Usage Filter\n\nAllows to query for Api Usage based on optional customer id. If the customer id is not set, returns current tenant API usage.For example, this entity filter selects the 'Api Usage' entity for customer with id 'e6501f30-2a7a-11ec-94eb-213c95f54092':\n\n```json\n{\n \"type\": \"apiUsageState\",\n \"customerId\": {\n \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n \"entityType\": \"CUSTOMER\"\n }\n}\n```\n\n## Relations Query Filter\n\nAllows to filter entities that are related to the provided root entity. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is \u003E 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'filter' object allows you to define the relation type and set of acceptable entity types to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only those who match the 'filters'.\n\nFor example, this entity filter selects all devices and assets which are related to the asset with id 'e51de0c0-2a7a-11ec-94eb-213c95f54092':\n\n```json\n{\n \"type\": \"relationsQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e51de0c0-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 1,\n \"fetchLastLevelOnly\": false,\n \"filters\": [\n {\n \"relationType\": \"Contains\",\n \"entityTypes\": [\n \"DEVICE\",\n \"ASSET\"\n ]\n }\n ]\n}\n```\n\n## Asset Search Query\n\nAllows to filter assets that are related to the provided root entity. Filters related assets based on the relation type and set of asset types. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is \u003E 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'relationType' defines the type of the relation to search for. The 'assetTypes' defines the type of the asset to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only assets that match 'relationType' and 'assetTypes' conditions.\n\nFor example, this entity filter selects 'charging station' assets which are related to the asset with id 'e51de0c0-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n```json\n{\n \"type\": \"assetSearchQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e51de0c0-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 1,\n \"fetchLastLevelOnly\": false,\n \"relationType\": \"Contains\",\n \"assetTypes\": [\n \"charging station\"\n ]\n}\n```\n\n## Device Search Query\n\nAllows to filter devices that are related to the provided root entity. Filters related devices based on the relation type and set of device types. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is \u003E 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'relationType' defines the type of the relation to search for. The 'deviceTypes' defines the type of the device to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\nFor example, this entity filter selects 'Charging port' and 'Air Quality Sensor' devices which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n```json\n{\n \"type\": \"deviceSearchQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 2,\n \"fetchLastLevelOnly\": true,\n \"relationType\": \"Contains\",\n \"deviceTypes\": [\n \"Air Quality Sensor\",\n \"Charging port\"\n ]\n}\n```\n\n## Entity View Query\n\nAllows to filter entity views that are related to the provided root entity. Filters related entity views based on the relation type and set of entity view types. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is \u003E 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'relationType' defines the type of the relation to search for. The 'entityViewTypes' defines the type of the entity view to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\nFor example, this entity filter selects 'Concrete mixer' entity views which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n```json\n{\n \"type\": \"entityViewSearchQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 1,\n \"fetchLastLevelOnly\": false,\n \"relationType\": \"Contains\",\n \"entityViewTypes\": [\n \"Concrete mixer\"\n ]\n}\n```\n\n## Edge Search Query\n\nAllows to filter edge instances that are related to the provided root entity. Filters related edge instances based on the relation type and set of edge types. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is \u003E 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'relationType' defines the type of the relation to search for. The 'deviceTypes' defines the type of the device to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\nFor example, this entity filter selects 'Factory' edge instances which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n```json\n{\n \"type\": \"deviceSearchQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 2,\n \"fetchLastLevelOnly\": true,\n \"relationType\": \"Contains\",\n \"edgeTypes\": [\n \"Factory\"\n ]\n}\n```\n\n # Key Filters\nKey Filter allows you to define complex logical expressions over entity field, attribute or latest time series value. The filter is defined using 'key', 'valueType' and 'predicate' objects. Single Entity Query may have zero, one or multiple predicates. If multiple filters are defined, they are evaluated using logical 'AND'. The example below checks that temperature of the entity is above 20 degrees:\n\n```json\n{\n \"key\": {\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n },\n \"valueType\": \"NUMERIC\",\n \"predicate\": {\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 20,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n}\n```\n\n Now let's review 'key', 'valueType' and 'predicate' objects in detail.\n\n## Filter Key\n\nFilter Key defines either entity field, attribute or telemetry. It is a JSON object that consists the key name and type. The following filter key types are supported: \n\n * 'CLIENT_ATTRIBUTE' - used for client attributes; \n * 'SHARED_ATTRIBUTE' - used for shared attributes; \n * 'SERVER_ATTRIBUTE' - used for server attributes; \n * 'ATTRIBUTE' - used for any of the above; \n * 'TIME_SERIES' - used for time series values; \n * 'ENTITY_FIELD' - used for accessing entity fields like 'name', 'label', etc. The list of available fields depends on the entity type; \n * 'ALARM_FIELD' - similar to entity field, but is used in alarm queries only; \n\n\n Let's review the example:\n\n```json\n{\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n}\n```\n\n## Value Type and Operations\n\nProvides a hint about the data type of the entity field that is defined in the filter key. The value type impacts the list of possible operations that you may use in the corresponding predicate. For example, you may use 'STARTS_WITH' or 'END_WITH', but you can't use 'GREATER_OR_EQUAL' for string values.The following filter value types and corresponding predicate operations are supported: \n\n * 'STRING' - used to filter any 'String' or 'JSON' values. Operations: EQUAL, NOT_EQUAL, STARTS_WITH, ENDS_WITH, CONTAINS, NOT_CONTAINS; \n * 'NUMERIC' - used for 'Long' and 'Double' values. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n * 'BOOLEAN' - used for boolean values. Operations: EQUAL, NOT_EQUAL;\n * 'DATE_TIME' - similar to numeric, transforms value to milliseconds since epoch. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n\n\n## Filter Predicate\n\nFilter Predicate defines the logical expression to evaluate. The list of available operations depends on the filter value type, see above. Platform supports 4 predicate types: 'STRING', 'NUMERIC', 'BOOLEAN' and 'COMPLEX'. The last one allows to combine multiple operations over one filter key.\n\nSimple predicate example to check 'value \u003C 100': \n\n```json\n{\n \"operation\": \"LESS\",\n \"value\": {\n \"defaultValue\": 100,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n}\n```\n\nComplex predicate example, to check 'value \u003C 10 or value \u003E 20': \n\n```json\n{\n \"type\": \"COMPLEX\",\n \"operation\": \"OR\",\n \"predicates\": [\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"defaultValue\": 10,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 20,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n ]\n}\n```\n\nMore complex predicate example, to check 'value \u003C 10 or (value \u003E 50 && value \u003C 60)': \n\n```json\n{\n \"type\": \"COMPLEX\",\n \"operation\": \"OR\",\n \"predicates\": [\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"defaultValue\": 10,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"type\": \"COMPLEX\",\n \"operation\": \"AND\",\n \"predicates\": [\n {\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 50,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"defaultValue\": 60,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n ]\n }\n ]\n}\n```\n\n You may also want to replace hardcoded values (for example, temperature \u003E 20) with the more dynamic expression (for example, temperature \u003E 'value of the tenant attribute with key 'temperatureThreshold'). It is possible to use 'dynamicValue' to define attribute of the tenant, customer or user that is performing the API call. See example below: \n\n```json\n{\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 0,\n \"dynamicValue\": {\n \"sourceType\": \"CURRENT_USER\",\n \"sourceAttribute\": \"temperatureThreshold\"\n }\n },\n \"type\": \"NUMERIC\"\n}\n```\n\n Note that you may use 'CURRENT_USER', 'CURRENT_CUSTOMER' and 'CURRENT_TENANT' as a 'sourceType'. The 'defaultValue' is used when the attribute with such a name is not defined for the chosen source.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "countEntitiesByQuery", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EntityCountQuery" - } + "summary": "Get List of Relation Infos (findEntityRelationInfosByFrom)", + "description": "Returns list of relation info objects for the specified entity by the 'from' direction. \n\nIf the user has the authority of 'System Administrator', the server checks that the entity is owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer. Relation Info is an extension of the default Relation object that contains information about the 'from' and 'to' entity names. ", + "operationId": "findEntityRelationInfosByFrom", + "parameters": [ + { + "name": "fromType", + "in": "path", + "description": "A string value representing the entity type. For example, 'DEVICE'", + "required": true, + "schema": { + "type": "string" } }, - "required": true - }, + { + "name": "fromId", + "in": "path", + "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "relationTypeGroup", + "in": "query", + "description": "A string value representing relation type group. For example, 'COMMON'", + "required": false, + "schema": { + "type": "string" + } + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "integer", - "format": "int64" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityRelationInfo" + } } } } @@ -37763,7 +37725,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -37867,31 +37829,53 @@ ] } }, - "/api/entitiesQuery/find": { - "post": { + "/api/relations/info/to/{toType}/{toId}": { + "get": { "tags": [ - "entity-query-controller" + "entity-relation-controller" ], - "summary": "Find Entity Data by Query", - "description": "Allows to run complex queries over platform entities (devices, assets, customers, etc) based on the combination of main entity filter and multiple key filters. Returns the paginated result of the query that contains requested entity fields and latest values of requested attributes and time series data.\n\n# Query Definition\n\n\n\nMain **entity filter** is mandatory and defines generic search criteria. For example, \"find all devices with profile 'Moisture Sensor'\" or \"Find all devices related to asset 'Building A'\"\n\nOptional **key filters** allow to filter results of the **entity filter** by complex criteria against main entity fields (name, label, type, etc), attributes and telemetry. For example, \"temperature \u003E 20 or temperature\u003C 10\" or \"name starts with 'T', and attribute 'model' is 'T1000', and time series field 'batteryLevel' \u003E 40\".\n\nThe **entity fields** and **latest values** contains list of entity fields and latest attribute/telemetry fields to fetch for each entity.\n\nThe **page link** contains information about the page to fetch and the sort ordering.\n\nLet's review the example:\n\n```json\n{\n \"entityFilter\": {\n \"type\": \"entityType\",\n \"resolveMultiple\": true,\n \"entityType\": \"DEVICE\"\n },\n \"keyFilters\": [\n {\n \"key\": {\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n },\n \"valueType\": \"NUMERIC\",\n \"predicate\": {\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 0,\n \"dynamicValue\": {\n \"sourceType\": \"CURRENT_USER\",\n \"sourceAttribute\": \"temperatureThreshold\",\n \"inherit\": false\n }\n },\n \"type\": \"NUMERIC\"\n }\n }\n ],\n \"entityFields\": [\n {\n \"type\": \"ENTITY_FIELD\",\n \"key\": \"name\"\n },\n {\n \"type\": \"ENTITY_FIELD\",\n \"key\": \"label\"\n },\n {\n \"type\": \"ENTITY_FIELD\",\n \"key\": \"additionalInfo\"\n }\n ],\n \"latestValues\": [\n {\n \"type\": \"ATTRIBUTE\",\n \"key\": \"model\"\n },\n {\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n }\n ],\n \"pageLink\": {\n \"page\": 0,\n \"pageSize\": 10,\n \"sortOrder\": {\n \"key\": {\n \"key\": \"name\",\n \"type\": \"ENTITY_FIELD\"\n },\n \"direction\": \"ASC\"\n }\n }\n}\n```\n\n Example mentioned above search all devices which have attribute 'active' set to 'true'. Now let's review available entity filters and key filters syntax:\n\n # Entity Filters\nEntity Filter body depends on the 'type' parameter. Let's review available entity filter types. In fact, they do correspond to available dashboard aliases.\n\n## Single Entity\n\nAllows to filter only one entity based on the id. For example, this entity filter selects certain device:\n\n```json\n{\n \"type\": \"singleEntity\",\n \"singleEntity\": {\n \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n \"entityType\": \"DEVICE\"\n }\n}\n```\n\n## Entity List Filter\n\nAllows to filter entities of the same type using their ids. For example, this entity filter selects two devices:\n\n```json\n{\n \"type\": \"entityList\",\n \"entityType\": \"DEVICE\",\n \"entityList\": [\n \"e6501f30-2a7a-11ec-94eb-213c95f54092\",\n \"e6657bf0-2a7a-11ec-94eb-213c95f54092\"\n ]\n}\n```\n\n## Entity Name Filter\n\nAllows to filter entities of the same type using the **'starts with'** expression over entity name. For example, this entity filter selects all devices which name starts with 'Air Quality':\n\n```json\n{\n \"type\": \"entityName\",\n \"entityType\": \"DEVICE\",\n \"entityNameFilter\": \"Air Quality\"\n}\n```\n\n## Entity Type Filter\n\nAllows to filter entities based on their type (CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, etc)For example, this entity filter selects all tenant customers:\n\n```json\n{\n \"type\": \"entityType\",\n \"entityType\": \"CUSTOMER\"\n}\n```\n\n## Asset Type Filter\n\nAllows to filter assets based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'charging station' assets which name starts with 'Tesla':\n\n```json\n{\n \"type\": \"assetType\",\n \"assetType\": \"charging station\",\n \"assetNameFilter\": \"Tesla\"\n}\n```\n\n## Device Type Filter\n\nAllows to filter devices based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Temperature Sensor' devices which name starts with 'ABC':\n\n```json\n{\n \"type\": \"deviceType\",\n \"deviceType\": \"Temperature Sensor\",\n \"deviceNameFilter\": \"ABC\"\n}\n```\n\n## Edge Type Filter\n\nAllows to filter edge instances based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Factory' edge instances which name starts with 'Nevada':\n\n```json\n{\n \"type\": \"edgeType\",\n \"edgeType\": \"Factory\",\n \"edgeNameFilter\": \"Nevada\"\n}\n```\n\n## Entity View Filter\n\nAllows to filter entity views based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Concrete Mixer' entity views which name starts with 'CAT':\n\n```json\n{\n \"type\": \"entityViewType\",\n \"entityViewType\": \"Concrete Mixer\",\n \"entityViewNameFilter\": \"CAT\"\n}\n```\n\n## Api Usage Filter\n\nAllows to query for Api Usage based on optional customer id. If the customer id is not set, returns current tenant API usage.For example, this entity filter selects the 'Api Usage' entity for customer with id 'e6501f30-2a7a-11ec-94eb-213c95f54092':\n\n```json\n{\n \"type\": \"apiUsageState\",\n \"customerId\": {\n \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n \"entityType\": \"CUSTOMER\"\n }\n}\n```\n\n## Relations Query Filter\n\nAllows to filter entities that are related to the provided root entity. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is \u003E 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'filter' object allows you to define the relation type and set of acceptable entity types to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only those who match the 'filters'.\n\nFor example, this entity filter selects all devices and assets which are related to the asset with id 'e51de0c0-2a7a-11ec-94eb-213c95f54092':\n\n```json\n{\n \"type\": \"relationsQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e51de0c0-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 1,\n \"fetchLastLevelOnly\": false,\n \"filters\": [\n {\n \"relationType\": \"Contains\",\n \"entityTypes\": [\n \"DEVICE\",\n \"ASSET\"\n ]\n }\n ]\n}\n```\n\n## Asset Search Query\n\nAllows to filter assets that are related to the provided root entity. Filters related assets based on the relation type and set of asset types. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is \u003E 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'relationType' defines the type of the relation to search for. The 'assetTypes' defines the type of the asset to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only assets that match 'relationType' and 'assetTypes' conditions.\n\nFor example, this entity filter selects 'charging station' assets which are related to the asset with id 'e51de0c0-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n```json\n{\n \"type\": \"assetSearchQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e51de0c0-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 1,\n \"fetchLastLevelOnly\": false,\n \"relationType\": \"Contains\",\n \"assetTypes\": [\n \"charging station\"\n ]\n}\n```\n\n## Device Search Query\n\nAllows to filter devices that are related to the provided root entity. Filters related devices based on the relation type and set of device types. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is \u003E 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'relationType' defines the type of the relation to search for. The 'deviceTypes' defines the type of the device to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\nFor example, this entity filter selects 'Charging port' and 'Air Quality Sensor' devices which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n```json\n{\n \"type\": \"deviceSearchQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 2,\n \"fetchLastLevelOnly\": true,\n \"relationType\": \"Contains\",\n \"deviceTypes\": [\n \"Air Quality Sensor\",\n \"Charging port\"\n ]\n}\n```\n\n## Entity View Query\n\nAllows to filter entity views that are related to the provided root entity. Filters related entity views based on the relation type and set of entity view types. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is \u003E 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'relationType' defines the type of the relation to search for. The 'entityViewTypes' defines the type of the entity view to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\nFor example, this entity filter selects 'Concrete mixer' entity views which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n```json\n{\n \"type\": \"entityViewSearchQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 1,\n \"fetchLastLevelOnly\": false,\n \"relationType\": \"Contains\",\n \"entityViewTypes\": [\n \"Concrete mixer\"\n ]\n}\n```\n\n## Edge Search Query\n\nAllows to filter edge instances that are related to the provided root entity. Filters related edge instances based on the relation type and set of edge types. Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. Assuming the 'maxLevel' is \u003E 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. The 'relationType' defines the type of the relation to search for. The 'deviceTypes' defines the type of the device to search for. The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\nFor example, this entity filter selects 'Factory' edge instances which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n```json\n{\n \"type\": \"deviceSearchQuery\",\n \"rootEntity\": {\n \"entityType\": \"ASSET\",\n \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n },\n \"direction\": \"FROM\",\n \"maxLevel\": 2,\n \"fetchLastLevelOnly\": true,\n \"relationType\": \"Contains\",\n \"edgeTypes\": [\n \"Factory\"\n ]\n}\n```\n\n # Key Filters\nKey Filter allows you to define complex logical expressions over entity field, attribute or latest time series value. The filter is defined using 'key', 'valueType' and 'predicate' objects. Single Entity Query may have zero, one or multiple predicates. If multiple filters are defined, they are evaluated using logical 'AND'. The example below checks that temperature of the entity is above 20 degrees:\n\n```json\n{\n \"key\": {\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n },\n \"valueType\": \"NUMERIC\",\n \"predicate\": {\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 20,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n}\n```\n\n Now let's review 'key', 'valueType' and 'predicate' objects in detail.\n\n## Filter Key\n\nFilter Key defines either entity field, attribute or telemetry. It is a JSON object that consists the key name and type. The following filter key types are supported: \n\n * 'CLIENT_ATTRIBUTE' - used for client attributes; \n * 'SHARED_ATTRIBUTE' - used for shared attributes; \n * 'SERVER_ATTRIBUTE' - used for server attributes; \n * 'ATTRIBUTE' - used for any of the above; \n * 'TIME_SERIES' - used for time series values; \n * 'ENTITY_FIELD' - used for accessing entity fields like 'name', 'label', etc. The list of available fields depends on the entity type; \n * 'ALARM_FIELD' - similar to entity field, but is used in alarm queries only; \n\n\n Let's review the example:\n\n```json\n{\n \"type\": \"TIME_SERIES\",\n \"key\": \"temperature\"\n}\n```\n\n## Value Type and Operations\n\nProvides a hint about the data type of the entity field that is defined in the filter key. The value type impacts the list of possible operations that you may use in the corresponding predicate. For example, you may use 'STARTS_WITH' or 'END_WITH', but you can't use 'GREATER_OR_EQUAL' for string values.The following filter value types and corresponding predicate operations are supported: \n\n * 'STRING' - used to filter any 'String' or 'JSON' values. Operations: EQUAL, NOT_EQUAL, STARTS_WITH, ENDS_WITH, CONTAINS, NOT_CONTAINS; \n * 'NUMERIC' - used for 'Long' and 'Double' values. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n * 'BOOLEAN' - used for boolean values. Operations: EQUAL, NOT_EQUAL;\n * 'DATE_TIME' - similar to numeric, transforms value to milliseconds since epoch. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n\n\n## Filter Predicate\n\nFilter Predicate defines the logical expression to evaluate. The list of available operations depends on the filter value type, see above. Platform supports 4 predicate types: 'STRING', 'NUMERIC', 'BOOLEAN' and 'COMPLEX'. The last one allows to combine multiple operations over one filter key.\n\nSimple predicate example to check 'value \u003C 100': \n\n```json\n{\n \"operation\": \"LESS\",\n \"value\": {\n \"defaultValue\": 100,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n}\n```\n\nComplex predicate example, to check 'value \u003C 10 or value \u003E 20': \n\n```json\n{\n \"type\": \"COMPLEX\",\n \"operation\": \"OR\",\n \"predicates\": [\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"defaultValue\": 10,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 20,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n ]\n}\n```\n\nMore complex predicate example, to check 'value \u003C 10 or (value \u003E 50 && value \u003C 60)': \n\n```json\n{\n \"type\": \"COMPLEX\",\n \"operation\": \"OR\",\n \"predicates\": [\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"defaultValue\": 10,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"type\": \"COMPLEX\",\n \"operation\": \"AND\",\n \"predicates\": [\n {\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 50,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n },\n {\n \"operation\": \"LESS\",\n \"value\": {\n \"defaultValue\": 60,\n \"dynamicValue\": null\n },\n \"type\": \"NUMERIC\"\n }\n ]\n }\n ]\n}\n```\n\n You may also want to replace hardcoded values (for example, temperature \u003E 20) with the more dynamic expression (for example, temperature \u003E 'value of the tenant attribute with key 'temperatureThreshold'). It is possible to use 'dynamicValue' to define attribute of the tenant, customer or user that is performing the API call. See example below: \n\n```json\n{\n \"operation\": \"GREATER\",\n \"value\": {\n \"defaultValue\": 0,\n \"dynamicValue\": {\n \"sourceType\": \"CURRENT_USER\",\n \"sourceAttribute\": \"temperatureThreshold\"\n }\n },\n \"type\": \"NUMERIC\"\n}\n```\n\n Note that you may use 'CURRENT_USER', 'CURRENT_CUSTOMER' and 'CURRENT_TENANT' as a 'sourceType'. The 'defaultValue' is used when the attribute with such a name is not defined for the chosen source.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "findEntityDataByQuery", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EntityDataQuery" - } + "summary": "Get List of Relation Infos (findEntityRelationInfosByTo)", + "description": "Returns list of relation info objects for the specified entity by the 'to' direction. \n\nIf the user has the authority of 'System Administrator', the server checks that the entity is owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer. Relation Info is an extension of the default Relation object that contains information about the 'from' and 'to' entity names. ", + "operationId": "findEntityRelationInfosByTo", + "parameters": [ + { + "name": "toType", + "in": "path", + "description": "A string value representing the entity type. For example, 'DEVICE'", + "required": true, + "schema": { + "type": "string" } }, - "required": true - }, + { + "name": "toId", + "in": "path", + "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "relationTypeGroup", + "in": "query", + "description": "A string value representing relation type group. For example, 'COMMON'", + "required": false, + "schema": { + "type": "string" + } + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEntityData" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityRelationInfo" + } } } } @@ -37908,7 +37892,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -38012,65 +37996,53 @@ ] } }, - "/api/entitiesQuery/find/keys": { - "post": { + "/api/relations/to/{toType}/{toId}": { + "get": { "tags": [ - "entity-query-controller" + "entity-relation-controller" ], - "summary": "Find Available Entity Keys by Query (deprecated)", - "description": "**Deprecated.** Use the V2 endpoint (`POST /api/v2/entitiesQuery/find/keys`) instead.\n\nReturns unique time series and/or attribute key names from entities matching the query.\n\nExecutes the Entity Data Query to find up to 100 entities, then fetches and aggregates all distinct key names.\n\nPrimarily used for UI features like autocomplete suggestions.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "findAvailableEntityKeysByQuery", + "summary": "Get List of Relations (findEntityRelationsByTo)", + "description": "Returns list of relation objects for the specified entity by the 'to' direction. \n\nIf the user has the authority of 'System Administrator', the server checks that the entity is owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer.", + "operationId": "findEntityRelationsByTo", "parameters": [ { - "name": "timeseries", - "in": "query", - "description": "When true, includes unique time series key names in the response.\nWhen false, the 'timeseries' list will be empty.", + "name": "toType", + "in": "path", + "description": "A string value representing the entity type. For example, 'DEVICE'", "required": true, "schema": { - "type": "boolean" + "type": "string" } }, { - "name": "attributes", - "in": "query", - "description": "When true, includes unique attribute key names in the response.\nWhen false, the 'attribute' list will be empty. Use 'scope' parameter to filter by attribute scope.", + "name": "toId", + "in": "path", + "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { - "type": "boolean" + "type": "string" } }, { - "name": "scope", + "name": "relationTypeGroup", "in": "query", - "description": "Filters attribute keys by scope. Only applies when 'attributes' is true.\nIf not specified, returns attribute keys from all scopes.", + "description": "A string value representing relation type group. For example, 'COMMON'", "required": false, "schema": { - "type": "string", - "enum": [ - "SERVER_SCOPE", - "SHARED_SCOPE", - "CLIENT_SCOPE" - ] + "type": "string" } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EntityDataQuery" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AvailableEntityKeys" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityRelation" + } } } } @@ -38087,7 +38059,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -38181,7 +38153,6 @@ } } }, - "deprecated": true, "security": [ { "HttpLoginForm": [] @@ -38192,77 +38163,62 @@ ] } }, - "/api/v2/entitiesQuery/find/keys": { - "post": { + "/api/relations/to/{toType}/{toId}/{relationType}": { + "get": { "tags": [ - "entity-query-controller" + "entity-relation-controller" ], - "summary": "Find Available Entity Keys By Query", - "description": "Discovers unique time series and/or attribute key names available on entities that match the given query.\nWorks in two steps: first, the request body (an Entity Data Query) is executed to find matching entities\n(page size is capped at 100); then, all distinct key names are collected from those entities.\n\nOptionally, each key can include a sample — the most recent value (by timestamp) for that key\nacross all matched entities.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "findAvailableEntityKeysByQueryV2", + "summary": "Get List of Relations (findEntityRelationsByToAndRelationType)", + "description": "Returns list of relation objects for the specified entity by the 'to' direction and relation type. \n\nIf the user has the authority of 'System Administrator', the server checks that the entity is owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer.", + "operationId": "findEntityRelationsByToAndRelationType", "parameters": [ { - "name": "includeTimeseries", - "in": "query", - "description": "When true, includes unique time series keys in the response.\nWhen false, the 'timeseries' field is omitted. At least one of 'includeTimeseries' or 'includeAttributes' must be true.", - "required": false, + "name": "toType", + "in": "path", + "description": "A string value representing the entity type. For example, 'DEVICE'", + "required": true, "schema": { - "type": "boolean", - "default": true + "type": "string" } }, { - "name": "includeAttributes", - "in": "query", - "description": "When true, includes unique attribute keys in the response.\nWhen false, the 'attributes' field is omitted. At least one of 'includeTimeseries' or 'includeAttributes' must be true.", - "required": false, + "name": "toId", + "in": "path", + "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, "schema": { - "type": "boolean", - "default": true + "type": "string" } }, { - "name": "scopes", - "in": "query", - "description": "Filters attribute keys by scope. Only applies when 'includeAttributes' is true.\nWhen not specified, scopes are auto-determined: all three scopes (server, client, shared) for device entities,\nserver scope only for other entity types.", - "required": false, + "name": "relationType", + "in": "path", + "description": "A string value representing relation type between entities. For example, 'Contains', 'Manages'. It can be any string value.", + "required": true, "schema": { - "type": "string", - "enum": [ - "SERVER_SCOPE", - "SHARED_SCOPE", - "CLIENT_SCOPE" - ] + "type": "string" } }, { - "name": "includeSamples", + "name": "relationTypeGroup", "in": "query", - "description": "When true, each key entry includes a 'sample' object with the most recent value and timestamp.\nWhen false, only key names are returned (sample is omitted from JSON).", + "description": "A string value representing relation type group. For example, 'COMMON'", "required": false, "schema": { - "type": "boolean", - "default": false + "type": "string" } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EntityDataQuery" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AvailableEntityKeysV2" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityRelation" + } } } } @@ -38279,7 +38235,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -38383,14 +38339,157 @@ ] } }, - "/api/relation": { - "get": { + "/api/v2/relation": { + "post": { "tags": [ "entity-relation-controller" ], - "summary": "Get Relation (getRelation)", - "description": "Returns relation object between two specified entities if present. Otherwise throws exception. \n\nIf the user has the authority of 'System Administrator', the server checks that 'from' and 'to' entities are owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that 'from' and 'to' entities are owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the 'from' and 'to' entities are assigned to the same customer.", - "operationId": "getRelation", + "summary": "Create Relation (saveRelation)", + "description": "Creates or updates a relation between two entities in the platform. Relations unique key is a combination of from/to entity id and relation type group and relation type. \n\nIf the user has the authority of 'System Administrator', the server checks that 'from' and 'to' entities are owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that 'from' and 'to' entities are owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the 'from' and 'to' entities are assigned to the same customer.", + "operationId": "saveRelation", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityRelation" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityRelation" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingsboardErrorResponse" + }, + "examples": { + "error-code-400": { + "summary": "Bad Request", + "value": { + "status": 400, + "message": "Invalid request body", + "errorCode": 31, + "timestamp": 1609459200000 + } + } + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingsboardErrorResponse" + }, + "examples": { + "error-code-401": { + "summary": "Unauthorized", + "value": { + "status": 401, + "message": "Authentication failed", + "errorCode": 10, + "timestamp": 1609459200000 + } + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingsboardErrorResponse" + }, + "examples": { + "error-code-403": { + "summary": "Forbidden", + "value": { + "status": 403, + "message": "You don't have permission to perform this operation!", + "errorCode": 20, + "timestamp": 1609459200000 + } + } + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingsboardErrorResponse" + }, + "examples": { + "error-code-404": { + "summary": "Not Found", + "value": { + "status": 404, + "message": "Requested item wasn't found!", + "errorCode": 32, + "timestamp": 1609459200000 + } + } + } + } + } + }, + "429": { + "description": "Too Many Requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingsboardErrorResponse" + }, + "examples": { + "error-code-429": { + "summary": "Too Many Requests", + "value": { + "status": 429, + "message": "Too many requests for current tenant!", + "errorCode": 33, + "timestamp": 1609459200000 + } + } + } + } + } + } + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] + }, + "delete": { + "tags": [ + "entity-relation-controller" + ], + "summary": "Delete Relation (deleteRelation)", + "description": "Deletes a relation between two entities in the platform. \n\nIf the user has the authority of 'System Administrator', the server checks that 'from' and 'to' entities are owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that 'from' and 'to' entities are owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the 'from' and 'to' entities are assigned to the same customer.", + "operationId": "deleteRelation", "parameters": [ { "name": "fromId", @@ -38574,34 +38673,32 @@ ] } }, - "/api/relations": { - "post": { + "/api/customer/entityView/{entityViewId}": { + "delete": { "tags": [ - "entity-relation-controller" + "entity-view-controller" ], - "summary": "Find related entities (findEntityRelationsByQuery)", - "description": "Returns all entities that are related to the specific entity. The entity id, relation type, entity types, depth of the search, and other query parameters defined using complex 'EntityRelationsQuery' object. See 'Model' tab of the Parameters for more info.", - "operationId": "findEntityRelationsByQuery", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EntityRelationsQuery" - } + "summary": "Unassign Entity View from customer (unassignEntityViewFromCustomer)", + "description": "Clears assignment of the Entity View to customer. Customer will not be able to query Entity View afterwards.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "unassignEntityViewFromCustomer", + "parameters": [ + { + "name": "entityViewId", + "in": "path", + "description": "A string value representing the entity view id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" } - }, - "required": true - }, + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityRelation" - } + "$ref": "#/components/schemas/EntityView" } } } @@ -38618,7 +38715,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -38720,28 +38817,21 @@ "ApiKeyForm": [] } ] - }, - "delete": { + } + }, + "/api/customer/public/entityView/{entityViewId}": { + "post": { "tags": [ - "entity-relation-controller" + "entity-view-controller" ], - "summary": "Delete common relations (deleteRelations)", - "description": "Deletes all the relations ('from' and 'to' direction) for the specified entity and relation type group: 'COMMON'. \n\nIf the user has the authority of 'System Administrator', the server checks that the entity is owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer.", - "operationId": "deleteRelations", + "summary": "Make entity view publicly available (assignEntityViewToPublicCustomer)", + "description": "Entity View will be available for non-authorized (not logged-in) users. This is useful to create dashboards that you plan to share/embed on a publicly available website. However, users that are logged-in and belong to different tenant will not be able to access the entity view.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "assignEntityViewToPublicCustomer", "parameters": [ { - "name": "entityId", - "in": "query", - "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "entityType", - "in": "query", - "description": "A string value representing the entity type. For example, 'DEVICE'", + "name": "entityViewId", + "in": "path", + "description": "A string value representing the entity view id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" @@ -38750,7 +38840,14 @@ ], "responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityView" + } + } + } }, "400": { "description": "Bad Request", @@ -38764,7 +38861,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -38868,41 +38965,32 @@ ] } }, - "/api/relations/from/{fromType}/{fromId}": { - "get": { + "/api/customer/{customerId}/entityView/{entityViewId}": { + "post": { "tags": [ - "entity-relation-controller" + "entity-view-controller" ], - "summary": "Get List of Relations (findEntityRelationsByFrom)", - "description": "Returns list of relation objects for the specified entity by the 'from' direction. \n\nIf the user has the authority of 'System Administrator', the server checks that the entity is owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer.", - "operationId": "findEntityRelationsByFrom", + "summary": "Assign Entity View to customer (assignEntityViewToCustomer)", + "description": "Creates assignment of the Entity View to customer. Customer will be able to query Entity View afterwards.\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "assignEntityViewToCustomer", "parameters": [ { - "name": "fromType", + "name": "customerId", "in": "path", - "description": "A string value representing the entity type. For example, 'DEVICE'", + "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" } }, { - "name": "fromId", + "name": "entityViewId", "in": "path", - "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "A string value representing the entity view id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" } - }, - { - "name": "relationTypeGroup", - "in": "query", - "description": "A string value representing relation type group. For example, 'COMMON'", - "required": false, - "schema": { - "type": "string" - } } ], "responses": { @@ -38911,10 +38999,7 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityRelation" - } + "$ref": "#/components/schemas/EntityView" } } } @@ -38931,7 +39016,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -39035,50 +39120,89 @@ ] } }, - "/api/relations/from/{fromType}/{fromId}/{relationType}": { + "/api/customer/{customerId}/entityViewInfos": { "get": { "tags": [ - "entity-relation-controller" + "entity-view-controller" ], - "summary": "Get List of Relations (findEntityRelationsByFromAndRelationType)", - "description": "Returns list of relation objects for the specified entity by the 'from' direction and relation type. \n\nIf the user has the authority of 'System Administrator', the server checks that the entity is owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer.", - "operationId": "findEntityRelationsByFromAndRelationType", + "summary": "Get Customer Entity View info (getCustomerEntityViewInfos)", + "description": "Returns a page of Entity View info objects assigned to customer. Entity Views limit the degree of exposure of the Device or Asset telemetry and attributes to the Customers. Every Entity View references exactly one entity (device or asset) and defines telemetry and attribute keys that will be visible to the assigned Customer. As a Tenant Administrator you are able to create multiple EVs per Device or Asset and assign them to different Customers. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getCustomerEntityViewInfos", "parameters": [ { - "name": "fromType", + "name": "customerId", "in": "path", - "description": "A string value representing the entity type. For example, 'DEVICE'", + "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" } }, { - "name": "fromId", - "in": "path", - "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", "required": true, "schema": { - "type": "string" + "type": "integer", + "format": "int32" } }, { - "name": "relationType", - "in": "path", - "description": "A string value representing relation type between entities. For example, 'Contains', 'Manages'. It can be any string value.", + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "type", + "in": "query", + "description": "\n\n## Entity View Filter\n\nAllows to filter entity views based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Concrete Mixer' entity views which name starts with 'CAT':\n\n```json\n{\n \"type\": \"entityViewType\",\n \"entityViewType\": \"Concrete Mixer\",\n \"entityViewNameFilter\": \"CAT\"\n}\n```", + "required": false, "schema": { "type": "string" } }, { - "name": "relationTypeGroup", + "name": "textSearch", "in": "query", - "description": "A string value representing relation type group. For example, 'COMMON'", + "description": "The case insensitive 'substring' filter based on the entity view name.", "required": false, "schema": { "type": "string" } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string", + "enum": [ + "createdTime", + "name", + "type", + "customerTitle" + ] + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ASC", + "DESC" + ] + } } ], "responses": { @@ -39087,10 +39211,7 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityRelation" - } + "$ref": "#/components/schemas/PageDataEntityViewInfo" } } } @@ -39211,34 +39332,97 @@ ] } }, - "/api/relations/info": { - "post": { + "/api/customer/{customerId}/entityViews": { + "get": { "tags": [ - "entity-relation-controller" + "entity-view-controller" ], - "summary": "Find related entity infos (findEntityRelationInfosByQuery)", - "description": "Returns all entity infos that are related to the specific entity. The entity id, relation type, entity types, depth of the search, and other query parameters defined using complex 'EntityRelationsQuery' object. See 'Model' tab of the Parameters for more info. Relation Info is an extension of the default Relation object that contains information about the 'from' and 'to' entity names. ", - "operationId": "findEntityRelationInfosByQuery", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EntityRelationsQuery" - } + "summary": "Get Customer Entity Views (getCustomerEntityViews)", + "description": "Returns a page of Entity View objects assigned to customer. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getCustomerEntityViews", + "parameters": [ + { + "name": "customerId", + "in": "path", + "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" } }, - "required": true - }, + { + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "type", + "in": "query", + "description": "\n\n## Entity View Filter\n\nAllows to filter entity views based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Concrete Mixer' entity views which name starts with 'CAT':\n\n```json\n{\n \"type\": \"entityViewType\",\n \"entityViewType\": \"Concrete Mixer\",\n \"entityViewNameFilter\": \"CAT\"\n}\n```", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'substring' filter based on the entity view name.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string", + "enum": [ + "createdTime", + "name", + "type" + ] + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ASC", + "DESC" + ] + } + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityRelationInfo" - } + "$ref": "#/components/schemas/PageDataEntityView" } } } @@ -39255,7 +39439,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -39359,41 +39543,30 @@ ] } }, - "/api/relations/info/from/{fromType}/{fromId}": { - "get": { + "/api/edge/{edgeId}/entityView/{entityViewId}": { + "post": { "tags": [ - "entity-relation-controller" + "entity-view-controller" ], - "summary": "Get List of Relation Infos (findEntityRelationInfosByFrom)", - "description": "Returns list of relation info objects for the specified entity by the 'from' direction. \n\nIf the user has the authority of 'System Administrator', the server checks that the entity is owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer. Relation Info is an extension of the default Relation object that contains information about the 'from' and 'to' entity names. ", - "operationId": "findEntityRelationInfosByFrom", + "summary": "Assign entity view to edge (assignEntityViewToEdge)", + "description": "Creates assignment of an existing entity view to an instance of The Edge. Assignment works in async way - first, notification event pushed to edge service queue on platform. Second, remote edge service will receive a copy of assignment entity view (Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform). Third, once entity view will be delivered to edge service, it's going to be available for usage on remote edge instance.", + "operationId": "assignEntityViewToEdge", "parameters": [ { - "name": "fromType", + "name": "edgeId", "in": "path", - "description": "A string value representing the entity type. For example, 'DEVICE'", "required": true, "schema": { "type": "string" } }, { - "name": "fromId", + "name": "entityViewId", "in": "path", - "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" } - }, - { - "name": "relationTypeGroup", - "in": "query", - "description": "A string value representing relation type group. For example, 'COMMON'", - "required": false, - "schema": { - "type": "string" - } } ], "responses": { @@ -39402,10 +39575,7 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityRelationInfo" - } + "$ref": "#/components/schemas/EntityView" } } } @@ -39422,7 +39592,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -39524,43 +39694,30 @@ "ApiKeyForm": [] } ] - } - }, - "/api/relations/info/to/{toType}/{toId}": { - "get": { + }, + "delete": { "tags": [ - "entity-relation-controller" + "entity-view-controller" ], - "summary": "Get List of Relation Infos (findEntityRelationInfosByTo)", - "description": "Returns list of relation info objects for the specified entity by the 'to' direction. \n\nIf the user has the authority of 'System Administrator', the server checks that the entity is owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer. Relation Info is an extension of the default Relation object that contains information about the 'from' and 'to' entity names. ", - "operationId": "findEntityRelationInfosByTo", + "summary": "Unassign entity view from edge (unassignEntityViewFromEdge)", + "description": "Clears assignment of the entity view to the edge. Unassignment works in async way - first, 'unassign' notification event pushed to edge queue on platform. Second, remote edge service will receive an 'unassign' command to remove entity view (Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform). Third, once 'unassign' command will be delivered to edge service, it's going to remove entity view locally.", + "operationId": "unassignEntityViewFromEdge", "parameters": [ { - "name": "toType", + "name": "edgeId", "in": "path", - "description": "A string value representing the entity type. For example, 'DEVICE'", "required": true, "schema": { "type": "string" } }, { - "name": "toId", + "name": "entityViewId", "in": "path", - "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" } - }, - { - "name": "relationTypeGroup", - "in": "query", - "description": "A string value representing relation type group. For example, 'COMMON'", - "required": false, - "schema": { - "type": "string" - } } ], "responses": { @@ -39569,10 +39726,7 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityRelationInfo" - } + "$ref": "#/components/schemas/EntityView" } } } @@ -39693,41 +39847,89 @@ ] } }, - "/api/relations/to/{toType}/{toId}": { + "/api/edge/{edgeId}/entityViews": { "get": { "tags": [ - "entity-relation-controller" + "entity-view-controller" ], - "summary": "Get List of Relations (findEntityRelationsByTo)", - "description": "Returns list of relation objects for the specified entity by the 'to' direction. \n\nIf the user has the authority of 'System Administrator', the server checks that the entity is owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer.", - "operationId": "findEntityRelationsByTo", + "summary": "getEdgeEntityViews", + "operationId": "getEdgeEntityViews", "parameters": [ { - "name": "toType", + "name": "edgeId", "in": "path", - "description": "A string value representing the entity type. For example, 'DEVICE'", "required": true, "schema": { "type": "string" } }, { - "name": "toId", - "in": "path", - "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "name": "pageSize", + "in": "query", "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "page", + "in": "query", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "type", + "in": "query", + "required": false, "schema": { "type": "string" } }, { - "name": "relationTypeGroup", + "name": "textSearch", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sortProperty", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sortOrder", "in": "query", - "description": "A string value representing relation type group. For example, 'COMMON'", "required": false, "schema": { "type": "string" } + }, + { + "name": "startTime", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "endTime", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } } ], "responses": { @@ -39736,10 +39938,7 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityRelation" - } + "$ref": "#/components/schemas/PageDataEntityView" } } } @@ -39860,195 +40059,51 @@ ] } }, - "/api/relations/to/{toType}/{toId}/{relationType}": { - "get": { + "/api/entityView": { + "post": { "tags": [ - "entity-relation-controller" + "entity-view-controller" ], - "summary": "Get List of Relations (findEntityRelationsByToAndRelationType)", - "description": "Returns list of relation objects for the specified entity by the 'to' direction and relation type. \n\nIf the user has the authority of 'System Administrator', the server checks that the entity is owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer.", - "operationId": "findEntityRelationsByToAndRelationType", + "summary": "Save or update entity view (saveEntityView)", + "description": "Entity Views limit the degree of exposure of the Device or Asset telemetry and attributes to the Customers. Every Entity View references exactly one entity (device or asset) and defines telemetry and attribute keys that will be visible to the assigned Customer. As a Tenant Administrator you are able to create multiple EVs per Device or Asset and assign them to different Customers. See the 'Model' tab for more details.Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Entity View entity.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "saveEntityView", "parameters": [ { - "name": "toType", - "in": "path", - "description": "A string value representing the entity type. For example, 'DEVICE'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "toId", - "in": "path", - "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, + "name": "nameConflictPolicy", + "in": "query", + "description": "Optional value of name conflict policy. Possible values: FAIL or UNIQUIFY. If omitted, FAIL policy is applied. FAIL policy implies exception will be thrown if an entity with the same name already exists. UNIQUIFY policy appends a suffix to the entity name, if a name conflict occurs.", + "required": false, "schema": { - "type": "string" + "$ref": "#/components/schemas/NameConflictPolicy", + "default": "FAIL" } }, { - "name": "relationType", - "in": "path", - "description": "A string value representing relation type between entities. For example, 'Contains', 'Manages'. It can be any string value.", - "required": true, + "name": "uniquifySeparator", + "in": "query", + "description": "Optional value of name suffix separator used by UNIQUIFY policy. By default, underscore separator is used. For example, strategy is UNIQUIFY, separator is '-'; if a name conflict occurs for entity name 'test-name', created entity will have name like 'test-name-7fsh4f'.", + "required": false, "schema": { - "type": "string" + "type": "string", + "default": "_" } }, { - "name": "relationTypeGroup", + "name": "uniquifyStrategy", "in": "query", - "description": "A string value representing relation type group. For example, 'COMMON'", + "description": "Optional value of uniquify strategy used by UNIQUIFY policy. Possible values: RANDOM or INCREMENTAL. By default, RANDOM strategy is used, which means random alphanumeric string will be added as a suffix to entity name. INCREMENTAL implies the first possible number starting from 1 will be added as a name suffix. For example, strategy is UNIQUIFY, uniquify strategy is INCREMENTAL; if a name conflict occurs for entity name 'test-name', created entity will have name like 'test-name-1.", "required": false, "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityRelation" - } - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-400": { - "summary": "Bad Request", - "value": { - "status": 400, - "message": "Invalid UUID string: 123", - "errorCode": 31, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-401": { - "summary": "Unauthorized", - "value": { - "status": 401, - "message": "Authentication failed", - "errorCode": 10, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-403": { - "summary": "Forbidden", - "value": { - "status": 403, - "message": "You don't have permission to perform this operation!", - "errorCode": 20, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-404": { - "summary": "Not Found", - "value": { - "status": 404, - "message": "Requested item wasn't found!", - "errorCode": 32, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "429": { - "description": "Too Many Requests", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-429": { - "summary": "Too Many Requests", - "value": { - "status": 429, - "message": "Too many requests for current tenant!", - "errorCode": 33, - "timestamp": 1609459200000 - } - } - } - } + "$ref": "#/components/schemas/UniquifyStrategy", + "default": "RANDOM" } } - }, - "security": [ - { - "HttpLoginForm": [] - }, - { - "ApiKeyForm": [] - } - ] - } - }, - "/api/v2/relation": { - "post": { - "tags": [ - "entity-relation-controller" ], - "summary": "Create Relation (saveRelation)", - "description": "Creates or updates a relation between two entities in the platform. Relations unique key is a combination of from/to entity id and relation type group and relation type. \n\nIf the user has the authority of 'System Administrator', the server checks that 'from' and 'to' entities are owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that 'from' and 'to' entities are owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the 'from' and 'to' entities are assigned to the same customer.", - "operationId": "saveRelation", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EntityRelation" + "$ref": "#/components/schemas/EntityView" } } }, @@ -40060,7 +40115,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EntityRelation" + "$ref": "#/components/schemas/EntityView" } } } @@ -40179,64 +40234,21 @@ "ApiKeyForm": [] } ] - }, - "delete": { + } + }, + "/api/entityView/info/{entityViewId}": { + "get": { "tags": [ - "entity-relation-controller" + "entity-view-controller" ], - "summary": "Delete Relation (deleteRelation)", - "description": "Deletes a relation between two entities in the platform. \n\nIf the user has the authority of 'System Administrator', the server checks that 'from' and 'to' entities are owned by the sysadmin. If the user has the authority of 'Tenant Administrator', the server checks that 'from' and 'to' entities are owned by the same tenant. If the user has the authority of 'Customer User', the server checks that the 'from' and 'to' entities are assigned to the same customer.", - "operationId": "deleteRelation", + "summary": "Get Entity View info (getEntityViewInfoById)", + "description": "Fetch the Entity View info object based on the provided Entity View Id. Entity Views Info extends the Entity View with customer title and 'is public' flag. Entity Views limit the degree of exposure of the Device or Asset telemetry and attributes to the Customers. Every Entity View references exactly one entity (device or asset) and defines telemetry and attribute keys that will be visible to the assigned Customer. As a Tenant Administrator you are able to create multiple EVs per Device or Asset and assign them to different Customers. See the 'Model' tab for more details.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getEntityViewInfoById", "parameters": [ { - "name": "fromId", - "in": "query", - "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "fromType", - "in": "query", - "description": "A string value representing the entity type. For example, 'DEVICE'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "relationType", - "in": "query", - "description": "A string value representing relation type between entities. For example, 'Contains', 'Manages'. It can be any string value.", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "relationTypeGroup", - "in": "query", - "description": "A string value representing relation type group. For example, 'COMMON'", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "toId", - "in": "query", - "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "toType", - "in": "query", - "description": "A string value representing the entity type. For example, 'DEVICE'", + "name": "entityViewId", + "in": "path", + "description": "A string value representing the entity view id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" @@ -40249,7 +40261,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EntityRelation" + "$ref": "#/components/schemas/EntityViewInfo" } } } @@ -40370,32 +40382,24 @@ ] } }, - "/api/customer/entityView/{entityViewId}": { - "delete": { + "/api/entityView/types": { + "get": { "tags": [ "entity-view-controller" ], - "summary": "Unassign Entity View from customer (unassignEntityViewFromCustomer)", - "description": "Clears assignment of the Entity View to customer. Customer will not be able to query Entity View afterwards.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "unassignEntityViewFromCustomer", - "parameters": [ - { - "name": "entityViewId", - "in": "path", - "description": "A string value representing the entity view id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - } - ], + "summary": "Get Entity View Types (getEntityViewTypes)", + "description": "Returns a set of unique entity view types based on entity views that are either owned by the tenant or assigned to the customer which user is performing the request.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getEntityViewTypes", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EntityView" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntitySubtype" + } } } } @@ -40516,14 +40520,14 @@ ] } }, - "/api/customer/public/entityView/{entityViewId}": { - "post": { + "/api/entityView/{entityViewId}": { + "get": { "tags": [ "entity-view-controller" ], - "summary": "Make entity view publicly available (assignEntityViewToPublicCustomer)", - "description": "Entity View will be available for non-authorized (not logged-in) users. This is useful to create dashboards that you plan to share/embed on a publicly available website. However, users that are logged-in and belong to different tenant will not be able to access the entity view.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "assignEntityViewToPublicCustomer", + "summary": "Get entity view (getEntityViewById)", + "description": "Fetch the EntityView object based on the provided entity view id. Entity Views limit the degree of exposure of the Device or Asset telemetry and attributes to the Customers. Every Entity View references exactly one entity (device or asset) and defines telemetry and attribute keys that will be visible to the assigned Customer. As a Tenant Administrator you are able to create multiple EVs per Device or Asset and assign them to different Customers. See the 'Model' tab for more details.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getEntityViewById", "parameters": [ { "name": "entityViewId", @@ -40558,7 +40562,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -40660,26 +40664,15 @@ "ApiKeyForm": [] } ] - } - }, - "/api/customer/{customerId}/entityView/{entityViewId}": { - "post": { + }, + "delete": { "tags": [ "entity-view-controller" ], - "summary": "Assign Entity View to customer (assignEntityViewToCustomer)", - "description": "Creates assignment of the Entity View to customer. Customer will be able to query Entity View afterwards.\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "assignEntityViewToCustomer", + "summary": "Delete entity view (deleteEntityView)", + "description": "Delete the EntityView object based on the provided entity view id. \n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "deleteEntityView", "parameters": [ - { - "name": "customerId", - "in": "path", - "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, { "name": "entityViewId", "in": "path", @@ -40692,14 +40685,7 @@ ], "responses": { "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EntityView" - } - } - } + "description": "OK" }, "400": { "description": "Bad Request", @@ -40713,7 +40699,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -40817,98 +40803,34 @@ ] } }, - "/api/customer/{customerId}/entityViewInfos": { - "get": { + "/api/entityViews": { + "post": { "tags": [ "entity-view-controller" ], - "summary": "Get Customer Entity View info (getCustomerEntityViewInfos)", - "description": "Returns a page of Entity View info objects assigned to customer. Entity Views limit the degree of exposure of the Device or Asset telemetry and attributes to the Customers. Every Entity View references exactly one entity (device or asset) and defines telemetry and attribute keys that will be visible to the assigned Customer. As a Tenant Administrator you are able to create multiple EVs per Device or Asset and assign them to different Customers. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getCustomerEntityViewInfos", - "parameters": [ - { - "name": "customerId", - "in": "path", - "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "type", - "in": "query", - "description": "\n\n## Entity View Filter\n\nAllows to filter entity views based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Concrete Mixer' entity views which name starts with 'CAT':\n\n```json\n{\n \"type\": \"entityViewType\",\n \"entityViewType\": \"Concrete Mixer\",\n \"entityViewNameFilter\": \"CAT\"\n}\n```", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'substring' filter based on the entity view name.", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string", - "enum": [ - "createdTime", - "name", - "type", - "customerTitle" - ] + "summary": "Find related entity views (findEntityViewsByQuery)", + "description": "Returns all entity views that are related to the specific entity. The entity id, relation type, entity view types, depth of the search, and other query parameters defined using complex 'EntityViewSearchQuery' object. See 'Model' tab of the Parameters for more info.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "findEntityViewsByQuery", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityViewSearchQuery" + } } }, - { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] - } - } - ], + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEntityViewInfo" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityView" + } } } } @@ -40925,7 +40847,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -41029,87 +40951,25 @@ ] } }, - "/api/customer/{customerId}/entityViews": { + "/api/entityViews/list": { "get": { "tags": [ "entity-view-controller" ], - "summary": "Get Customer Entity Views (getCustomerEntityViews)", - "description": "Returns a page of Entity View objects assigned to customer. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getCustomerEntityViews", + "summary": "Get Entity Views By Ids (getEntityViewsByIds)", + "description": "Requested entity views must be owned by tenant or assigned to customer which user is performing the request. ", + "operationId": "getEntityViewsByIds", "parameters": [ { - "name": "customerId", - "in": "path", - "description": "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", + "name": "entityViewIds", "in": "query", - "description": "Sequence number of page starting from 0", + "description": "A list of entity view ids, separated by comma ','", "required": true, "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "type", - "in": "query", - "description": "\n\n## Entity View Filter\n\nAllows to filter entity views based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Concrete Mixer' entity views which name starts with 'CAT':\n\n```json\n{\n \"type\": \"entityViewType\",\n \"entityViewType\": \"Concrete Mixer\",\n \"entityViewNameFilter\": \"CAT\"\n}\n```", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'substring' filter based on the entity view name.", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string", - "enum": [ - "createdTime", - "name", - "type" - ] - } - }, - { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] + "type": "array", + "items": { + "type": "string" + } } } ], @@ -41119,7 +40979,10 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEntityView" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityView" + } } } } @@ -41240,26 +41103,19 @@ ] } }, - "/api/edge/{edgeId}/entityView/{entityViewId}": { - "post": { + "/api/tenant/entityView": { + "get": { "tags": [ "entity-view-controller" ], - "summary": "Assign entity view to edge (assignEntityViewToEdge)", - "description": "Creates assignment of an existing entity view to an instance of The Edge. Assignment works in async way - first, notification event pushed to edge service queue on platform. Second, remote edge service will receive a copy of assignment entity view (Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform). Third, once entity view will be delivered to edge service, it's going to be available for usage on remote edge instance.", - "operationId": "assignEntityViewToEdge", + "summary": "Get Entity View by name (getTenantEntityViewByName)", + "description": "Fetch the Entity View object based on the tenant id and entity view name. \n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getTenantEntityViewByName", "parameters": [ { - "name": "edgeId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "entityViewId", - "in": "path", + "name": "entityViewName", + "in": "query", + "description": "Entity View name", "required": true, "schema": { "type": "string" @@ -41289,7 +41145,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -41391,30 +41247,82 @@ "ApiKeyForm": [] } ] - }, - "delete": { + } + }, + "/api/tenant/entityViewInfos": { + "get": { "tags": [ "entity-view-controller" ], - "summary": "Unassign entity view from edge (unassignEntityViewFromEdge)", - "description": "Clears assignment of the entity view to the edge. Unassignment works in async way - first, 'unassign' notification event pushed to edge queue on platform. Second, remote edge service will receive an 'unassign' command to remove entity view (Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform). Third, once 'unassign' command will be delivered to edge service, it's going to remove entity view locally.", - "operationId": "unassignEntityViewFromEdge", + "summary": "Get Tenant Entity Views (getTenantEntityViews)", + "description": "Returns a page of entity views info owned by tenant. Entity Views limit the degree of exposure of the Device or Asset telemetry and attributes to the Customers. Every Entity View references exactly one entity (device or asset) and defines telemetry and attribute keys that will be visible to the assigned Customer. As a Tenant Administrator you are able to create multiple EVs per Device or Asset and assign them to different Customers. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getTenantEntityViewInfos", "parameters": [ { - "name": "edgeId", - "in": "path", + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", "required": true, "schema": { - "type": "string" + "type": "integer", + "format": "int32" } }, { - "name": "entityViewId", - "in": "path", + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "type", + "in": "query", + "description": "\n\n## Entity View Filter\n\nAllows to filter entity views based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Concrete Mixer' entity views which name starts with 'CAT':\n\n```json\n{\n \"type\": \"entityViewType\",\n \"entityViewType\": \"Concrete Mixer\",\n \"entityViewNameFilter\": \"CAT\"\n}\n```", + "required": false, "schema": { "type": "string" } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'substring' filter based on the entity view name.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string", + "enum": [ + "createdTime", + "name", + "type", + "customerTitle" + ] + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ASC", + "DESC" + ] + } } ], "responses": { @@ -41423,7 +41331,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EntityView" + "$ref": "#/components/schemas/PageDataEntityViewInfo" } } } @@ -41544,25 +41452,19 @@ ] } }, - "/api/edge/{edgeId}/entityViews": { + "/api/tenant/entityViews": { "get": { "tags": [ "entity-view-controller" ], - "summary": "getEdgeEntityViews", - "operationId": "getEdgeEntityViews", + "summary": "Get Tenant Entity Views (getTenantEntityViews)", + "description": "Returns a page of entity views owned by tenant. Entity Views limit the degree of exposure of the Device or Asset telemetry and attributes to the Customers. Every Entity View references exactly one entity (device or asset) and defines telemetry and attribute keys that will be visible to the assigned Customer. As a Tenant Administrator you are able to create multiple EVs per Device or Asset and assign them to different Customers. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getTenantEntityViews", "parameters": [ - { - "name": "edgeId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, { "name": "pageSize", "in": "query", + "description": "Maximum amount of entities in a one page", "required": true, "schema": { "type": "integer", @@ -41572,6 +41474,7 @@ { "name": "page", "in": "query", + "description": "Sequence number of page starting from 0", "required": true, "schema": { "type": "integer", @@ -41581,6 +41484,7 @@ { "name": "type", "in": "query", + "description": "\n\n## Entity View Filter\n\nAllows to filter entity views based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Concrete Mixer' entity views which name starts with 'CAT':\n\n```json\n{\n \"type\": \"entityViewType\",\n \"entityViewType\": \"Concrete Mixer\",\n \"entityViewNameFilter\": \"CAT\"\n}\n```", "required": false, "schema": { "type": "string" @@ -41589,6 +41493,7 @@ { "name": "textSearch", "in": "query", + "description": "The case insensitive 'substring' filter based on the entity view name.", "required": false, "schema": { "type": "string" @@ -41597,35 +41502,28 @@ { "name": "sortProperty", "in": "query", + "description": "Property of entity to sort by", "required": false, "schema": { - "type": "string" + "type": "string", + "enum": [ + "createdTime", + "name", + "type" + ] } }, { "name": "sortOrder", "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", "required": false, "schema": { - "type": "string" - } - }, - { - "name": "startTime", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "endTime", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "format": "int64" + "type": "string", + "enum": [ + "ASC", + "DESC" + ] } } ], @@ -41756,43 +41654,115 @@ ] } }, - "/api/entityView": { + "/api/events/{entityType}/{entityId}": { "post": { "tags": [ - "entity-view-controller" + "event-controller" ], - "summary": "Save or update entity view (saveEntityView)", - "description": "Entity Views limit the degree of exposure of the Device or Asset telemetry and attributes to the Customers. Every Entity View references exactly one entity (device or asset) and defines telemetry and attribute keys that will be visible to the assigned Customer. As a Tenant Administrator you are able to create multiple EVs per Device or Asset and assign them to different Customers. See the 'Model' tab for more details.Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Entity View entity.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "saveEntityView", + "summary": "Get Events by event filter (getEventsByFilter)", + "description": "Returns a page of events for the chosen entity by specifying the event filter. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\n# Event Filter Definition\n\n6 different eventFilter objects could be set for different event types. The eventType field is required. Others are optional. If some of them are set, the filtering will be applied according to them. See the examples below for all the fields used for each event type filtering. \n\nNote,\n\n * 'server' - string value representing the server name, identifier or ip address where the platform is running;\n * 'errorStr' - the case insensitive 'contains' filter based on error message.\n\n## Error Event Filter\n\n```json\n{\n \"eventType\":\"ERROR\",\n \"server\":\"ip-172-31-24-152\",\n \"method\":\"onClusterEventMsg\",\n \"errorStr\":\"Error Message\"\n}\n```\n\n * 'method' - string value representing the method name when the error happened.\n\n## Lifecycle Event Filter\n\n```json\n{\n \"eventType\":\"LC_EVENT\",\n \"server\":\"ip-172-31-24-152\",\n \"event\":\"STARTED\",\n \"status\":\"Success\",\n \"errorStr\":\"Error Message\"\n}\n```\n\n * 'event' - string value representing the lifecycle event type;\n * 'status' - string value representing status of the lifecycle event.\n\n## Statistics Event Filter\n\n```json\n{\n \"eventType\":\"STATS\",\n \"server\":\"ip-172-31-24-152\",\n \"messagesProcessed\":10,\n \"errorsOccurred\":5\n}\n```\n\n * 'messagesProcessed' - the minimum number of successfully processed messages;\n * 'errorsOccurred' - the minimum number of errors occurred during messages processing.\n\n## Debug Rule Node Event Filter\n\n```json\n{\n \"eventType\":\"DEBUG_RULE_NODE\",\n \"msgDirectionType\":\"IN\",\n \"server\":\"ip-172-31-24-152\",\n \"dataSearch\":\"humidity\",\n \"metadataSearch\":\"deviceName\",\n \"entityName\":\"DEVICE\",\n \"relationType\":\"Success\",\n \"entityId\":\"de9d54a0-2b7a-11ec-a3cc-23386423d98f\",\n \"msgType\":\"POST_TELEMETRY_REQUEST\",\n \"isError\":\"false\",\n \"errorStr\":\"Error Message\"\n}\n```\n\n## Debug Rule Chain Event Filter\n\n```json\n{\n \"eventType\":\"DEBUG_RULE_CHAIN\",\n \"msgDirectionType\":\"IN\",\n \"server\":\"ip-172-31-24-152\",\n \"dataSearch\":\"humidity\",\n \"metadataSearch\":\"deviceName\",\n \"entityName\":\"DEVICE\",\n \"relationType\":\"Success\",\n \"entityId\":\"de9d54a0-2b7a-11ec-a3cc-23386423d98f\",\n \"msgType\":\"POST_TELEMETRY_REQUEST\",\n \"isError\":\"false\",\n \"errorStr\":\"Error Message\"\n}\n```\n\n * 'msgDirectionType' - string value representing msg direction type (incoming to entity or outcoming from entity);\n * 'dataSearch' - the case insensitive 'contains' filter based on data (key and value) for the message;\n * 'metadataSearch' - the case insensitive 'contains' filter based on metadata (key and value) for the message;\n * 'entityName' - string value representing the entity type;\n * 'relationType' - string value representing the type of message routing;\n * 'entityId' - string value representing the entity id in the event body (originator of the message);\n * 'msgType' - string value representing the message type;\n * 'isError' - boolean value to filter the errors.\n\n## Debug Calculated Field Event Filter\n\n```json\n{\n \"eventType\":\"DEBUG_CALCULATED_FIELD\",\n \"server\":\"ip-172-31-24-152\",\n \"isError\":\"false\",\n \"errorStr\":\"Error Message\"\n \"entityId\":\"cf4b8741-f618-471f-ae08-d881ca7f9fe9\",\n \"msgId\":\"5cf7d3a0-aee7-40dd-a737-ade05528e7eb\",\n \"msgType\":\"POST_TELEMETRY_REQUEST\",\n \"arguments\":\"{\n \"x\": {\n \"ts\": 1739432016629,\n \"value\": 20\n },\n \"y\": {\n \"ts\": 1739429717656,\n \"value\": 12\n }\n }\",\n \"result\":\"{\n \"x + y\": 32\n }\",\n}\n```\n\n * 'entityId' - string value representing the entity id in the event body;\n * 'entityType' - string value representing the entity type;\n * 'msgId' - string value representing the message id in the rule engine;\n * 'msgType' - string value representing the message type;\n * 'arguments' - string value representing the arguments that were used in the calculation performed;\n * 'result' - string value representing the result of a calculation;\n * 'isError' - boolean value to filter the errors.\n\n", + "operationId": "getEventsByFilter", "parameters": [ { - "name": "nameConflictPolicy", + "name": "entityType", + "in": "path", + "description": "A string value representing the entity type. For example, 'DEVICE'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "entityId", + "in": "path", + "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "tenantId", "in": "query", - "description": "Optional value of name conflict policy. Possible values: FAIL or UNIQUIFY. If omitted, FAIL policy is applied. FAIL policy implies exception will be thrown if an entity with the same name already exists. UNIQUIFY policy appends a suffix to the entity name, if a name conflict occurs.", + "description": "A string value representing the tenant id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The value is not used in searching.", "required": false, "schema": { - "$ref": "#/components/schemas/NameConflictPolicy", - "default": "FAIL" + "type": "string" } }, { - "name": "uniquifySeparator", + "name": "sortProperty", "in": "query", - "description": "Optional value of name suffix separator used by UNIQUIFY policy. By default, underscore separator is used. For example, strategy is UNIQUIFY, separator is '-'; if a name conflict occurs for entity name 'test-name', created entity will have name like 'test-name-7fsh4f'.", + "description": "Property of entity to sort by", "required": false, "schema": { "type": "string", - "default": "_" + "enum": [ + "ts", + "id" + ] } }, { - "name": "uniquifyStrategy", + "name": "sortOrder", "in": "query", - "description": "Optional value of uniquify strategy used by UNIQUIFY policy. Possible values: RANDOM or INCREMENTAL. By default, RANDOM strategy is used, which means random alphanumeric string will be added as a suffix to entity name. INCREMENTAL implies the first possible number starting from 1 will be added as a name suffix. For example, strategy is UNIQUIFY, uniquify strategy is INCREMENTAL; if a name conflict occurs for entity name 'test-name', created entity will have name like 'test-name-1.", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", "required": false, "schema": { - "$ref": "#/components/schemas/UniquifyStrategy", - "default": "RANDOM" + "type": "string", + "enum": [ + "ASC", + "DESC" + ] + } + }, + { + "name": "startTime", + "in": "query", + "description": "Timestamp. Events with creation time before it won't be queried.", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "endTime", + "in": "query", + "description": "Timestamp. Events with creation time after it won't be queried.", + "required": false, + "schema": { + "type": "integer", + "format": "int64" } } ], @@ -41800,7 +41770,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EntityView" + "$ref": "#/components/schemas/EventFilter" } } }, @@ -41812,7 +41782,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EntityView" + "$ref": "#/components/schemas/PageDataEventInfo" } } } @@ -41933,36 +41903,68 @@ ] } }, - "/api/entityView/info/{entityViewId}": { - "get": { + "/api/events/{entityType}/{entityId}/clear": { + "post": { "tags": [ - "entity-view-controller" + "event-controller" ], - "summary": "Get Entity View info (getEntityViewInfoById)", - "description": "Fetch the Entity View info object based on the provided Entity View Id. Entity Views Info extends the Entity View with customer title and 'is public' flag. Entity Views limit the degree of exposure of the Device or Asset telemetry and attributes to the Customers. Every Entity View references exactly one entity (device or asset) and defines telemetry and attribute keys that will be visible to the assigned Customer. As a Tenant Administrator you are able to create multiple EVs per Device or Asset and assign them to different Customers. See the 'Model' tab for more details.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getEntityViewInfoById", + "summary": "Clear Events (clearEvents)", + "description": "Clears events by filter for specified entity.", + "operationId": "clearEvents", "parameters": [ { - "name": "entityViewId", + "name": "entityType", "in": "path", - "description": "A string value representing the entity view id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "A string value representing the entity type. For example, 'DEVICE'", "required": true, "schema": { "type": "string" } + }, + { + "name": "entityId", + "in": "path", + "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "startTime", + "in": "query", + "description": "Timestamp. Events with creation time before it won't be queried.", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "endTime", + "in": "query", + "description": "Timestamp. Events with creation time after it won't be queried.", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } } ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EntityViewInfo" - } + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EventFilter" } } }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, "400": { "description": "Bad Request", "content": { @@ -41975,7 +41977,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -42079,24 +42081,135 @@ ] } }, - "/api/entityView/types": { + "/api/events/{entityType}/{entityId}/{eventType}": { "get": { "tags": [ - "entity-view-controller" + "event-controller" + ], + "summary": "Get Events by type (getEventsByType)", + "description": "Returns a page of events for specified entity by specifying event type. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. ", + "operationId": "getEventsByType", + "parameters": [ + { + "name": "entityType", + "in": "path", + "description": "A string value representing the entity type. For example, 'DEVICE'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "entityId", + "in": "path", + "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "eventType", + "in": "path", + "description": "A string value representing event type", + "required": true, + "schema": { + "type": "string" + }, + "example": "STATS" + }, + { + "name": "tenantId", + "in": "query", + "description": "A string value representing the tenant id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The value is not used in searching.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ts", + "id" + ] + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ASC", + "DESC" + ] + } + }, + { + "name": "startTime", + "in": "query", + "description": "Timestamp. Events with creation time before it won't be queried.", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "endTime", + "in": "query", + "description": "Timestamp. Events with creation time after it won't be queried.", + "required": false, + "schema": { + "type": "integer", + "format": "int64" + } + } ], - "summary": "Get Entity View Types (getEntityViewTypes)", - "description": "Returns a set of unique entity view types based on entity views that are either owned by the tenant or assigned to the customer which user is performing the request.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getEntityViewTypes", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntitySubtype" - } + "$ref": "#/components/schemas/PageDataEventInfo" } } } @@ -42217,32 +42330,44 @@ ] } }, - "/api/entityView/{entityViewId}": { - "get": { + "/api/image": { + "post": { "tags": [ - "entity-view-controller" + "image-controller" ], - "summary": "Get entity view (getEntityViewById)", - "description": "Fetch the EntityView object based on the provided entity view id. Entity Views limit the degree of exposure of the Device or Asset telemetry and attributes to the Customers. Every Entity View references exactly one entity (device or asset) and defines telemetry and attribute keys that will be visible to the assigned Customer. As a Tenant Administrator you are able to create multiple EVs per Device or Asset and assign them to different Customers. See the 'Model' tab for more details.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getEntityViewById", - "parameters": [ - { - "name": "entityViewId", - "in": "path", - "description": "A string value representing the entity view id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" + "summary": "uploadImage", + "operationId": "uploadImage", + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "format": "binary" + }, + "title": { + "type": "string" + }, + "imageSubType": { + "type": "string" + } + }, + "required": [ + "file" + ] + } } } - ], + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EntityView" + "$ref": "#/components/schemas/TbResourceInfo" } } } @@ -42259,7 +42384,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -42361,28 +42486,35 @@ "ApiKeyForm": [] } ] - }, - "delete": { + } + }, + "/api/image/import": { + "put": { "tags": [ - "entity-view-controller" + "image-controller" ], - "summary": "Delete entity view (deleteEntityView)", - "description": "Delete the EntityView object based on the provided entity view id. \n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "deleteEntityView", - "parameters": [ - { - "name": "entityViewId", - "in": "path", - "description": "A string value representing the entity view id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" + "summary": "importImage", + "operationId": "importImage", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceExportData" + } } - } - ], + }, + "required": true + }, "responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TbResourceInfo" + } + } + } }, "400": { "description": "Bad Request", @@ -42500,34 +42632,101 @@ ] } }, - "/api/entityViews": { - "post": { + "/api/images": { + "get": { "tags": [ - "entity-view-controller" + "image-controller" ], - "summary": "Find related entity views (findEntityViewsByQuery)", - "description": "Returns all entity views that are related to the specific entity. The entity id, relation type, entity view types, depth of the search, and other query parameters defined using complex 'EntityViewSearchQuery' object. See 'Model' tab of the Parameters for more info.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "findEntityViewsByQuery", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EntityViewSearchQuery" - } + "summary": "getImages", + "operationId": "getImages", + "parameters": [ + { + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", + "required": true, + "schema": { + "type": "integer", + "format": "int32" } }, - "required": true - }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "imageSubType", + "in": "query", + "description": "A string value representing resource sub-type.", + "required": false, + "schema": { + "type": "string", + "enum": [ + "IMAGE", + "SCADA_SYMBOL" + ] + } + }, + { + "name": "includeSystemImages", + "in": "query", + "description": "Use 'true' to include system images. Disabled by default. Ignored for requests by users with system administrator authority.", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'substring' filter based on the resource title.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string", + "enum": [ + "createdTime", + "title", + "resourceType", + "tenantId" + ] + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ASC", + "DESC" + ] + } + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityView" - } + "$ref": "#/components/schemas/PageDataTbResourceInfo" } } } @@ -42544,7 +42743,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -42648,25 +42847,36 @@ ] } }, - "/api/entityViews/list": { + "/api/images/public/{publicResourceKey}": { "get": { "tags": [ - "entity-view-controller" + "image-controller" ], - "summary": "Get Entity Views By Ids (getEntityViewsByIds)", - "description": "Requested entity views must be owned by tenant or assigned to customer which user is performing the request. ", - "operationId": "getEntityViewsByIds", + "summary": "downloadPublicImage", + "operationId": "downloadPublicImage", "parameters": [ { - "name": "entityViewIds", - "in": "query", - "description": "A list of entity view ids, separated by comma ','", + "name": "publicResourceKey", + "in": "path", "required": true, "schema": { - "type": "array", - "items": { - "type": "string" - } + "type": "string" + } + }, + { + "name": "If-None-Match", + "in": "header", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "Accept-Encoding", + "in": "header", + "required": false, + "schema": { + "type": "string" } } ], @@ -42674,12 +42884,10 @@ "200": { "description": "OK", "content": { - "application/json": { + "image/*": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityView" - } + "type": "string", + "format": "binary" } } } @@ -42800,32 +43008,61 @@ ] } }, - "/api/tenant/entityView": { + "/api/images/{type}/{key}": { "get": { "tags": [ - "entity-view-controller" + "image-controller" ], - "summary": "Get Entity View by name (getTenantEntityViewByName)", - "description": "Fetch the Entity View object based on the tenant id and entity view name. \n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getTenantEntityViewByName", + "summary": "downloadImage", + "operationId": "downloadImage", "parameters": [ { - "name": "entityViewName", - "in": "query", - "description": "Entity View name", + "name": "type", + "in": "path", + "description": "Type of the image: tenant or system", + "required": true, + "schema": { + "type": "string", + "enum": [ + "tenant", + "system" + ] + } + }, + { + "name": "key", + "in": "path", + "description": "Image resource key, for example thermostats_dashboard_background.jpeg", "required": true, "schema": { "type": "string" } + }, + { + "name": "If-None-Match", + "in": "header", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "Accept-Encoding", + "in": "header", + "required": false, + "schema": { + "type": "string" + } } ], "responses": { "200": { "description": "OK", "content": { - "application/json": { + "image/*": { "schema": { - "$ref": "#/components/schemas/EntityView" + "type": "string", + "format": "binary" } } } @@ -42944,1996 +43181,62 @@ "ApiKeyForm": [] } ] - } - }, - "/api/tenant/entityViewInfos": { - "get": { + }, + "put": { "tags": [ - "entity-view-controller" + "image-controller" ], - "summary": "Get Tenant Entity Views (getTenantEntityViews)", - "description": "Returns a page of entity views info owned by tenant. Entity Views limit the degree of exposure of the Device or Asset telemetry and attributes to the Customers. Every Entity View references exactly one entity (device or asset) and defines telemetry and attribute keys that will be visible to the assigned Customer. As a Tenant Administrator you are able to create multiple EVs per Device or Asset and assign them to different Customers. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getTenantEntityViewInfos", + "summary": "updateImage", + "operationId": "updateImage", "parameters": [ - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, { "name": "type", - "in": "query", - "description": "\n\n## Entity View Filter\n\nAllows to filter entity views based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Concrete Mixer' entity views which name starts with 'CAT':\n\n```json\n{\n \"type\": \"entityViewType\",\n \"entityViewType\": \"Concrete Mixer\",\n \"entityViewNameFilter\": \"CAT\"\n}\n```", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'substring' filter based on the entity view name.", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, + "in": "path", + "description": "Type of the image: tenant or system", + "required": true, "schema": { "type": "string", "enum": [ - "createdTime", - "name", - "type", - "customerTitle" + "tenant", + "system" ] } }, { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, + "name": "key", + "in": "path", + "description": "Image resource key, for example thermostats_dashboard_background.jpeg", + "required": true, "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] + "type": "string" } } ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "format": "binary" + } + }, + "required": [ + "file" + ] + } + } + } + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEntityViewInfo" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-400": { - "summary": "Bad Request", - "value": { - "status": 400, - "message": "Invalid UUID string: 123", - "errorCode": 31, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-401": { - "summary": "Unauthorized", - "value": { - "status": 401, - "message": "Authentication failed", - "errorCode": 10, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-403": { - "summary": "Forbidden", - "value": { - "status": 403, - "message": "You don't have permission to perform this operation!", - "errorCode": 20, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-404": { - "summary": "Not Found", - "value": { - "status": 404, - "message": "Requested item wasn't found!", - "errorCode": 32, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "429": { - "description": "Too Many Requests", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-429": { - "summary": "Too Many Requests", - "value": { - "status": 429, - "message": "Too many requests for current tenant!", - "errorCode": 33, - "timestamp": 1609459200000 - } - } - } - } - } - } - }, - "security": [ - { - "HttpLoginForm": [] - }, - { - "ApiKeyForm": [] - } - ] - } - }, - "/api/tenant/entityViews": { - "get": { - "tags": [ - "entity-view-controller" - ], - "summary": "Get Tenant Entity Views (getTenantEntityViews)", - "description": "Returns a page of entity views owned by tenant. Entity Views limit the degree of exposure of the Device or Asset telemetry and attributes to the Customers. Every Entity View references exactly one entity (device or asset) and defines telemetry and attribute keys that will be visible to the assigned Customer. As a Tenant Administrator you are able to create multiple EVs per Device or Asset and assign them to different Customers. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getTenantEntityViews", - "parameters": [ - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "type", - "in": "query", - "description": "\n\n## Entity View Filter\n\nAllows to filter entity views based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all 'Concrete Mixer' entity views which name starts with 'CAT':\n\n```json\n{\n \"type\": \"entityViewType\",\n \"entityViewType\": \"Concrete Mixer\",\n \"entityViewNameFilter\": \"CAT\"\n}\n```", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'substring' filter based on the entity view name.", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string", - "enum": [ - "createdTime", - "name", - "type" - ] - } - }, - { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PageDataEntityView" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-400": { - "summary": "Bad Request", - "value": { - "status": 400, - "message": "Invalid UUID string: 123", - "errorCode": 31, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-401": { - "summary": "Unauthorized", - "value": { - "status": 401, - "message": "Authentication failed", - "errorCode": 10, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-403": { - "summary": "Forbidden", - "value": { - "status": 403, - "message": "You don't have permission to perform this operation!", - "errorCode": 20, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-404": { - "summary": "Not Found", - "value": { - "status": 404, - "message": "Requested item wasn't found!", - "errorCode": 32, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "429": { - "description": "Too Many Requests", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-429": { - "summary": "Too Many Requests", - "value": { - "status": 429, - "message": "Too many requests for current tenant!", - "errorCode": 33, - "timestamp": 1609459200000 - } - } - } - } - } - } - }, - "security": [ - { - "HttpLoginForm": [] - }, - { - "ApiKeyForm": [] - } - ] - } - }, - "/api/events/{entityType}/{entityId}": { - "post": { - "tags": [ - "event-controller" - ], - "summary": "Get Events by event filter (getEventsByFilter)", - "description": "Returns a page of events for the chosen entity by specifying the event filter. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. \n\n# Event Filter Definition\n\n6 different eventFilter objects could be set for different event types. The eventType field is required. Others are optional. If some of them are set, the filtering will be applied according to them. See the examples below for all the fields used for each event type filtering. \n\nNote,\n\n * 'server' - string value representing the server name, identifier or ip address where the platform is running;\n * 'errorStr' - the case insensitive 'contains' filter based on error message.\n\n## Error Event Filter\n\n```json\n{\n \"eventType\":\"ERROR\",\n \"server\":\"ip-172-31-24-152\",\n \"method\":\"onClusterEventMsg\",\n \"errorStr\":\"Error Message\"\n}\n```\n\n * 'method' - string value representing the method name when the error happened.\n\n## Lifecycle Event Filter\n\n```json\n{\n \"eventType\":\"LC_EVENT\",\n \"server\":\"ip-172-31-24-152\",\n \"event\":\"STARTED\",\n \"status\":\"Success\",\n \"errorStr\":\"Error Message\"\n}\n```\n\n * 'event' - string value representing the lifecycle event type;\n * 'status' - string value representing status of the lifecycle event.\n\n## Statistics Event Filter\n\n```json\n{\n \"eventType\":\"STATS\",\n \"server\":\"ip-172-31-24-152\",\n \"messagesProcessed\":10,\n \"errorsOccurred\":5\n}\n```\n\n * 'messagesProcessed' - the minimum number of successfully processed messages;\n * 'errorsOccurred' - the minimum number of errors occurred during messages processing.\n\n## Debug Rule Node Event Filter\n\n```json\n{\n \"eventType\":\"DEBUG_RULE_NODE\",\n \"msgDirectionType\":\"IN\",\n \"server\":\"ip-172-31-24-152\",\n \"dataSearch\":\"humidity\",\n \"metadataSearch\":\"deviceName\",\n \"entityName\":\"DEVICE\",\n \"relationType\":\"Success\",\n \"entityId\":\"de9d54a0-2b7a-11ec-a3cc-23386423d98f\",\n \"msgType\":\"POST_TELEMETRY_REQUEST\",\n \"isError\":\"false\",\n \"errorStr\":\"Error Message\"\n}\n```\n\n## Debug Rule Chain Event Filter\n\n```json\n{\n \"eventType\":\"DEBUG_RULE_CHAIN\",\n \"msgDirectionType\":\"IN\",\n \"server\":\"ip-172-31-24-152\",\n \"dataSearch\":\"humidity\",\n \"metadataSearch\":\"deviceName\",\n \"entityName\":\"DEVICE\",\n \"relationType\":\"Success\",\n \"entityId\":\"de9d54a0-2b7a-11ec-a3cc-23386423d98f\",\n \"msgType\":\"POST_TELEMETRY_REQUEST\",\n \"isError\":\"false\",\n \"errorStr\":\"Error Message\"\n}\n```\n\n * 'msgDirectionType' - string value representing msg direction type (incoming to entity or outcoming from entity);\n * 'dataSearch' - the case insensitive 'contains' filter based on data (key and value) for the message;\n * 'metadataSearch' - the case insensitive 'contains' filter based on metadata (key and value) for the message;\n * 'entityName' - string value representing the entity type;\n * 'relationType' - string value representing the type of message routing;\n * 'entityId' - string value representing the entity id in the event body (originator of the message);\n * 'msgType' - string value representing the message type;\n * 'isError' - boolean value to filter the errors.\n\n## Debug Calculated Field Event Filter\n\n```json\n{\n \"eventType\":\"DEBUG_CALCULATED_FIELD\",\n \"server\":\"ip-172-31-24-152\",\n \"isError\":\"false\",\n \"errorStr\":\"Error Message\"\n \"entityId\":\"cf4b8741-f618-471f-ae08-d881ca7f9fe9\",\n \"msgId\":\"5cf7d3a0-aee7-40dd-a737-ade05528e7eb\",\n \"msgType\":\"POST_TELEMETRY_REQUEST\",\n \"arguments\":\"{\n \"x\": {\n \"ts\": 1739432016629,\n \"value\": 20\n },\n \"y\": {\n \"ts\": 1739429717656,\n \"value\": 12\n }\n }\",\n \"result\":\"{\n \"x + y\": 32\n }\",\n}\n```\n\n * 'entityId' - string value representing the entity id in the event body;\n * 'entityType' - string value representing the entity type;\n * 'msgId' - string value representing the message id in the rule engine;\n * 'msgType' - string value representing the message type;\n * 'arguments' - string value representing the arguments that were used in the calculation performed;\n * 'result' - string value representing the result of a calculation;\n * 'isError' - boolean value to filter the errors.\n\n", - "operationId": "getEventsByFilter", - "parameters": [ - { - "name": "entityType", - "in": "path", - "description": "A string value representing the entity type. For example, 'DEVICE'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "entityId", - "in": "path", - "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "tenantId", - "in": "query", - "description": "A string value representing the tenant id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The value is not used in searching.", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ts", - "id" - ] - } - }, - { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] - } - }, - { - "name": "startTime", - "in": "query", - "description": "Timestamp. Events with creation time before it won't be queried.", - "required": false, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "endTime", - "in": "query", - "description": "Timestamp. Events with creation time after it won't be queried.", - "required": false, - "schema": { - "type": "integer", - "format": "int64" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EventFilter" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PageDataEventInfo" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-400": { - "summary": "Bad Request", - "value": { - "status": 400, - "message": "Invalid request body", - "errorCode": 31, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-401": { - "summary": "Unauthorized", - "value": { - "status": 401, - "message": "Authentication failed", - "errorCode": 10, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-403": { - "summary": "Forbidden", - "value": { - "status": 403, - "message": "You don't have permission to perform this operation!", - "errorCode": 20, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-404": { - "summary": "Not Found", - "value": { - "status": 404, - "message": "Requested item wasn't found!", - "errorCode": 32, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "429": { - "description": "Too Many Requests", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-429": { - "summary": "Too Many Requests", - "value": { - "status": 429, - "message": "Too many requests for current tenant!", - "errorCode": 33, - "timestamp": 1609459200000 - } - } - } - } - } - } - }, - "security": [ - { - "HttpLoginForm": [] - }, - { - "ApiKeyForm": [] - } - ] - } - }, - "/api/events/{entityType}/{entityId}/clear": { - "post": { - "tags": [ - "event-controller" - ], - "summary": "Clear Events (clearEvents)", - "description": "Clears events by filter for specified entity.", - "operationId": "clearEvents", - "parameters": [ - { - "name": "entityType", - "in": "path", - "description": "A string value representing the entity type. For example, 'DEVICE'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "entityId", - "in": "path", - "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "startTime", - "in": "query", - "description": "Timestamp. Events with creation time before it won't be queried.", - "required": false, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "endTime", - "in": "query", - "description": "Timestamp. Events with creation time after it won't be queried.", - "required": false, - "schema": { - "type": "integer", - "format": "int64" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EventFilter" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-400": { - "summary": "Bad Request", - "value": { - "status": 400, - "message": "Invalid request body", - "errorCode": 31, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-401": { - "summary": "Unauthorized", - "value": { - "status": 401, - "message": "Authentication failed", - "errorCode": 10, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-403": { - "summary": "Forbidden", - "value": { - "status": 403, - "message": "You don't have permission to perform this operation!", - "errorCode": 20, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-404": { - "summary": "Not Found", - "value": { - "status": 404, - "message": "Requested item wasn't found!", - "errorCode": 32, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "429": { - "description": "Too Many Requests", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-429": { - "summary": "Too Many Requests", - "value": { - "status": 429, - "message": "Too many requests for current tenant!", - "errorCode": 33, - "timestamp": 1609459200000 - } - } - } - } - } - } - }, - "security": [ - { - "HttpLoginForm": [] - }, - { - "ApiKeyForm": [] - } - ] - } - }, - "/api/events/{entityType}/{entityId}/{eventType}": { - "get": { - "tags": [ - "event-controller" - ], - "summary": "Get Events by type (getEventsByType)", - "description": "Returns a page of events for specified entity by specifying event type. You can specify parameters to filter the results. The result is wrapped with PageData object that allows you to iterate over result set using pagination. See response schema for more details. ", - "operationId": "getEventsByType", - "parameters": [ - { - "name": "entityType", - "in": "path", - "description": "A string value representing the entity type. For example, 'DEVICE'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "entityId", - "in": "path", - "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "eventType", - "in": "path", - "description": "A string value representing event type", - "required": true, - "schema": { - "type": "string" - }, - "example": "STATS" - }, - { - "name": "tenantId", - "in": "query", - "description": "A string value representing the tenant id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The value is not used in searching.", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ts", - "id" - ] - } - }, - { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] - } - }, - { - "name": "startTime", - "in": "query", - "description": "Timestamp. Events with creation time before it won't be queried.", - "required": false, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "endTime", - "in": "query", - "description": "Timestamp. Events with creation time after it won't be queried.", - "required": false, - "schema": { - "type": "integer", - "format": "int64" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PageDataEventInfo" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-400": { - "summary": "Bad Request", - "value": { - "status": 400, - "message": "Invalid UUID string: 123", - "errorCode": 31, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-401": { - "summary": "Unauthorized", - "value": { - "status": 401, - "message": "Authentication failed", - "errorCode": 10, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-403": { - "summary": "Forbidden", - "value": { - "status": 403, - "message": "You don't have permission to perform this operation!", - "errorCode": 20, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-404": { - "summary": "Not Found", - "value": { - "status": 404, - "message": "Requested item wasn't found!", - "errorCode": 32, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "429": { - "description": "Too Many Requests", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-429": { - "summary": "Too Many Requests", - "value": { - "status": 429, - "message": "Too many requests for current tenant!", - "errorCode": 33, - "timestamp": 1609459200000 - } - } - } - } - } - } - }, - "security": [ - { - "HttpLoginForm": [] - }, - { - "ApiKeyForm": [] - } - ] - } - }, - "/api/image": { - "post": { - "tags": [ - "image-controller" - ], - "summary": "uploadImage", - "operationId": "uploadImage", - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "file": { - "type": "string", - "format": "binary" - }, - "title": { - "type": "string" - }, - "imageSubType": { - "type": "string" - } - }, - "required": [ - "file" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TbResourceInfo" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-400": { - "summary": "Bad Request", - "value": { - "status": 400, - "message": "Invalid request body", - "errorCode": 31, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-401": { - "summary": "Unauthorized", - "value": { - "status": 401, - "message": "Authentication failed", - "errorCode": 10, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-403": { - "summary": "Forbidden", - "value": { - "status": 403, - "message": "You don't have permission to perform this operation!", - "errorCode": 20, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-404": { - "summary": "Not Found", - "value": { - "status": 404, - "message": "Requested item wasn't found!", - "errorCode": 32, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "429": { - "description": "Too Many Requests", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-429": { - "summary": "Too Many Requests", - "value": { - "status": 429, - "message": "Too many requests for current tenant!", - "errorCode": 33, - "timestamp": 1609459200000 - } - } - } - } - } - } - }, - "security": [ - { - "HttpLoginForm": [] - }, - { - "ApiKeyForm": [] - } - ] - } - }, - "/api/image/import": { - "put": { - "tags": [ - "image-controller" - ], - "summary": "importImage", - "operationId": "importImage", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ResourceExportData" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TbResourceInfo" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-400": { - "summary": "Bad Request", - "value": { - "status": 400, - "message": "Invalid UUID string: 123", - "errorCode": 31, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-401": { - "summary": "Unauthorized", - "value": { - "status": 401, - "message": "Authentication failed", - "errorCode": 10, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-403": { - "summary": "Forbidden", - "value": { - "status": 403, - "message": "You don't have permission to perform this operation!", - "errorCode": 20, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-404": { - "summary": "Not Found", - "value": { - "status": 404, - "message": "Requested item wasn't found!", - "errorCode": 32, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "429": { - "description": "Too Many Requests", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-429": { - "summary": "Too Many Requests", - "value": { - "status": 429, - "message": "Too many requests for current tenant!", - "errorCode": 33, - "timestamp": 1609459200000 - } - } - } - } - } - } - }, - "security": [ - { - "HttpLoginForm": [] - }, - { - "ApiKeyForm": [] - } - ] - } - }, - "/api/images": { - "get": { - "tags": [ - "image-controller" - ], - "summary": "getImages", - "operationId": "getImages", - "parameters": [ - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "imageSubType", - "in": "query", - "description": "A string value representing resource sub-type.", - "required": false, - "schema": { - "type": "string", - "enum": [ - "IMAGE", - "SCADA_SYMBOL" - ] - } - }, - { - "name": "includeSystemImages", - "in": "query", - "description": "Use 'true' to include system images. Disabled by default. Ignored for requests by users with system administrator authority.", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'substring' filter based on the resource title.", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string", - "enum": [ - "createdTime", - "title", - "resourceType", - "tenantId" - ] - } - }, - { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PageDataTbResourceInfo" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-400": { - "summary": "Bad Request", - "value": { - "status": 400, - "message": "Invalid UUID string: 123", - "errorCode": 31, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-401": { - "summary": "Unauthorized", - "value": { - "status": 401, - "message": "Authentication failed", - "errorCode": 10, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-403": { - "summary": "Forbidden", - "value": { - "status": 403, - "message": "You don't have permission to perform this operation!", - "errorCode": 20, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-404": { - "summary": "Not Found", - "value": { - "status": 404, - "message": "Requested item wasn't found!", - "errorCode": 32, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "429": { - "description": "Too Many Requests", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-429": { - "summary": "Too Many Requests", - "value": { - "status": 429, - "message": "Too many requests for current tenant!", - "errorCode": 33, - "timestamp": 1609459200000 - } - } - } - } - } - } - }, - "security": [ - { - "HttpLoginForm": [] - }, - { - "ApiKeyForm": [] - } - ] - } - }, - "/api/images/public/{publicResourceKey}": { - "get": { - "tags": [ - "image-controller" - ], - "summary": "downloadPublicImage", - "operationId": "downloadPublicImage", - "parameters": [ - { - "name": "publicResourceKey", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "If-None-Match", - "in": "header", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "Accept-Encoding", - "in": "header", - "required": false, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "image/*": { - "schema": { - "type": "string", - "format": "binary" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-400": { - "summary": "Bad Request", - "value": { - "status": 400, - "message": "Invalid UUID string: 123", - "errorCode": 31, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-401": { - "summary": "Unauthorized", - "value": { - "status": 401, - "message": "Authentication failed", - "errorCode": 10, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-403": { - "summary": "Forbidden", - "value": { - "status": 403, - "message": "You don't have permission to perform this operation!", - "errorCode": 20, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-404": { - "summary": "Not Found", - "value": { - "status": 404, - "message": "Requested item wasn't found!", - "errorCode": 32, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "429": { - "description": "Too Many Requests", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-429": { - "summary": "Too Many Requests", - "value": { - "status": 429, - "message": "Too many requests for current tenant!", - "errorCode": 33, - "timestamp": 1609459200000 - } - } - } - } - } - } - }, - "security": [ - { - "HttpLoginForm": [] - }, - { - "ApiKeyForm": [] - } - ] - } - }, - "/api/images/{type}/{key}": { - "get": { - "tags": [ - "image-controller" - ], - "summary": "downloadImage", - "operationId": "downloadImage", - "parameters": [ - { - "name": "type", - "in": "path", - "description": "Type of the image: tenant or system", - "required": true, - "schema": { - "type": "string", - "enum": [ - "tenant", - "system" - ] - } - }, - { - "name": "key", - "in": "path", - "description": "Image resource key, for example thermostats_dashboard_background.jpeg", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "If-None-Match", - "in": "header", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "Accept-Encoding", - "in": "header", - "required": false, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "image/*": { - "schema": { - "type": "string", - "format": "binary" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-400": { - "summary": "Bad Request", - "value": { - "status": 400, - "message": "Invalid UUID string: 123", - "errorCode": 31, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-401": { - "summary": "Unauthorized", - "value": { - "status": 401, - "message": "Authentication failed", - "errorCode": 10, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-403": { - "summary": "Forbidden", - "value": { - "status": 403, - "message": "You don't have permission to perform this operation!", - "errorCode": 20, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-404": { - "summary": "Not Found", - "value": { - "status": 404, - "message": "Requested item wasn't found!", - "errorCode": 32, - "timestamp": 1609459200000 - } - } - } - } - } - }, - "429": { - "description": "Too Many Requests", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThingsboardErrorResponse" - }, - "examples": { - "error-code-429": { - "summary": "Too Many Requests", - "value": { - "status": 429, - "message": "Too many requests for current tenant!", - "errorCode": 33, - "timestamp": 1609459200000 - } - } - } - } - } - } - }, - "security": [ - { - "HttpLoginForm": [] - }, - { - "ApiKeyForm": [] - } - ] - }, - "put": { - "tags": [ - "image-controller" - ], - "summary": "updateImage", - "operationId": "updateImage", - "parameters": [ - { - "name": "type", - "in": "path", - "description": "Type of the image: tenant or system", - "required": true, - "schema": { - "type": "string", - "enum": [ - "tenant", - "system" - ] - } - }, - { - "name": "key", - "in": "path", - "description": "Image resource key, for example thermostats_dashboard_background.jpeg", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "file": { - "type": "string", - "format": "binary" - } - }, - "required": [ - "file" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TbResourceInfo" + "$ref": "#/components/schemas/TbResourceInfo" } } } @@ -46953,9 +45256,7 @@ "application/json": { "schema": { "properties": { - "refreshToken": { - - } + "refreshToken": {} } } } @@ -47145,9 +45446,7 @@ "application/json": { "schema": { "type": "object", - "additionalProperties": { - - } + "additionalProperties": {} } } }, @@ -90586,9 +88885,7 @@ "HasIdObject": { "type": "object", "properties": { - "id": { - - } + "id": {} } }, "HomeDashboardInfo": { @@ -90798,9 +89095,7 @@ }, "JsonNode": { "description": "A value representing the any type (object or primitive)", - "example": { - - } + "example": {} }, "JsonTransportPayloadConfiguration": { "allOf": [ @@ -91421,9 +89716,7 @@ "firstName": { "type": "string" }, - "id": { - - }, + "id": {}, "lastName": { "type": "string" }, @@ -93578,7 +91871,7 @@ "version": { "type": "string", "description": "OTA Package version.", - "example": 1 + "example": 1.0 }, "tag": { "type": "string", @@ -93697,7 +91990,7 @@ "version": { "type": "string", "description": "OTA Package version.", - "example": 1 + "example": 1.0 }, "tag": { "type": "string", @@ -93840,9 +92133,7 @@ "type" ] }, - "OutputStrategy": { - - }, + "OutputStrategy": {}, "PSKLwM2MBootstrapServerCredential": { "allOf": [ { @@ -97073,7 +95364,7 @@ "version": { "type": "string", "description": "OTA Package version.", - "example": 1 + "example": 1.0 }, "tag": { "type": "string", @@ -97996,9 +96287,7 @@ } } }, - "SystemLevelUsersFilter": { - - }, + "SystemLevelUsersFilter": {}, "TaskProcessingFailureNotificationRuleTriggerConfig": { "allOf": [ { @@ -98892,7 +97181,23 @@ }, "ThingsboardErrorCode": { "description": "Platform error code", - "enum": [2, 10, 11, 15, 20, 30, 31, 32, 33, 34, 35, 40, 41, 45, 46] + "enum": [ + 2, + 10, + 11, + 15, + 20, + 30, + 31, + 32, + 33, + 34, + 35, + 40, + 41, + 45, + 46 + ] }, "ThingsboardErrorResponse": { "properties": { @@ -99686,9 +97991,7 @@ "type" ] }, - "Version": { - - }, + "Version": {}, "VersionCreateConfig": { "type": "object", "properties": { @@ -100443,10 +98746,10 @@ }, "ApiKeyForm": { "type": "apiKey", - "description": "Enter the API key value with 'ApiKey' prefix in format: **ApiKey \u003Cyour_api_key_value\u003E**\n\nExample: **ApiKey tb_5te51SkLRYpjGrujUGwqkjFvooWBlQpVe2An2Dr3w13wjfxDW**\n\n\u003Cbr\u003E**NOTE**: Use only ONE authentication method at a time. If both are authorized, JWT auth takes the priority.\u003Cbr\u003E\n", + "description": "Enter the API key value with 'ApiKey' prefix in format: **ApiKey **\n\nExample: **ApiKey tb_5te51SkLRYpjGrujUGwqkjFvooWBlQpVe2An2Dr3w13wjfxDW**\n\n
**NOTE**: Use only ONE authentication method at a time. If both are authorized, JWT auth takes the priority.
\n", "name": "X-Authorization", "in": "header" } } } -} \ No newline at end of file +} diff --git a/ce/src/main/java/org/thingsboard/client/api/ThingsboardApi.java b/ce/src/main/java/org/thingsboard/client/api/ThingsboardApi.java index 5a0c3157..fcb202c2 100644 --- a/ce/src/main/java/org/thingsboard/client/api/ThingsboardApi.java +++ b/ce/src/main/java/org/thingsboard/client/api/ThingsboardApi.java @@ -25174,157 +25174,6 @@ private HttpRequest.Builder getDefaultTenantProfileInfoRequestBuilder(Map headers) throws ApiException { - ApiResponse localVarResponse = getDeviceAttributesWithHttpInfo(deviceToken, clientKeys, sharedKeys, headers); - return localVarResponse.getData(); - } - - /** - * Get attributes (getDeviceAttributes) - * Returns all attributes that belong to device. Use optional 'clientKeys' and/or 'sharedKeys' parameter to return specific attributes. Example of the result: ```json { \"stringKey\":\"value1\", \"booleanKey\":true, \"doubleKey\":42.0, \"longKey\":73, \"jsonKey\": { \"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"} } } ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param clientKeys Comma separated key names for attribute with client scope (required) - * @param sharedKeys Comma separated key names for attribute with shared scope (required) - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse getDeviceAttributesWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String clientKeys, @javax.annotation.Nonnull String sharedKeys) throws ApiException { - return getDeviceAttributesWithHttpInfo(deviceToken, clientKeys, sharedKeys, null); - } - - /** - * Get attributes (getDeviceAttributes) - * Returns all attributes that belong to device. Use optional 'clientKeys' and/or 'sharedKeys' parameter to return specific attributes. Example of the result: ```json { \"stringKey\":\"value1\", \"booleanKey\":true, \"doubleKey\":42.0, \"longKey\":73, \"jsonKey\": { \"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"} } } ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param clientKeys Comma separated key names for attribute with client scope (required) - * @param sharedKeys Comma separated key names for attribute with shared scope (required) - * @param headers Optional headers to include in the request - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse getDeviceAttributesWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String clientKeys, @javax.annotation.Nonnull String sharedKeys, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = getDeviceAttributesRequestBuilder(deviceToken, clientKeys, sharedKeys, headers); - try { - HttpResponse localVarResponse = memberVarHttpClient.send( - localVarRequestBuilder.build(), - HttpResponse.BodyHandlers.ofInputStream()); - if (memberVarResponseInterceptor != null) { - memberVarResponseInterceptor.accept(localVarResponse); - } - InputStream localVarResponseBody = null; - try { - if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("getDeviceAttributes", localVarResponse); - } - localVarResponseBody = ApiClient.getResponseBody(localVarResponse); - if (localVarResponseBody == null) { - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - null - ); - } - - - - String responseBody = new String(localVarResponseBody.readAllBytes()); - String responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); - - - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - responseValue - ); - } finally { - if (localVarResponseBody != null) { - localVarResponseBody.close(); - } - } - } catch (IOException e) { - throw new ApiException(e); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new ApiException(e); - } - } - - private HttpRequest.Builder getDeviceAttributesRequestBuilder(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String clientKeys, @javax.annotation.Nonnull String sharedKeys, Map headers) throws ApiException { - // verify the required parameter 'deviceToken' is set - if (deviceToken == null) { - throw new ApiException(400, "Missing the required parameter 'deviceToken' when calling getDeviceAttributes"); - } - // verify the required parameter 'clientKeys' is set - if (clientKeys == null) { - throw new ApiException(400, "Missing the required parameter 'clientKeys' when calling getDeviceAttributes"); - } - // verify the required parameter 'sharedKeys' is set - if (sharedKeys == null) { - throw new ApiException(400, "Missing the required parameter 'sharedKeys' when calling getDeviceAttributes"); - } - - HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - - String localVarPath = "/api/v1/{deviceToken}/attributes" - .replace("{deviceToken}", ApiClient.urlEncode(deviceToken.toString())); - - List localVarQueryParams = new ArrayList<>(); - StringJoiner localVarQueryStringJoiner = new StringJoiner("&"); - String localVarQueryParameterBaseName; - localVarQueryParameterBaseName = "clientKeys"; - localVarQueryParams.addAll(ApiClient.parameterToPairs("clientKeys", clientKeys)); - localVarQueryParameterBaseName = "sharedKeys"; - localVarQueryParams.addAll(ApiClient.parameterToPairs("sharedKeys", sharedKeys)); - - if (!localVarQueryParams.isEmpty() || localVarQueryStringJoiner.length() != 0) { - StringJoiner queryJoiner = new StringJoiner("&"); - localVarQueryParams.forEach(p -> queryJoiner.add(p.getName() + '=' + p.getValue())); - if (localVarQueryStringJoiner.length() != 0) { - queryJoiner.add(localVarQueryStringJoiner.toString()); - } - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath + '?' + queryJoiner.toString())); - } else { - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); - } - - localVarRequestBuilder.header("Accept", "application/json"); - - localVarRequestBuilder.method("GET", HttpRequest.BodyPublishers.noBody()); - if (memberVarReadTimeout != null) { - localVarRequestBuilder.timeout(memberVarReadTimeout); - } - // Add custom headers if provided - localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); - if (memberVarInterceptor != null) { - memberVarInterceptor.accept(localVarRequestBuilder); - } - return localVarRequestBuilder; - } - /** * Get Device (getDeviceById) * Fetch the Device object based on the provided Device Id. If the user has the authority of 'TENANT_ADMIN', the server checks that the device is owned by the same tenant. If the user has the authority of 'CUSTOMER_USER', the server checks that the device is assigned to the same customer. Available for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. @@ -30370,169 +30219,6 @@ private HttpRequest.Builder getFeaturesInfoRequestBuilder(Map he return localVarRequestBuilder; } - /** - * Get Device Firmware (getFirmware) - * Downloads the current firmware package.When the platform initiates firmware update, it informs the device by updating the 'fw_title', 'fw_version', 'fw_checksum' and 'fw_checksum_algorithm' shared attributes.The 'fw_title' and 'fw_version' parameters must be supplied in this request to double-check that the firmware that device is downloading matches the firmware it expects to download. This is important, since the administrator may change the firmware assignment while device is downloading the firmware. Optional 'chunk' and 'size' parameters may be used to download the firmware in chunks. For example, device may request first 16 KB of firmware using 'chunk'=0 and 'size'=16384. Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param title Title of the firmware, corresponds to the value of 'fw_title' attribute. (required) - * @param version Version of the firmware, corresponds to the value of 'fw_version' attribute. (required) - * @param size Size of the chunk. Optional. Omit to download the entire file without chunks. (optional, default to 0) - * @param chunk Index of the chunk. Optional. Omit to download the entire file without chunks. (optional, default to 0) - * @return String - * @throws ApiException if fails to make API call - */ - public String getFirmware(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String title, @javax.annotation.Nonnull String version, @javax.annotation.Nullable Integer size, @javax.annotation.Nullable Integer chunk) throws ApiException { - return getFirmware(deviceToken, title, version, size, chunk, null); - } - - /** - * Get Device Firmware (getFirmware) - * Downloads the current firmware package.When the platform initiates firmware update, it informs the device by updating the 'fw_title', 'fw_version', 'fw_checksum' and 'fw_checksum_algorithm' shared attributes.The 'fw_title' and 'fw_version' parameters must be supplied in this request to double-check that the firmware that device is downloading matches the firmware it expects to download. This is important, since the administrator may change the firmware assignment while device is downloading the firmware. Optional 'chunk' and 'size' parameters may be used to download the firmware in chunks. For example, device may request first 16 KB of firmware using 'chunk'=0 and 'size'=16384. Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param title Title of the firmware, corresponds to the value of 'fw_title' attribute. (required) - * @param version Version of the firmware, corresponds to the value of 'fw_version' attribute. (required) - * @param size Size of the chunk. Optional. Omit to download the entire file without chunks. (optional, default to 0) - * @param chunk Index of the chunk. Optional. Omit to download the entire file without chunks. (optional, default to 0) - * @param headers Optional headers to include in the request - * @return String - * @throws ApiException if fails to make API call - */ - public String getFirmware(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String title, @javax.annotation.Nonnull String version, @javax.annotation.Nullable Integer size, @javax.annotation.Nullable Integer chunk, Map headers) throws ApiException { - ApiResponse localVarResponse = getFirmwareWithHttpInfo(deviceToken, title, version, size, chunk, headers); - return localVarResponse.getData(); - } - - /** - * Get Device Firmware (getFirmware) - * Downloads the current firmware package.When the platform initiates firmware update, it informs the device by updating the 'fw_title', 'fw_version', 'fw_checksum' and 'fw_checksum_algorithm' shared attributes.The 'fw_title' and 'fw_version' parameters must be supplied in this request to double-check that the firmware that device is downloading matches the firmware it expects to download. This is important, since the administrator may change the firmware assignment while device is downloading the firmware. Optional 'chunk' and 'size' parameters may be used to download the firmware in chunks. For example, device may request first 16 KB of firmware using 'chunk'=0 and 'size'=16384. Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param title Title of the firmware, corresponds to the value of 'fw_title' attribute. (required) - * @param version Version of the firmware, corresponds to the value of 'fw_version' attribute. (required) - * @param size Size of the chunk. Optional. Omit to download the entire file without chunks. (optional, default to 0) - * @param chunk Index of the chunk. Optional. Omit to download the entire file without chunks. (optional, default to 0) - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse getFirmwareWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String title, @javax.annotation.Nonnull String version, @javax.annotation.Nullable Integer size, @javax.annotation.Nullable Integer chunk) throws ApiException { - return getFirmwareWithHttpInfo(deviceToken, title, version, size, chunk, null); - } - - /** - * Get Device Firmware (getFirmware) - * Downloads the current firmware package.When the platform initiates firmware update, it informs the device by updating the 'fw_title', 'fw_version', 'fw_checksum' and 'fw_checksum_algorithm' shared attributes.The 'fw_title' and 'fw_version' parameters must be supplied in this request to double-check that the firmware that device is downloading matches the firmware it expects to download. This is important, since the administrator may change the firmware assignment while device is downloading the firmware. Optional 'chunk' and 'size' parameters may be used to download the firmware in chunks. For example, device may request first 16 KB of firmware using 'chunk'=0 and 'size'=16384. Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param title Title of the firmware, corresponds to the value of 'fw_title' attribute. (required) - * @param version Version of the firmware, corresponds to the value of 'fw_version' attribute. (required) - * @param size Size of the chunk. Optional. Omit to download the entire file without chunks. (optional, default to 0) - * @param chunk Index of the chunk. Optional. Omit to download the entire file without chunks. (optional, default to 0) - * @param headers Optional headers to include in the request - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse getFirmwareWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String title, @javax.annotation.Nonnull String version, @javax.annotation.Nullable Integer size, @javax.annotation.Nullable Integer chunk, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = getFirmwareRequestBuilder(deviceToken, title, version, size, chunk, headers); - try { - HttpResponse localVarResponse = memberVarHttpClient.send( - localVarRequestBuilder.build(), - HttpResponse.BodyHandlers.ofInputStream()); - if (memberVarResponseInterceptor != null) { - memberVarResponseInterceptor.accept(localVarResponse); - } - InputStream localVarResponseBody = null; - try { - if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("getFirmware", localVarResponse); - } - localVarResponseBody = ApiClient.getResponseBody(localVarResponse); - if (localVarResponseBody == null) { - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - null - ); - } - - - - String responseBody = new String(localVarResponseBody.readAllBytes()); - String responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); - - - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - responseValue - ); - } finally { - if (localVarResponseBody != null) { - localVarResponseBody.close(); - } - } - } catch (IOException e) { - throw new ApiException(e); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new ApiException(e); - } - } - - private HttpRequest.Builder getFirmwareRequestBuilder(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String title, @javax.annotation.Nonnull String version, @javax.annotation.Nullable Integer size, @javax.annotation.Nullable Integer chunk, Map headers) throws ApiException { - // verify the required parameter 'deviceToken' is set - if (deviceToken == null) { - throw new ApiException(400, "Missing the required parameter 'deviceToken' when calling getFirmware"); - } - // verify the required parameter 'title' is set - if (title == null) { - throw new ApiException(400, "Missing the required parameter 'title' when calling getFirmware"); - } - // verify the required parameter 'version' is set - if (version == null) { - throw new ApiException(400, "Missing the required parameter 'version' when calling getFirmware"); - } - - HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - - String localVarPath = "/api/v1/{deviceToken}/firmware" - .replace("{deviceToken}", ApiClient.urlEncode(deviceToken.toString())); - - List localVarQueryParams = new ArrayList<>(); - StringJoiner localVarQueryStringJoiner = new StringJoiner("&"); - String localVarQueryParameterBaseName; - localVarQueryParameterBaseName = "title"; - localVarQueryParams.addAll(ApiClient.parameterToPairs("title", title)); - localVarQueryParameterBaseName = "version"; - localVarQueryParams.addAll(ApiClient.parameterToPairs("version", version)); - localVarQueryParameterBaseName = "size"; - localVarQueryParams.addAll(ApiClient.parameterToPairs("size", size)); - localVarQueryParameterBaseName = "chunk"; - localVarQueryParams.addAll(ApiClient.parameterToPairs("chunk", chunk)); - - if (!localVarQueryParams.isEmpty() || localVarQueryStringJoiner.length() != 0) { - StringJoiner queryJoiner = new StringJoiner("&"); - localVarQueryParams.forEach(p -> queryJoiner.add(p.getName() + '=' + p.getValue())); - if (localVarQueryStringJoiner.length() != 0) { - queryJoiner.add(localVarQueryStringJoiner.toString()); - } - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath + '?' + queryJoiner.toString())); - } else { - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); - } - - localVarRequestBuilder.header("Accept", "application/json"); - - localVarRequestBuilder.method("GET", HttpRequest.BodyPublishers.noBody()); - if (memberVarReadTimeout != null) { - localVarRequestBuilder.timeout(memberVarReadTimeout); - } - // Add custom headers if provided - localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); - if (memberVarInterceptor != null) { - memberVarInterceptor.accept(localVarRequestBuilder); - } - return localVarRequestBuilder; - } - /** * Get user settings (getGeneralUserSettings) * Fetch the User settings based on authorized user. @@ -39790,169 +39476,6 @@ private HttpRequest.Builder getShortCustomerInfoByIdRequestBuilder(@javax.annota return localVarRequestBuilder; } - /** - * Get Device Software (getSoftware) - * Downloads the current software package.When the platform initiates software update, it informs the device by updating the 'sw_title', 'sw_version', 'sw_checksum' and 'sw_checksum_algorithm' shared attributes.The 'sw_title' and 'sw_version' parameters must be supplied in this request to double-check that the software that device is downloading matches the software it expects to download. This is important, since the administrator may change the software assignment while device is downloading the software. Optional 'chunk' and 'size' parameters may be used to download the software in chunks. For example, device may request first 16 KB of software using 'chunk'=0 and 'size'=16384. Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param title Title of the software, corresponds to the value of 'sw_title' attribute. (required) - * @param version Version of the software, corresponds to the value of 'sw_version' attribute. (required) - * @param size Size of the chunk. Optional. Omit to download the entire file without using chunks. (optional, default to 0) - * @param chunk Index of the chunk. Optional. Omit to download the entire file without using chunks. (optional, default to 0) - * @return String - * @throws ApiException if fails to make API call - */ - public String getSoftware(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String title, @javax.annotation.Nonnull String version, @javax.annotation.Nullable Integer size, @javax.annotation.Nullable Integer chunk) throws ApiException { - return getSoftware(deviceToken, title, version, size, chunk, null); - } - - /** - * Get Device Software (getSoftware) - * Downloads the current software package.When the platform initiates software update, it informs the device by updating the 'sw_title', 'sw_version', 'sw_checksum' and 'sw_checksum_algorithm' shared attributes.The 'sw_title' and 'sw_version' parameters must be supplied in this request to double-check that the software that device is downloading matches the software it expects to download. This is important, since the administrator may change the software assignment while device is downloading the software. Optional 'chunk' and 'size' parameters may be used to download the software in chunks. For example, device may request first 16 KB of software using 'chunk'=0 and 'size'=16384. Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param title Title of the software, corresponds to the value of 'sw_title' attribute. (required) - * @param version Version of the software, corresponds to the value of 'sw_version' attribute. (required) - * @param size Size of the chunk. Optional. Omit to download the entire file without using chunks. (optional, default to 0) - * @param chunk Index of the chunk. Optional. Omit to download the entire file without using chunks. (optional, default to 0) - * @param headers Optional headers to include in the request - * @return String - * @throws ApiException if fails to make API call - */ - public String getSoftware(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String title, @javax.annotation.Nonnull String version, @javax.annotation.Nullable Integer size, @javax.annotation.Nullable Integer chunk, Map headers) throws ApiException { - ApiResponse localVarResponse = getSoftwareWithHttpInfo(deviceToken, title, version, size, chunk, headers); - return localVarResponse.getData(); - } - - /** - * Get Device Software (getSoftware) - * Downloads the current software package.When the platform initiates software update, it informs the device by updating the 'sw_title', 'sw_version', 'sw_checksum' and 'sw_checksum_algorithm' shared attributes.The 'sw_title' and 'sw_version' parameters must be supplied in this request to double-check that the software that device is downloading matches the software it expects to download. This is important, since the administrator may change the software assignment while device is downloading the software. Optional 'chunk' and 'size' parameters may be used to download the software in chunks. For example, device may request first 16 KB of software using 'chunk'=0 and 'size'=16384. Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param title Title of the software, corresponds to the value of 'sw_title' attribute. (required) - * @param version Version of the software, corresponds to the value of 'sw_version' attribute. (required) - * @param size Size of the chunk. Optional. Omit to download the entire file without using chunks. (optional, default to 0) - * @param chunk Index of the chunk. Optional. Omit to download the entire file without using chunks. (optional, default to 0) - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse getSoftwareWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String title, @javax.annotation.Nonnull String version, @javax.annotation.Nullable Integer size, @javax.annotation.Nullable Integer chunk) throws ApiException { - return getSoftwareWithHttpInfo(deviceToken, title, version, size, chunk, null); - } - - /** - * Get Device Software (getSoftware) - * Downloads the current software package.When the platform initiates software update, it informs the device by updating the 'sw_title', 'sw_version', 'sw_checksum' and 'sw_checksum_algorithm' shared attributes.The 'sw_title' and 'sw_version' parameters must be supplied in this request to double-check that the software that device is downloading matches the software it expects to download. This is important, since the administrator may change the software assignment while device is downloading the software. Optional 'chunk' and 'size' parameters may be used to download the software in chunks. For example, device may request first 16 KB of software using 'chunk'=0 and 'size'=16384. Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param title Title of the software, corresponds to the value of 'sw_title' attribute. (required) - * @param version Version of the software, corresponds to the value of 'sw_version' attribute. (required) - * @param size Size of the chunk. Optional. Omit to download the entire file without using chunks. (optional, default to 0) - * @param chunk Index of the chunk. Optional. Omit to download the entire file without using chunks. (optional, default to 0) - * @param headers Optional headers to include in the request - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse getSoftwareWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String title, @javax.annotation.Nonnull String version, @javax.annotation.Nullable Integer size, @javax.annotation.Nullable Integer chunk, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = getSoftwareRequestBuilder(deviceToken, title, version, size, chunk, headers); - try { - HttpResponse localVarResponse = memberVarHttpClient.send( - localVarRequestBuilder.build(), - HttpResponse.BodyHandlers.ofInputStream()); - if (memberVarResponseInterceptor != null) { - memberVarResponseInterceptor.accept(localVarResponse); - } - InputStream localVarResponseBody = null; - try { - if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("getSoftware", localVarResponse); - } - localVarResponseBody = ApiClient.getResponseBody(localVarResponse); - if (localVarResponseBody == null) { - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - null - ); - } - - - - String responseBody = new String(localVarResponseBody.readAllBytes()); - String responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); - - - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - responseValue - ); - } finally { - if (localVarResponseBody != null) { - localVarResponseBody.close(); - } - } - } catch (IOException e) { - throw new ApiException(e); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new ApiException(e); - } - } - - private HttpRequest.Builder getSoftwareRequestBuilder(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String title, @javax.annotation.Nonnull String version, @javax.annotation.Nullable Integer size, @javax.annotation.Nullable Integer chunk, Map headers) throws ApiException { - // verify the required parameter 'deviceToken' is set - if (deviceToken == null) { - throw new ApiException(400, "Missing the required parameter 'deviceToken' when calling getSoftware"); - } - // verify the required parameter 'title' is set - if (title == null) { - throw new ApiException(400, "Missing the required parameter 'title' when calling getSoftware"); - } - // verify the required parameter 'version' is set - if (version == null) { - throw new ApiException(400, "Missing the required parameter 'version' when calling getSoftware"); - } - - HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - - String localVarPath = "/api/v1/{deviceToken}/software" - .replace("{deviceToken}", ApiClient.urlEncode(deviceToken.toString())); - - List localVarQueryParams = new ArrayList<>(); - StringJoiner localVarQueryStringJoiner = new StringJoiner("&"); - String localVarQueryParameterBaseName; - localVarQueryParameterBaseName = "title"; - localVarQueryParams.addAll(ApiClient.parameterToPairs("title", title)); - localVarQueryParameterBaseName = "version"; - localVarQueryParams.addAll(ApiClient.parameterToPairs("version", version)); - localVarQueryParameterBaseName = "size"; - localVarQueryParams.addAll(ApiClient.parameterToPairs("size", size)); - localVarQueryParameterBaseName = "chunk"; - localVarQueryParams.addAll(ApiClient.parameterToPairs("chunk", chunk)); - - if (!localVarQueryParams.isEmpty() || localVarQueryStringJoiner.length() != 0) { - StringJoiner queryJoiner = new StringJoiner("&"); - localVarQueryParams.forEach(p -> queryJoiner.add(p.getName() + '=' + p.getValue())); - if (localVarQueryStringJoiner.length() != 0) { - queryJoiner.add(localVarQueryStringJoiner.toString()); - } - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath + '?' + queryJoiner.toString())); - } else { - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); - } - - localVarRequestBuilder.header("Accept", "application/json"); - - localVarRequestBuilder.method("GET", HttpRequest.BodyPublishers.noBody()); - if (memberVarReadTimeout != null) { - localVarRequestBuilder.timeout(memberVarReadTimeout); - } - // Add custom headers if provided - localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); - if (memberVarInterceptor != null) { - memberVarInterceptor.accept(localVarRequestBuilder); - } - return localVarRequestBuilder; - } - /** * Get system info (getSystemInfo) * Get main information about system. Available for users with 'SYS_ADMIN' authority. @@ -52275,387 +51798,6 @@ private HttpRequest.Builder markNotificationAsReadRequestBuilder(@javax.annotati return localVarRequestBuilder; } - /** - * Post attributes (postDeviceAttributes) - * Post client attribute updates on behalf of device. Example of the request: ```json { \"stringKey\":\"value1\", \"booleanKey\":true, \"doubleKey\":42.0, \"longKey\":73, \"jsonKey\": { \"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"} } } ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param body JSON with attribute key-value pairs. See API call description for example. (required) - * @return String - * @throws ApiException if fails to make API call - */ - public String postDeviceAttributes(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String body) throws ApiException { - return postDeviceAttributes(deviceToken, body, null); - } - - /** - * Post attributes (postDeviceAttributes) - * Post client attribute updates on behalf of device. Example of the request: ```json { \"stringKey\":\"value1\", \"booleanKey\":true, \"doubleKey\":42.0, \"longKey\":73, \"jsonKey\": { \"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"} } } ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param body JSON with attribute key-value pairs. See API call description for example. (required) - * @param headers Optional headers to include in the request - * @return String - * @throws ApiException if fails to make API call - */ - public String postDeviceAttributes(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String body, Map headers) throws ApiException { - ApiResponse localVarResponse = postDeviceAttributesWithHttpInfo(deviceToken, body, headers); - return localVarResponse.getData(); - } - - /** - * Post attributes (postDeviceAttributes) - * Post client attribute updates on behalf of device. Example of the request: ```json { \"stringKey\":\"value1\", \"booleanKey\":true, \"doubleKey\":42.0, \"longKey\":73, \"jsonKey\": { \"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"} } } ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param body JSON with attribute key-value pairs. See API call description for example. (required) - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse postDeviceAttributesWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String body) throws ApiException { - return postDeviceAttributesWithHttpInfo(deviceToken, body, null); - } - - /** - * Post attributes (postDeviceAttributes) - * Post client attribute updates on behalf of device. Example of the request: ```json { \"stringKey\":\"value1\", \"booleanKey\":true, \"doubleKey\":42.0, \"longKey\":73, \"jsonKey\": { \"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"} } } ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param body JSON with attribute key-value pairs. See API call description for example. (required) - * @param headers Optional headers to include in the request - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse postDeviceAttributesWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String body, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = postDeviceAttributesRequestBuilder(deviceToken, body, headers); - try { - HttpResponse localVarResponse = memberVarHttpClient.send( - localVarRequestBuilder.build(), - HttpResponse.BodyHandlers.ofInputStream()); - if (memberVarResponseInterceptor != null) { - memberVarResponseInterceptor.accept(localVarResponse); - } - InputStream localVarResponseBody = null; - try { - if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("postDeviceAttributes", localVarResponse); - } - localVarResponseBody = ApiClient.getResponseBody(localVarResponse); - if (localVarResponseBody == null) { - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - null - ); - } - - - - String responseBody = new String(localVarResponseBody.readAllBytes()); - String responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); - - - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - responseValue - ); - } finally { - if (localVarResponseBody != null) { - localVarResponseBody.close(); - } - } - } catch (IOException e) { - throw new ApiException(e); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new ApiException(e); - } - } - - private HttpRequest.Builder postDeviceAttributesRequestBuilder(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String body, Map headers) throws ApiException { - // verify the required parameter 'deviceToken' is set - if (deviceToken == null) { - throw new ApiException(400, "Missing the required parameter 'deviceToken' when calling postDeviceAttributes"); - } - // verify the required parameter 'body' is set - if (body == null) { - throw new ApiException(400, "Missing the required parameter 'body' when calling postDeviceAttributes"); - } - - HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - - String localVarPath = "/api/v1/{deviceToken}/attributes" - .replace("{deviceToken}", ApiClient.urlEncode(deviceToken.toString())); - - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); - - localVarRequestBuilder.header("Content-Type", "application/json"); - localVarRequestBuilder.header("Accept", "application/json"); - - localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofString(body)); - if (memberVarReadTimeout != null) { - localVarRequestBuilder.timeout(memberVarReadTimeout); - } - // Add custom headers if provided - localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); - if (memberVarInterceptor != null) { - memberVarInterceptor.accept(localVarRequestBuilder); - } - return localVarRequestBuilder; - } - - /** - * Send the RPC command (postRpcRequest) - * Send the RPC request to server. The request payload is a JSON document that contains 'method' and 'params'. For example: ```json {\"method\": \"sumOnServer\", \"params\":{\"a\":2, \"b\":2}} ``` The response contains arbitrary JSON with the RPC reply. For example: ```json {\"result\": 4} ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param body The RPC request JSON (required) - * @return String - * @throws ApiException if fails to make API call - */ - public String postRpcRequest(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String body) throws ApiException { - return postRpcRequest(deviceToken, body, null); - } - - /** - * Send the RPC command (postRpcRequest) - * Send the RPC request to server. The request payload is a JSON document that contains 'method' and 'params'. For example: ```json {\"method\": \"sumOnServer\", \"params\":{\"a\":2, \"b\":2}} ``` The response contains arbitrary JSON with the RPC reply. For example: ```json {\"result\": 4} ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param body The RPC request JSON (required) - * @param headers Optional headers to include in the request - * @return String - * @throws ApiException if fails to make API call - */ - public String postRpcRequest(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String body, Map headers) throws ApiException { - ApiResponse localVarResponse = postRpcRequestWithHttpInfo(deviceToken, body, headers); - return localVarResponse.getData(); - } - - /** - * Send the RPC command (postRpcRequest) - * Send the RPC request to server. The request payload is a JSON document that contains 'method' and 'params'. For example: ```json {\"method\": \"sumOnServer\", \"params\":{\"a\":2, \"b\":2}} ``` The response contains arbitrary JSON with the RPC reply. For example: ```json {\"result\": 4} ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param body The RPC request JSON (required) - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse postRpcRequestWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String body) throws ApiException { - return postRpcRequestWithHttpInfo(deviceToken, body, null); - } - - /** - * Send the RPC command (postRpcRequest) - * Send the RPC request to server. The request payload is a JSON document that contains 'method' and 'params'. For example: ```json {\"method\": \"sumOnServer\", \"params\":{\"a\":2, \"b\":2}} ``` The response contains arbitrary JSON with the RPC reply. For example: ```json {\"result\": 4} ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param body The RPC request JSON (required) - * @param headers Optional headers to include in the request - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse postRpcRequestWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String body, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = postRpcRequestRequestBuilder(deviceToken, body, headers); - try { - HttpResponse localVarResponse = memberVarHttpClient.send( - localVarRequestBuilder.build(), - HttpResponse.BodyHandlers.ofInputStream()); - if (memberVarResponseInterceptor != null) { - memberVarResponseInterceptor.accept(localVarResponse); - } - InputStream localVarResponseBody = null; - try { - if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("postRpcRequest", localVarResponse); - } - localVarResponseBody = ApiClient.getResponseBody(localVarResponse); - if (localVarResponseBody == null) { - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - null - ); - } - - - - String responseBody = new String(localVarResponseBody.readAllBytes()); - String responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); - - - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - responseValue - ); - } finally { - if (localVarResponseBody != null) { - localVarResponseBody.close(); - } - } - } catch (IOException e) { - throw new ApiException(e); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new ApiException(e); - } - } - - private HttpRequest.Builder postRpcRequestRequestBuilder(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String body, Map headers) throws ApiException { - // verify the required parameter 'deviceToken' is set - if (deviceToken == null) { - throw new ApiException(400, "Missing the required parameter 'deviceToken' when calling postRpcRequest"); - } - // verify the required parameter 'body' is set - if (body == null) { - throw new ApiException(400, "Missing the required parameter 'body' when calling postRpcRequest"); - } - - HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - - String localVarPath = "/api/v1/{deviceToken}/rpc" - .replace("{deviceToken}", ApiClient.urlEncode(deviceToken.toString())); - - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); - - localVarRequestBuilder.header("Content-Type", "application/json"); - localVarRequestBuilder.header("Accept", "application/json"); - - localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofString(body)); - if (memberVarReadTimeout != null) { - localVarRequestBuilder.timeout(memberVarReadTimeout); - } - // Add custom headers if provided - localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); - if (memberVarInterceptor != null) { - memberVarInterceptor.accept(localVarRequestBuilder); - } - return localVarRequestBuilder; - } - - /** - * Post time series data (postTelemetry) - * Post time series data on behalf of device. Example of the request: The request payload is a JSON document with three possible formats: Simple format without timestamp. In such a case, current server time will be used: ```json { \"stringKey\":\"value1\", \"booleanKey\":true, \"doubleKey\":42.0, \"longKey\":73, \"jsonKey\": { \"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"} } } ``` Single JSON object with timestamp: ```json {\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}} ``` JSON array with timestamps: ```json [ {\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}}, {\"ts\":1634712588000,\"values\":{\"temperature\":25, \"humidity\":88}} ] ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param body (required) - * @return String - * @throws ApiException if fails to make API call - */ - public String postTelemetry(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String body) throws ApiException { - return postTelemetry(deviceToken, body, null); - } - - /** - * Post time series data (postTelemetry) - * Post time series data on behalf of device. Example of the request: The request payload is a JSON document with three possible formats: Simple format without timestamp. In such a case, current server time will be used: ```json { \"stringKey\":\"value1\", \"booleanKey\":true, \"doubleKey\":42.0, \"longKey\":73, \"jsonKey\": { \"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"} } } ``` Single JSON object with timestamp: ```json {\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}} ``` JSON array with timestamps: ```json [ {\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}}, {\"ts\":1634712588000,\"values\":{\"temperature\":25, \"humidity\":88}} ] ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param body (required) - * @param headers Optional headers to include in the request - * @return String - * @throws ApiException if fails to make API call - */ - public String postTelemetry(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String body, Map headers) throws ApiException { - ApiResponse localVarResponse = postTelemetryWithHttpInfo(deviceToken, body, headers); - return localVarResponse.getData(); - } - - /** - * Post time series data (postTelemetry) - * Post time series data on behalf of device. Example of the request: The request payload is a JSON document with three possible formats: Simple format without timestamp. In such a case, current server time will be used: ```json { \"stringKey\":\"value1\", \"booleanKey\":true, \"doubleKey\":42.0, \"longKey\":73, \"jsonKey\": { \"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"} } } ``` Single JSON object with timestamp: ```json {\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}} ``` JSON array with timestamps: ```json [ {\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}}, {\"ts\":1634712588000,\"values\":{\"temperature\":25, \"humidity\":88}} ] ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param body (required) - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse postTelemetryWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String body) throws ApiException { - return postTelemetryWithHttpInfo(deviceToken, body, null); - } - - /** - * Post time series data (postTelemetry) - * Post time series data on behalf of device. Example of the request: The request payload is a JSON document with three possible formats: Simple format without timestamp. In such a case, current server time will be used: ```json { \"stringKey\":\"value1\", \"booleanKey\":true, \"doubleKey\":42.0, \"longKey\":73, \"jsonKey\": { \"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"} } } ``` Single JSON object with timestamp: ```json {\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}} ``` JSON array with timestamps: ```json [ {\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}}, {\"ts\":1634712588000,\"values\":{\"temperature\":25, \"humidity\":88}} ] ``` The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param body (required) - * @param headers Optional headers to include in the request - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse postTelemetryWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String body, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = postTelemetryRequestBuilder(deviceToken, body, headers); - try { - HttpResponse localVarResponse = memberVarHttpClient.send( - localVarRequestBuilder.build(), - HttpResponse.BodyHandlers.ofInputStream()); - if (memberVarResponseInterceptor != null) { - memberVarResponseInterceptor.accept(localVarResponse); - } - InputStream localVarResponseBody = null; - try { - if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("postTelemetry", localVarResponse); - } - localVarResponseBody = ApiClient.getResponseBody(localVarResponse); - if (localVarResponseBody == null) { - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - null - ); - } - - - - String responseBody = new String(localVarResponseBody.readAllBytes()); - String responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); - - - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - responseValue - ); - } finally { - if (localVarResponseBody != null) { - localVarResponseBody.close(); - } - } - } catch (IOException e) { - throw new ApiException(e); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new ApiException(e); - } - } - - private HttpRequest.Builder postTelemetryRequestBuilder(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String body, Map headers) throws ApiException { - // verify the required parameter 'deviceToken' is set - if (deviceToken == null) { - throw new ApiException(400, "Missing the required parameter 'deviceToken' when calling postTelemetry"); - } - // verify the required parameter 'body' is set - if (body == null) { - throw new ApiException(400, "Missing the required parameter 'body' when calling postTelemetry"); - } - - HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - - String localVarPath = "/api/v1/{deviceToken}/telemetry" - .replace("{deviceToken}", ApiClient.urlEncode(deviceToken.toString())); - - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); - - localVarRequestBuilder.header("Content-Type", "application/json"); - localVarRequestBuilder.header("Accept", "application/json"); - - localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofString(body)); - if (memberVarReadTimeout != null) { - localVarRequestBuilder.timeout(memberVarReadTimeout); - } - // Add custom headers if provided - localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); - if (memberVarInterceptor != null) { - memberVarInterceptor.accept(localVarRequestBuilder); - } - return localVarRequestBuilder; - } - /** * Import the bulk of assets (processAssetsBulkImport) * There's an ability to import the bulk of assets using the only .csv file. @@ -52780,173 +51922,50 @@ private HttpRequest.Builder processAssetsBulkImportRequestBuilder(@javax.annotat } /** - * Import the bulk of devices (processDevicesBulkImport) - * There's an ability to import the bulk of devices using the only .csv file. Available for users with 'TENANT_ADMIN' authority. - * @param bulkImportRequest (required) - * @return BulkImportResultDevice - * @throws ApiException if fails to make API call - */ - public BulkImportResultDevice processDevicesBulkImport(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest) throws ApiException { - return processDevicesBulkImport(bulkImportRequest, null); - } - - /** - * Import the bulk of devices (processDevicesBulkImport) - * There's an ability to import the bulk of devices using the only .csv file. Available for users with 'TENANT_ADMIN' authority. - * @param bulkImportRequest (required) - * @param headers Optional headers to include in the request - * @return BulkImportResultDevice - * @throws ApiException if fails to make API call - */ - public BulkImportResultDevice processDevicesBulkImport(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest, Map headers) throws ApiException { - ApiResponse localVarResponse = processDevicesBulkImportWithHttpInfo(bulkImportRequest, headers); - return localVarResponse.getData(); - } - - /** - * Import the bulk of devices (processDevicesBulkImport) - * There's an ability to import the bulk of devices using the only .csv file. Available for users with 'TENANT_ADMIN' authority. - * @param bulkImportRequest (required) - * @return ApiResponse<BulkImportResultDevice> - * @throws ApiException if fails to make API call - */ - public ApiResponse processDevicesBulkImportWithHttpInfo(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest) throws ApiException { - return processDevicesBulkImportWithHttpInfo(bulkImportRequest, null); - } - - /** - * Import the bulk of devices (processDevicesBulkImport) - * There's an ability to import the bulk of devices using the only .csv file. Available for users with 'TENANT_ADMIN' authority. - * @param bulkImportRequest (required) - * @param headers Optional headers to include in the request - * @return ApiResponse<BulkImportResultDevice> - * @throws ApiException if fails to make API call - */ - public ApiResponse processDevicesBulkImportWithHttpInfo(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = processDevicesBulkImportRequestBuilder(bulkImportRequest, headers); - try { - HttpResponse localVarResponse = memberVarHttpClient.send( - localVarRequestBuilder.build(), - HttpResponse.BodyHandlers.ofInputStream()); - if (memberVarResponseInterceptor != null) { - memberVarResponseInterceptor.accept(localVarResponse); - } - InputStream localVarResponseBody = null; - try { - if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("processDevicesBulkImport", localVarResponse); - } - localVarResponseBody = ApiClient.getResponseBody(localVarResponse); - if (localVarResponseBody == null) { - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - null - ); - } - - - - String responseBody = new String(localVarResponseBody.readAllBytes()); - BulkImportResultDevice responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); - - - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - responseValue - ); - } finally { - if (localVarResponseBody != null) { - localVarResponseBody.close(); - } - } - } catch (IOException e) { - throw new ApiException(e); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new ApiException(e); - } - } - - private HttpRequest.Builder processDevicesBulkImportRequestBuilder(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest, Map headers) throws ApiException { - // verify the required parameter 'bulkImportRequest' is set - if (bulkImportRequest == null) { - throw new ApiException(400, "Missing the required parameter 'bulkImportRequest' when calling processDevicesBulkImport"); - } - - HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - - String localVarPath = "/api/device/bulk_import"; - - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); - - localVarRequestBuilder.header("Content-Type", "application/json"); - localVarRequestBuilder.header("Accept", "application/json"); - - try { - byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(bulkImportRequest); - localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); - } catch (IOException e) { - throw new ApiException(e); - } - if (memberVarReadTimeout != null) { - localVarRequestBuilder.timeout(memberVarReadTimeout); - } - // Add custom headers if provided - localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); - if (memberVarInterceptor != null) { - memberVarInterceptor.accept(localVarRequestBuilder); - } - return localVarRequestBuilder; - } - - /** - * Import the bulk of edges (processEdgesBulkImport) - * There's an ability to import the bulk of edges using the only .csv file. Available for users with 'TENANT_ADMIN' authority. + * Import the bulk of devices (processDevicesBulkImport) + * There's an ability to import the bulk of devices using the only .csv file. Available for users with 'TENANT_ADMIN' authority. * @param bulkImportRequest (required) - * @return BulkImportResultEdge + * @return BulkImportResultDevice * @throws ApiException if fails to make API call */ - public BulkImportResultEdge processEdgesBulkImport(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest) throws ApiException { - return processEdgesBulkImport(bulkImportRequest, null); + public BulkImportResultDevice processDevicesBulkImport(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest) throws ApiException { + return processDevicesBulkImport(bulkImportRequest, null); } /** - * Import the bulk of edges (processEdgesBulkImport) - * There's an ability to import the bulk of edges using the only .csv file. Available for users with 'TENANT_ADMIN' authority. + * Import the bulk of devices (processDevicesBulkImport) + * There's an ability to import the bulk of devices using the only .csv file. Available for users with 'TENANT_ADMIN' authority. * @param bulkImportRequest (required) * @param headers Optional headers to include in the request - * @return BulkImportResultEdge + * @return BulkImportResultDevice * @throws ApiException if fails to make API call */ - public BulkImportResultEdge processEdgesBulkImport(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest, Map headers) throws ApiException { - ApiResponse localVarResponse = processEdgesBulkImportWithHttpInfo(bulkImportRequest, headers); + public BulkImportResultDevice processDevicesBulkImport(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest, Map headers) throws ApiException { + ApiResponse localVarResponse = processDevicesBulkImportWithHttpInfo(bulkImportRequest, headers); return localVarResponse.getData(); } /** - * Import the bulk of edges (processEdgesBulkImport) - * There's an ability to import the bulk of edges using the only .csv file. Available for users with 'TENANT_ADMIN' authority. + * Import the bulk of devices (processDevicesBulkImport) + * There's an ability to import the bulk of devices using the only .csv file. Available for users with 'TENANT_ADMIN' authority. * @param bulkImportRequest (required) - * @return ApiResponse<BulkImportResultEdge> + * @return ApiResponse<BulkImportResultDevice> * @throws ApiException if fails to make API call */ - public ApiResponse processEdgesBulkImportWithHttpInfo(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest) throws ApiException { - return processEdgesBulkImportWithHttpInfo(bulkImportRequest, null); + public ApiResponse processDevicesBulkImportWithHttpInfo(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest) throws ApiException { + return processDevicesBulkImportWithHttpInfo(bulkImportRequest, null); } /** - * Import the bulk of edges (processEdgesBulkImport) - * There's an ability to import the bulk of edges using the only .csv file. Available for users with 'TENANT_ADMIN' authority. + * Import the bulk of devices (processDevicesBulkImport) + * There's an ability to import the bulk of devices using the only .csv file. Available for users with 'TENANT_ADMIN' authority. * @param bulkImportRequest (required) * @param headers Optional headers to include in the request - * @return ApiResponse<BulkImportResultEdge> + * @return ApiResponse<BulkImportResultDevice> * @throws ApiException if fails to make API call */ - public ApiResponse processEdgesBulkImportWithHttpInfo(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = processEdgesBulkImportRequestBuilder(bulkImportRequest, headers); + public ApiResponse processDevicesBulkImportWithHttpInfo(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest, Map headers) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = processDevicesBulkImportRequestBuilder(bulkImportRequest, headers); try { HttpResponse localVarResponse = memberVarHttpClient.send( localVarRequestBuilder.build(), @@ -52957,11 +51976,11 @@ public ApiResponse processEdgesBulkImportWithHttpInfo(@jav InputStream localVarResponseBody = null; try { if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("processEdgesBulkImport", localVarResponse); + throw getApiException("processDevicesBulkImport", localVarResponse); } localVarResponseBody = ApiClient.getResponseBody(localVarResponse); if (localVarResponseBody == null) { - return new ApiResponse( + return new ApiResponse( localVarResponse.statusCode(), localVarResponse.headers().map(), null @@ -52971,10 +51990,10 @@ public ApiResponse processEdgesBulkImportWithHttpInfo(@jav String responseBody = new String(localVarResponseBody.readAllBytes()); - BulkImportResultEdge responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + BulkImportResultDevice responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); - return new ApiResponse( + return new ApiResponse( localVarResponse.statusCode(), localVarResponse.headers().map(), responseValue @@ -52993,15 +52012,15 @@ public ApiResponse processEdgesBulkImportWithHttpInfo(@jav } } - private HttpRequest.Builder processEdgesBulkImportRequestBuilder(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest, Map headers) throws ApiException { + private HttpRequest.Builder processDevicesBulkImportRequestBuilder(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest, Map headers) throws ApiException { // verify the required parameter 'bulkImportRequest' is set if (bulkImportRequest == null) { - throw new ApiException(400, "Missing the required parameter 'bulkImportRequest' when calling processEdgesBulkImport"); + throw new ApiException(400, "Missing the required parameter 'bulkImportRequest' when calling processDevicesBulkImport"); } HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - String localVarPath = "/api/edge/bulk_import"; + String localVarPath = "/api/device/bulk_import"; localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); @@ -53026,47 +52045,50 @@ private HttpRequest.Builder processEdgesBulkImportRequestBuilder(@javax.annotati } /** - * processSystemEdqsRequest - * - * @param toCoreEdqsRequest (required) + * Import the bulk of edges (processEdgesBulkImport) + * There's an ability to import the bulk of edges using the only .csv file. Available for users with 'TENANT_ADMIN' authority. + * @param bulkImportRequest (required) + * @return BulkImportResultEdge * @throws ApiException if fails to make API call */ - public void processSystemEdqsRequest(@javax.annotation.Nonnull ToCoreEdqsRequest toCoreEdqsRequest) throws ApiException { - processSystemEdqsRequest(toCoreEdqsRequest, null); + public BulkImportResultEdge processEdgesBulkImport(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest) throws ApiException { + return processEdgesBulkImport(bulkImportRequest, null); } /** - * processSystemEdqsRequest - * - * @param toCoreEdqsRequest (required) + * Import the bulk of edges (processEdgesBulkImport) + * There's an ability to import the bulk of edges using the only .csv file. Available for users with 'TENANT_ADMIN' authority. + * @param bulkImportRequest (required) * @param headers Optional headers to include in the request + * @return BulkImportResultEdge * @throws ApiException if fails to make API call */ - public void processSystemEdqsRequest(@javax.annotation.Nonnull ToCoreEdqsRequest toCoreEdqsRequest, Map headers) throws ApiException { - processSystemEdqsRequestWithHttpInfo(toCoreEdqsRequest, headers); + public BulkImportResultEdge processEdgesBulkImport(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest, Map headers) throws ApiException { + ApiResponse localVarResponse = processEdgesBulkImportWithHttpInfo(bulkImportRequest, headers); + return localVarResponse.getData(); } /** - * processSystemEdqsRequest - * - * @param toCoreEdqsRequest (required) - * @return ApiResponse<Void> + * Import the bulk of edges (processEdgesBulkImport) + * There's an ability to import the bulk of edges using the only .csv file. Available for users with 'TENANT_ADMIN' authority. + * @param bulkImportRequest (required) + * @return ApiResponse<BulkImportResultEdge> * @throws ApiException if fails to make API call */ - public ApiResponse processSystemEdqsRequestWithHttpInfo(@javax.annotation.Nonnull ToCoreEdqsRequest toCoreEdqsRequest) throws ApiException { - return processSystemEdqsRequestWithHttpInfo(toCoreEdqsRequest, null); + public ApiResponse processEdgesBulkImportWithHttpInfo(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest) throws ApiException { + return processEdgesBulkImportWithHttpInfo(bulkImportRequest, null); } /** - * processSystemEdqsRequest - * - * @param toCoreEdqsRequest (required) + * Import the bulk of edges (processEdgesBulkImport) + * There's an ability to import the bulk of edges using the only .csv file. Available for users with 'TENANT_ADMIN' authority. + * @param bulkImportRequest (required) * @param headers Optional headers to include in the request - * @return ApiResponse<Void> + * @return ApiResponse<BulkImportResultEdge> * @throws ApiException if fails to make API call */ - public ApiResponse processSystemEdqsRequestWithHttpInfo(@javax.annotation.Nonnull ToCoreEdqsRequest toCoreEdqsRequest, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = processSystemEdqsRequestRequestBuilder(toCoreEdqsRequest, headers); + public ApiResponse processEdgesBulkImportWithHttpInfo(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest, Map headers) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = processEdgesBulkImportRequestBuilder(bulkImportRequest, headers); try { HttpResponse localVarResponse = memberVarHttpClient.send( localVarRequestBuilder.build(), @@ -53077,16 +52099,27 @@ public ApiResponse processSystemEdqsRequestWithHttpInfo(@javax.annotation. InputStream localVarResponseBody = null; try { if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("processSystemEdqsRequest", localVarResponse); + throw getApiException("processEdgesBulkImport", localVarResponse); } localVarResponseBody = ApiClient.getResponseBody(localVarResponse); - if (localVarResponseBody != null) { - localVarResponseBody.readAllBytes(); + if (localVarResponseBody == null) { + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ); } - return new ApiResponse<>( + + + + String responseBody = new String(localVarResponseBody.readAllBytes()); + BulkImportResultEdge responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + + + return new ApiResponse( localVarResponse.statusCode(), localVarResponse.headers().map(), - null + responseValue ); } finally { if (localVarResponseBody != null) { @@ -53102,15 +52135,15 @@ public ApiResponse processSystemEdqsRequestWithHttpInfo(@javax.annotation. } } - private HttpRequest.Builder processSystemEdqsRequestRequestBuilder(@javax.annotation.Nonnull ToCoreEdqsRequest toCoreEdqsRequest, Map headers) throws ApiException { - // verify the required parameter 'toCoreEdqsRequest' is set - if (toCoreEdqsRequest == null) { - throw new ApiException(400, "Missing the required parameter 'toCoreEdqsRequest' when calling processSystemEdqsRequest"); + private HttpRequest.Builder processEdgesBulkImportRequestBuilder(@javax.annotation.Nonnull BulkImportRequest bulkImportRequest, Map headers) throws ApiException { + // verify the required parameter 'bulkImportRequest' is set + if (bulkImportRequest == null) { + throw new ApiException(400, "Missing the required parameter 'bulkImportRequest' when calling processEdgesBulkImport"); } HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - String localVarPath = "/api/edqs/system/request"; + String localVarPath = "/api/edge/bulk_import"; localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); @@ -53118,7 +52151,7 @@ private HttpRequest.Builder processSystemEdqsRequestRequestBuilder(@javax.annota localVarRequestBuilder.header("Accept", "application/json"); try { - byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(toCoreEdqsRequest); + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(bulkImportRequest); localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); } catch (IOException e) { throw new ApiException(e); @@ -53135,50 +52168,47 @@ private HttpRequest.Builder processSystemEdqsRequestRequestBuilder(@javax.annota } /** - * Provision new device (provisionDevice) - * Exchange the provision request to the device credentials. See more info about provisioning in the corresponding 'Device provisioning' platform documentation.Requires valid JSON request with the following format: ```json { \"deviceName\": \"NEW_DEVICE_NAME\", \"provisionDeviceKey\": \"u7piawkboq8v32dmcmpp\", \"provisionDeviceSecret\": \"jpmwdn8ptlswmf4m29bw\" } ``` Where 'deviceName' is the name of enw or existing device which depends on the provisioning strategy. The 'provisionDeviceKey' and 'provisionDeviceSecret' matches info configured in one of the existing device profiles. The result of the successful call is the JSON object that contains new credentials: ```json { \"credentialsType\":\"ACCESS_TOKEN\", \"credentialsValue\":\"DEVICE_ACCESS_TOKEN\", \"status\":\"SUCCESS\" } ``` - * @param body JSON with provision request. See API call description for example. (required) - * @return String + * processSystemEdqsRequest + * + * @param toCoreEdqsRequest (required) * @throws ApiException if fails to make API call */ - public String provisionDevice(@javax.annotation.Nonnull String body) throws ApiException { - return provisionDevice(body, null); + public void processSystemEdqsRequest(@javax.annotation.Nonnull ToCoreEdqsRequest toCoreEdqsRequest) throws ApiException { + processSystemEdqsRequest(toCoreEdqsRequest, null); } /** - * Provision new device (provisionDevice) - * Exchange the provision request to the device credentials. See more info about provisioning in the corresponding 'Device provisioning' platform documentation.Requires valid JSON request with the following format: ```json { \"deviceName\": \"NEW_DEVICE_NAME\", \"provisionDeviceKey\": \"u7piawkboq8v32dmcmpp\", \"provisionDeviceSecret\": \"jpmwdn8ptlswmf4m29bw\" } ``` Where 'deviceName' is the name of enw or existing device which depends on the provisioning strategy. The 'provisionDeviceKey' and 'provisionDeviceSecret' matches info configured in one of the existing device profiles. The result of the successful call is the JSON object that contains new credentials: ```json { \"credentialsType\":\"ACCESS_TOKEN\", \"credentialsValue\":\"DEVICE_ACCESS_TOKEN\", \"status\":\"SUCCESS\" } ``` - * @param body JSON with provision request. See API call description for example. (required) + * processSystemEdqsRequest + * + * @param toCoreEdqsRequest (required) * @param headers Optional headers to include in the request - * @return String * @throws ApiException if fails to make API call */ - public String provisionDevice(@javax.annotation.Nonnull String body, Map headers) throws ApiException { - ApiResponse localVarResponse = provisionDeviceWithHttpInfo(body, headers); - return localVarResponse.getData(); + public void processSystemEdqsRequest(@javax.annotation.Nonnull ToCoreEdqsRequest toCoreEdqsRequest, Map headers) throws ApiException { + processSystemEdqsRequestWithHttpInfo(toCoreEdqsRequest, headers); } /** - * Provision new device (provisionDevice) - * Exchange the provision request to the device credentials. See more info about provisioning in the corresponding 'Device provisioning' platform documentation.Requires valid JSON request with the following format: ```json { \"deviceName\": \"NEW_DEVICE_NAME\", \"provisionDeviceKey\": \"u7piawkboq8v32dmcmpp\", \"provisionDeviceSecret\": \"jpmwdn8ptlswmf4m29bw\" } ``` Where 'deviceName' is the name of enw or existing device which depends on the provisioning strategy. The 'provisionDeviceKey' and 'provisionDeviceSecret' matches info configured in one of the existing device profiles. The result of the successful call is the JSON object that contains new credentials: ```json { \"credentialsType\":\"ACCESS_TOKEN\", \"credentialsValue\":\"DEVICE_ACCESS_TOKEN\", \"status\":\"SUCCESS\" } ``` - * @param body JSON with provision request. See API call description for example. (required) - * @return ApiResponse<String> + * processSystemEdqsRequest + * + * @param toCoreEdqsRequest (required) + * @return ApiResponse<Void> * @throws ApiException if fails to make API call */ - public ApiResponse provisionDeviceWithHttpInfo(@javax.annotation.Nonnull String body) throws ApiException { - return provisionDeviceWithHttpInfo(body, null); + public ApiResponse processSystemEdqsRequestWithHttpInfo(@javax.annotation.Nonnull ToCoreEdqsRequest toCoreEdqsRequest) throws ApiException { + return processSystemEdqsRequestWithHttpInfo(toCoreEdqsRequest, null); } /** - * Provision new device (provisionDevice) - * Exchange the provision request to the device credentials. See more info about provisioning in the corresponding 'Device provisioning' platform documentation.Requires valid JSON request with the following format: ```json { \"deviceName\": \"NEW_DEVICE_NAME\", \"provisionDeviceKey\": \"u7piawkboq8v32dmcmpp\", \"provisionDeviceSecret\": \"jpmwdn8ptlswmf4m29bw\" } ``` Where 'deviceName' is the name of enw or existing device which depends on the provisioning strategy. The 'provisionDeviceKey' and 'provisionDeviceSecret' matches info configured in one of the existing device profiles. The result of the successful call is the JSON object that contains new credentials: ```json { \"credentialsType\":\"ACCESS_TOKEN\", \"credentialsValue\":\"DEVICE_ACCESS_TOKEN\", \"status\":\"SUCCESS\" } ``` - * @param body JSON with provision request. See API call description for example. (required) + * processSystemEdqsRequest + * + * @param toCoreEdqsRequest (required) * @param headers Optional headers to include in the request - * @return ApiResponse<String> + * @return ApiResponse<Void> * @throws ApiException if fails to make API call */ - public ApiResponse provisionDeviceWithHttpInfo(@javax.annotation.Nonnull String body, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = provisionDeviceRequestBuilder(body, headers); + public ApiResponse processSystemEdqsRequestWithHttpInfo(@javax.annotation.Nonnull ToCoreEdqsRequest toCoreEdqsRequest, Map headers) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = processSystemEdqsRequestRequestBuilder(toCoreEdqsRequest, headers); try { HttpResponse localVarResponse = memberVarHttpClient.send( localVarRequestBuilder.build(), @@ -53189,27 +52219,16 @@ public ApiResponse provisionDeviceWithHttpInfo(@javax.annotation.Nonnull InputStream localVarResponseBody = null; try { if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("provisionDevice", localVarResponse); + throw getApiException("processSystemEdqsRequest", localVarResponse); } localVarResponseBody = ApiClient.getResponseBody(localVarResponse); - if (localVarResponseBody == null) { - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - null - ); + if (localVarResponseBody != null) { + localVarResponseBody.readAllBytes(); } - - - - String responseBody = new String(localVarResponseBody.readAllBytes()); - String responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); - - - return new ApiResponse( + return new ApiResponse<>( localVarResponse.statusCode(), localVarResponse.headers().map(), - responseValue + null ); } finally { if (localVarResponseBody != null) { @@ -53225,22 +52244,27 @@ public ApiResponse provisionDeviceWithHttpInfo(@javax.annotation.Nonnull } } - private HttpRequest.Builder provisionDeviceRequestBuilder(@javax.annotation.Nonnull String body, Map headers) throws ApiException { - // verify the required parameter 'body' is set - if (body == null) { - throw new ApiException(400, "Missing the required parameter 'body' when calling provisionDevice"); + private HttpRequest.Builder processSystemEdqsRequestRequestBuilder(@javax.annotation.Nonnull ToCoreEdqsRequest toCoreEdqsRequest, Map headers) throws ApiException { + // verify the required parameter 'toCoreEdqsRequest' is set + if (toCoreEdqsRequest == null) { + throw new ApiException(400, "Missing the required parameter 'toCoreEdqsRequest' when calling processSystemEdqsRequest"); } HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - String localVarPath = "/api/v1/provision"; + String localVarPath = "/api/edqs/system/request"; localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); localVarRequestBuilder.header("Content-Type", "application/json"); localVarRequestBuilder.header("Accept", "application/json"); - localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofString(body)); + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(toCoreEdqsRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } if (memberVarReadTimeout != null) { localVarRequestBuilder.timeout(memberVarReadTimeout); } @@ -53954,142 +52978,6 @@ private HttpRequest.Builder removeMobileSessionRequestBuilder(@javax.annotation. return localVarRequestBuilder; } - /** - * Reply to RPC commands (replyToCommand) - * Replies to server originated RPC command identified by 'requestId' parameter. The response is arbitrary JSON. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param requestId RPC request id from the incoming RPC request (required) - * @param body Reply to the RPC request, JSON. For example: {\"status\":\"success\"} (required) - * @return String - * @throws ApiException if fails to make API call - */ - public String replyToCommand(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String requestId, @javax.annotation.Nonnull String body) throws ApiException { - return replyToCommand(deviceToken, requestId, body, null); - } - - /** - * Reply to RPC commands (replyToCommand) - * Replies to server originated RPC command identified by 'requestId' parameter. The response is arbitrary JSON. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param requestId RPC request id from the incoming RPC request (required) - * @param body Reply to the RPC request, JSON. For example: {\"status\":\"success\"} (required) - * @param headers Optional headers to include in the request - * @return String - * @throws ApiException if fails to make API call - */ - public String replyToCommand(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String requestId, @javax.annotation.Nonnull String body, Map headers) throws ApiException { - ApiResponse localVarResponse = replyToCommandWithHttpInfo(deviceToken, requestId, body, headers); - return localVarResponse.getData(); - } - - /** - * Reply to RPC commands (replyToCommand) - * Replies to server originated RPC command identified by 'requestId' parameter. The response is arbitrary JSON. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param requestId RPC request id from the incoming RPC request (required) - * @param body Reply to the RPC request, JSON. For example: {\"status\":\"success\"} (required) - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse replyToCommandWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String requestId, @javax.annotation.Nonnull String body) throws ApiException { - return replyToCommandWithHttpInfo(deviceToken, requestId, body, null); - } - - /** - * Reply to RPC commands (replyToCommand) - * Replies to server originated RPC command identified by 'requestId' parameter. The response is arbitrary JSON. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param requestId RPC request id from the incoming RPC request (required) - * @param body Reply to the RPC request, JSON. For example: {\"status\":\"success\"} (required) - * @param headers Optional headers to include in the request - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse replyToCommandWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String requestId, @javax.annotation.Nonnull String body, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = replyToCommandRequestBuilder(deviceToken, requestId, body, headers); - try { - HttpResponse localVarResponse = memberVarHttpClient.send( - localVarRequestBuilder.build(), - HttpResponse.BodyHandlers.ofInputStream()); - if (memberVarResponseInterceptor != null) { - memberVarResponseInterceptor.accept(localVarResponse); - } - InputStream localVarResponseBody = null; - try { - if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("replyToCommand", localVarResponse); - } - localVarResponseBody = ApiClient.getResponseBody(localVarResponse); - if (localVarResponseBody == null) { - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - null - ); - } - - - - String responseBody = new String(localVarResponseBody.readAllBytes()); - String responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); - - - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - responseValue - ); - } finally { - if (localVarResponseBody != null) { - localVarResponseBody.close(); - } - } - } catch (IOException e) { - throw new ApiException(e); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new ApiException(e); - } - } - - private HttpRequest.Builder replyToCommandRequestBuilder(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nonnull String requestId, @javax.annotation.Nonnull String body, Map headers) throws ApiException { - // verify the required parameter 'deviceToken' is set - if (deviceToken == null) { - throw new ApiException(400, "Missing the required parameter 'deviceToken' when calling replyToCommand"); - } - // verify the required parameter 'requestId' is set - if (requestId == null) { - throw new ApiException(400, "Missing the required parameter 'requestId' when calling replyToCommand"); - } - // verify the required parameter 'body' is set - if (body == null) { - throw new ApiException(400, "Missing the required parameter 'body' when calling replyToCommand"); - } - - HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - - String localVarPath = "/api/v1/{deviceToken}/rpc/{requestId}" - .replace("{deviceToken}", ApiClient.urlEncode(deviceToken.toString())) - .replace("{requestId}", ApiClient.urlEncode(requestId.toString())); - - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); - - localVarRequestBuilder.header("Content-Type", "application/json"); - localVarRequestBuilder.header("Accept", "application/json"); - - localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofString(body)); - if (memberVarReadTimeout != null) { - localVarRequestBuilder.timeout(memberVarReadTimeout); - } - // Add custom headers if provided - localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); - if (memberVarInterceptor != null) { - memberVarInterceptor.accept(localVarRequestBuilder); - } - return localVarRequestBuilder; - } - /** * Report action of User over the dashboard (reportUserDashboardAction) * Report action of User over the dashboard. Available for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. @@ -55913,129 +54801,6 @@ private HttpRequest.Builder saveCalculatedFieldRequestBuilder(@javax.annotation. return localVarRequestBuilder; } - /** - * Save claiming information (saveClaimingInfo) - * Saves the information required for user to claim the device. See more info about claiming in the corresponding 'Claiming devices' platform documentation. Example of the request payload: ```json {\"secretKey\":\"value\", \"durationMs\":60000} ``` Note: both 'secretKey' and 'durationMs' is optional parameters. In case the secretKey is not specified, the empty string as a default value is used. In case the durationMs is not specified, the system parameter device.claim.duration is used. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param body (optional) - * @return String - * @throws ApiException if fails to make API call - */ - public String saveClaimingInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nullable String body) throws ApiException { - return saveClaimingInfo(deviceToken, body, null); - } - - /** - * Save claiming information (saveClaimingInfo) - * Saves the information required for user to claim the device. See more info about claiming in the corresponding 'Claiming devices' platform documentation. Example of the request payload: ```json {\"secretKey\":\"value\", \"durationMs\":60000} ``` Note: both 'secretKey' and 'durationMs' is optional parameters. In case the secretKey is not specified, the empty string as a default value is used. In case the durationMs is not specified, the system parameter device.claim.duration is used. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param body (optional) - * @param headers Optional headers to include in the request - * @return String - * @throws ApiException if fails to make API call - */ - public String saveClaimingInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nullable String body, Map headers) throws ApiException { - ApiResponse localVarResponse = saveClaimingInfoWithHttpInfo(deviceToken, body, headers); - return localVarResponse.getData(); - } - - /** - * Save claiming information (saveClaimingInfo) - * Saves the information required for user to claim the device. See more info about claiming in the corresponding 'Claiming devices' platform documentation. Example of the request payload: ```json {\"secretKey\":\"value\", \"durationMs\":60000} ``` Note: both 'secretKey' and 'durationMs' is optional parameters. In case the secretKey is not specified, the empty string as a default value is used. In case the durationMs is not specified, the system parameter device.claim.duration is used. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param body (optional) - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse saveClaimingInfoWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nullable String body) throws ApiException { - return saveClaimingInfoWithHttpInfo(deviceToken, body, null); - } - - /** - * Save claiming information (saveClaimingInfo) - * Saves the information required for user to claim the device. See more info about claiming in the corresponding 'Claiming devices' platform documentation. Example of the request payload: ```json {\"secretKey\":\"value\", \"durationMs\":60000} ``` Note: both 'secretKey' and 'durationMs' is optional parameters. In case the secretKey is not specified, the empty string as a default value is used. In case the durationMs is not specified, the system parameter device.claim.duration is used. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param body (optional) - * @param headers Optional headers to include in the request - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse saveClaimingInfoWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nullable String body, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = saveClaimingInfoRequestBuilder(deviceToken, body, headers); - try { - HttpResponse localVarResponse = memberVarHttpClient.send( - localVarRequestBuilder.build(), - HttpResponse.BodyHandlers.ofInputStream()); - if (memberVarResponseInterceptor != null) { - memberVarResponseInterceptor.accept(localVarResponse); - } - InputStream localVarResponseBody = null; - try { - if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("saveClaimingInfo", localVarResponse); - } - localVarResponseBody = ApiClient.getResponseBody(localVarResponse); - if (localVarResponseBody == null) { - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - null - ); - } - - - - String responseBody = new String(localVarResponseBody.readAllBytes()); - String responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); - - - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - responseValue - ); - } finally { - if (localVarResponseBody != null) { - localVarResponseBody.close(); - } - } - } catch (IOException e) { - throw new ApiException(e); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new ApiException(e); - } - } - - private HttpRequest.Builder saveClaimingInfoRequestBuilder(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nullable String body, Map headers) throws ApiException { - // verify the required parameter 'deviceToken' is set - if (deviceToken == null) { - throw new ApiException(400, "Missing the required parameter 'deviceToken' when calling saveClaimingInfo"); - } - - HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - - String localVarPath = "/api/v1/{deviceToken}/claim" - .replace("{deviceToken}", ApiClient.urlEncode(deviceToken.toString())); - - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); - - localVarRequestBuilder.header("Content-Type", "application/json"); - localVarRequestBuilder.header("Accept", "application/json"); - - localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofString(body)); - if (memberVarReadTimeout != null) { - localVarRequestBuilder.timeout(memberVarReadTimeout); - } - // Add custom headers if provided - localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); - if (memberVarInterceptor != null) { - memberVarInterceptor.accept(localVarRequestBuilder); - } - return localVarRequestBuilder; - } - /** * Create or update OAuth2 client registration template (saveClientRegistrationTemplate) Available for users with 'SYS_ADMIN' authority. * Client registration template is OAuth2 provider configuration template with default settings for registering new OAuth2 clients @@ -63746,280 +62511,6 @@ private HttpRequest.Builder submitTwoFaAccountConfigRequestBuilder(@javax.annota return localVarRequestBuilder; } - /** - * Subscribe to attribute updates (subscribeToAttributes) (Deprecated) - * Subscribes to client and shared scope attribute updates using http long polling. Deprecated, since long polling is resource and network consuming. Consider using MQTT or CoAP protocol for light-weight real-time updates. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param timeout Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side. (optional, default to 0) - * @return String - * @throws ApiException if fails to make API call - */ - public String subscribeToAttributes(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nullable Long timeout) throws ApiException { - return subscribeToAttributes(deviceToken, timeout, null); - } - - /** - * Subscribe to attribute updates (subscribeToAttributes) (Deprecated) - * Subscribes to client and shared scope attribute updates using http long polling. Deprecated, since long polling is resource and network consuming. Consider using MQTT or CoAP protocol for light-weight real-time updates. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param timeout Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side. (optional, default to 0) - * @param headers Optional headers to include in the request - * @return String - * @throws ApiException if fails to make API call - */ - public String subscribeToAttributes(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nullable Long timeout, Map headers) throws ApiException { - ApiResponse localVarResponse = subscribeToAttributesWithHttpInfo(deviceToken, timeout, headers); - return localVarResponse.getData(); - } - - /** - * Subscribe to attribute updates (subscribeToAttributes) (Deprecated) - * Subscribes to client and shared scope attribute updates using http long polling. Deprecated, since long polling is resource and network consuming. Consider using MQTT or CoAP protocol for light-weight real-time updates. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param timeout Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side. (optional, default to 0) - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse subscribeToAttributesWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nullable Long timeout) throws ApiException { - return subscribeToAttributesWithHttpInfo(deviceToken, timeout, null); - } - - /** - * Subscribe to attribute updates (subscribeToAttributes) (Deprecated) - * Subscribes to client and shared scope attribute updates using http long polling. Deprecated, since long polling is resource and network consuming. Consider using MQTT or CoAP protocol for light-weight real-time updates. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param timeout Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side. (optional, default to 0) - * @param headers Optional headers to include in the request - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse subscribeToAttributesWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nullable Long timeout, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = subscribeToAttributesRequestBuilder(deviceToken, timeout, headers); - try { - HttpResponse localVarResponse = memberVarHttpClient.send( - localVarRequestBuilder.build(), - HttpResponse.BodyHandlers.ofInputStream()); - if (memberVarResponseInterceptor != null) { - memberVarResponseInterceptor.accept(localVarResponse); - } - InputStream localVarResponseBody = null; - try { - if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("subscribeToAttributes", localVarResponse); - } - localVarResponseBody = ApiClient.getResponseBody(localVarResponse); - if (localVarResponseBody == null) { - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - null - ); - } - - - - String responseBody = new String(localVarResponseBody.readAllBytes()); - String responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); - - - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - responseValue - ); - } finally { - if (localVarResponseBody != null) { - localVarResponseBody.close(); - } - } - } catch (IOException e) { - throw new ApiException(e); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new ApiException(e); - } - } - - private HttpRequest.Builder subscribeToAttributesRequestBuilder(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nullable Long timeout, Map headers) throws ApiException { - // verify the required parameter 'deviceToken' is set - if (deviceToken == null) { - throw new ApiException(400, "Missing the required parameter 'deviceToken' when calling subscribeToAttributes"); - } - - HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - - String localVarPath = "/api/v1/{deviceToken}/attributes/updates" - .replace("{deviceToken}", ApiClient.urlEncode(deviceToken.toString())); - - List localVarQueryParams = new ArrayList<>(); - StringJoiner localVarQueryStringJoiner = new StringJoiner("&"); - String localVarQueryParameterBaseName; - localVarQueryParameterBaseName = "timeout"; - localVarQueryParams.addAll(ApiClient.parameterToPairs("timeout", timeout)); - - if (!localVarQueryParams.isEmpty() || localVarQueryStringJoiner.length() != 0) { - StringJoiner queryJoiner = new StringJoiner("&"); - localVarQueryParams.forEach(p -> queryJoiner.add(p.getName() + '=' + p.getValue())); - if (localVarQueryStringJoiner.length() != 0) { - queryJoiner.add(localVarQueryStringJoiner.toString()); - } - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath + '?' + queryJoiner.toString())); - } else { - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); - } - - localVarRequestBuilder.header("Accept", "application/json"); - - localVarRequestBuilder.method("GET", HttpRequest.BodyPublishers.noBody()); - if (memberVarReadTimeout != null) { - localVarRequestBuilder.timeout(memberVarReadTimeout); - } - // Add custom headers if provided - localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); - if (memberVarInterceptor != null) { - memberVarInterceptor.accept(localVarRequestBuilder); - } - return localVarRequestBuilder; - } - - /** - * Subscribe to RPC commands (subscribeToCommands) (Deprecated) - * Subscribes to RPC commands using http long polling. Deprecated, since long polling is resource and network consuming. Consider using MQTT or CoAP protocol for light-weight real-time updates. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param timeout Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side. (optional, default to 0) - * @return String - * @throws ApiException if fails to make API call - */ - public String subscribeToCommands(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nullable Long timeout) throws ApiException { - return subscribeToCommands(deviceToken, timeout, null); - } - - /** - * Subscribe to RPC commands (subscribeToCommands) (Deprecated) - * Subscribes to RPC commands using http long polling. Deprecated, since long polling is resource and network consuming. Consider using MQTT or CoAP protocol for light-weight real-time updates. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param timeout Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side. (optional, default to 0) - * @param headers Optional headers to include in the request - * @return String - * @throws ApiException if fails to make API call - */ - public String subscribeToCommands(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nullable Long timeout, Map headers) throws ApiException { - ApiResponse localVarResponse = subscribeToCommandsWithHttpInfo(deviceToken, timeout, headers); - return localVarResponse.getData(); - } - - /** - * Subscribe to RPC commands (subscribeToCommands) (Deprecated) - * Subscribes to RPC commands using http long polling. Deprecated, since long polling is resource and network consuming. Consider using MQTT or CoAP protocol for light-weight real-time updates. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param timeout Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side. (optional, default to 0) - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse subscribeToCommandsWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nullable Long timeout) throws ApiException { - return subscribeToCommandsWithHttpInfo(deviceToken, timeout, null); - } - - /** - * Subscribe to RPC commands (subscribeToCommands) (Deprecated) - * Subscribes to RPC commands using http long polling. Deprecated, since long polling is resource and network consuming. Consider using MQTT or CoAP protocol for light-weight real-time updates. The API call is designed to be used by device firmware and requires device access token ('deviceToken'). It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead). - * @param deviceToken Your device access token. (required) - * @param timeout Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side. (optional, default to 0) - * @param headers Optional headers to include in the request - * @return ApiResponse<String> - * @throws ApiException if fails to make API call - */ - public ApiResponse subscribeToCommandsWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nullable Long timeout, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = subscribeToCommandsRequestBuilder(deviceToken, timeout, headers); - try { - HttpResponse localVarResponse = memberVarHttpClient.send( - localVarRequestBuilder.build(), - HttpResponse.BodyHandlers.ofInputStream()); - if (memberVarResponseInterceptor != null) { - memberVarResponseInterceptor.accept(localVarResponse); - } - InputStream localVarResponseBody = null; - try { - if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("subscribeToCommands", localVarResponse); - } - localVarResponseBody = ApiClient.getResponseBody(localVarResponse); - if (localVarResponseBody == null) { - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - null - ); - } - - - - String responseBody = new String(localVarResponseBody.readAllBytes()); - String responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); - - - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - responseValue - ); - } finally { - if (localVarResponseBody != null) { - localVarResponseBody.close(); - } - } - } catch (IOException e) { - throw new ApiException(e); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new ApiException(e); - } - } - - private HttpRequest.Builder subscribeToCommandsRequestBuilder(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nullable Long timeout, Map headers) throws ApiException { - // verify the required parameter 'deviceToken' is set - if (deviceToken == null) { - throw new ApiException(400, "Missing the required parameter 'deviceToken' when calling subscribeToCommands"); - } - - HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - - String localVarPath = "/api/v1/{deviceToken}/rpc" - .replace("{deviceToken}", ApiClient.urlEncode(deviceToken.toString())); - - List localVarQueryParams = new ArrayList<>(); - StringJoiner localVarQueryStringJoiner = new StringJoiner("&"); - String localVarQueryParameterBaseName; - localVarQueryParameterBaseName = "timeout"; - localVarQueryParams.addAll(ApiClient.parameterToPairs("timeout", timeout)); - - if (!localVarQueryParams.isEmpty() || localVarQueryStringJoiner.length() != 0) { - StringJoiner queryJoiner = new StringJoiner("&"); - localVarQueryParams.forEach(p -> queryJoiner.add(p.getName() + '=' + p.getValue())); - if (localVarQueryStringJoiner.length() != 0) { - queryJoiner.add(localVarQueryStringJoiner.toString()); - } - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath + '?' + queryJoiner.toString())); - } else { - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); - } - - localVarRequestBuilder.header("Accept", "application/json"); - - localVarRequestBuilder.method("GET", HttpRequest.BodyPublishers.noBody()); - if (memberVarReadTimeout != null) { - localVarRequestBuilder.timeout(memberVarReadTimeout); - } - // Add custom headers if provided - localVarRequestBuilder = HttpRequestBuilderExtensions.withAdditionalHeaders(localVarRequestBuilder, headers); - if (memberVarInterceptor != null) { - memberVarInterceptor.accept(localVarRequestBuilder); - } - return localVarRequestBuilder; - } - /** * Sync edge (syncEdge) * Starts synchronization process between edge and cloud. All entities that are assigned to particular edge are going to be send to remote edge service. Available for users with 'TENANT_ADMIN' authority.