diff --git a/pe/docs/DeviceApiControllerApi.md b/pe/docs/DeviceApiControllerApi.md deleted file mode 100644 index ad70f8db..00000000 --- a/pe/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/pe/docs/EntityGroupControllerApi.md b/pe/docs/EntityGroupControllerApi.md index 2a59fa92..6d163e42 100644 --- a/pe/docs/EntityGroupControllerApi.md +++ b/pe/docs/EntityGroupControllerApi.md @@ -37,6 +37,7 @@ void removeEntitiesFromEntityGroup(@Nonnull String entityGroupId, @Nonnull List< EntityGroupInfo saveEntityGroup(@Nonnull EntityGroup entityGroup) // Create Or Update Entity Group (saveEntityGroup) void shareEntityGroup(@Nonnull String entityGroupId, @Nonnull ShareGroupRequest shareGroupRequest) // Share the Entity Group (shareEntityGroup) void shareEntityGroupToChildOwnerUserGroup(@Nonnull String entityGroupId, @Nonnull String userGroupId, @Nonnull String roleId) // Share the Entity Group with User group (shareEntityGroupToChildOwnerUserGroup) +void shareEntityGroupToChildOwnerUserGroupV2(@Nonnull UUID entityGroupId, @Nonnull ShareGroupRequest shareGroupRequest) // Share the Entity Group with User group (shareEntityGroupToChildOwnerUserGroupV2) EntityGroup unassignEntityGroupFromEdge(@Nonnull String edgeId, @Nonnull String groupType, @Nonnull String entityGroupId) // Unassign entity group from edge (unassignEntityGroupFromEdge) ``` @@ -945,6 +946,31 @@ Share the entity group with specified user group using specified role. Availab null (empty response body) +## shareEntityGroupToChildOwnerUserGroupV2 + +``` +void shareEntityGroupToChildOwnerUserGroupV2(@Nonnull UUID entityGroupId, @Nonnull ShareGroupRequest shareGroupRequest) +``` + +**POST** `/api/v2/entityGroup/{entityGroupId}/share` + +Share the Entity Group with User group (shareEntityGroupToChildOwnerUserGroupV2) + +Share the entity group with specified user group using specified role. Available for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for specified group. + + +### Parameters + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **entityGroupId** | **UUID** | A uuid value representing the Entity Group Id that you would like to share. For example, '784f394c-42b6-435a-983c-b7beff2784f9' | | +| **shareGroupRequest** | **ShareGroupRequest** | | | + +### Return type + +null (empty response body) + + ## unassignEntityGroupFromEdge ``` diff --git a/pe/docs/ReportTimeSeriesChartSettings.md b/pe/docs/ReportTimeSeriesChartSettings.md index 7b9dcfc9..939a0353 100644 --- a/pe/docs/ReportTimeSeriesChartSettings.md +++ b/pe/docs/ReportTimeSeriesChartSettings.md @@ -23,8 +23,8 @@ | **legendLabelColor** | **String** | | [optional] | | **legendValueFont** | **Font** | | [optional] | | **legendValueColor** | **String** | | [optional] | -| **yaxes** | **Map\** | | [optional] | | **xaxis** | **TimeSeriesChartXAxisSettings** | | [optional] | +| **yaxes** | **Map\** | | [optional] | | **thresholds** | **List\** | | [optional] | | **grid** | **TimeSeriesChartGridSettings** | | [optional] | | **yAxes** | **Map\** | | [optional] | diff --git a/pe/spec/openapi.json b/pe/spec/openapi.json index 114ab2e5..d3a29980 100644 --- a/pe/spec/openapi.json +++ b/pe/spec/openapi.json @@ -97,10 +97,6 @@ "name": "dashboard-report-controller", "description": "Dashboard Report Controller" }, - { - "name": "device-api-controller", - "description": "Device Api Controller" - }, { "name": "device-connectivity-controller", "description": "Device Connectivity Controller" @@ -29516,175 +29512,19 @@ ] } }, - "/api/v1/provision": { - "post": { - "tags": [ - "device-api-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" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "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 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 - } - } - } - } - } - } - } - } - }, - "/api/v1/{deviceToken}/attributes": { + "/api/device-connectivity/gateway-launch/{deviceId}/docker-compose/download": { "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": "Download generated docker-compose.yml file for gateway (downloadGatewayDockerCompose)", + "description": "Download generated docker-compose.yml for gateway.", + "operationId": "downloadGatewayDockerCompose", "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" @@ -29695,9 +29535,10 @@ "200": { "description": "OK", "content": { - "application/json": { + "application/octet-stream": { "schema": { - "type": "string" + "type": "string", + "format": "binary" } } } @@ -29807,44 +29648,57 @@ } } } - } - }, - "post": { + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] + } + }, + "/api/device-connectivity/{deviceId}": { + "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": "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.", + "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "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": { "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}" + } } } } @@ -29861,7 +29715,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -29954,46 +29808,44 @@ } } } - } + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] } }, - "/api/v1/{deviceToken}/attributes/updates": { + "/api/device-connectivity/{protocol}/certificate/download": { "get": { "tags": [ - "device-api-controller" + "device-connectivity-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": "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" } - }, - { - "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": { "200": { "description": "OK", "content": { - "application/json": { + "application/octet-stream": { "schema": { - "type": "string" + "type": "string", + "format": "binary" } } } @@ -30103,33 +29955,49 @@ } } } - } + }, + "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. Security check is performed to verify that the user has 'CLAIM_DEVICES' permission for the entity (entities).", + "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" } + }, + { + "name": "subCustomerId", + "in": "query", + "required": false, + "schema": { + "type": "string" + } } ], "requestBody": { "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/ClaimRequest" } } } @@ -30250,66 +30118,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. Security check is performed to verify that the user has 'CLAIM_DEVICES' permission for the entity (entities).", + "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": { @@ -30428,36 +30262,118 @@ } } } - } + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] } }, - "/api/v1/{deviceToken}/rpc": { + "/api/customer/{customerId}/deviceInfos": { "get": { "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": "Get Customer Device Infos (getCustomerDeviceInfos)", + "description": "Returns a page of device info objects owned by the specified customer. Device Info is an extension of the default Device object that contains information about the owner name. 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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "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": "timeout", + "name": "pageSize", "in": "query", - "description": "Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side.", - "required": false, + "description": "Maximum amount of entities in a one page", + "required": true, "schema": { "type": "integer", - "format": "int64", - "default": 0 + "format": "int32" + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "includeCustomers", + "in": "query", + "description": "Include customer or sub-customer entities", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "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" + ] } } ], @@ -30467,7 +30383,7 @@ "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/PageDataDeviceInfo" } } } @@ -30577,64 +30493,131 @@ } } } - } - }, - "post": { + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] + } + }, + "/api/customer/{customerId}/devices": { + "get": { "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": "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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "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" } - } - ], - "requestBody": { - "description": "The RPC request JSON", - "content": { - "application/json": { - "schema": { - "type": "string" - } + }, + { + "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": "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": { "200": { - "description": "RPC request to server was sent to Rule Engine.", + "description": "OK", "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/PageDataDevice" } } } }, "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 UUID string: 123", + "errorCode": 31, + "timestamp": 1609459200000 + } + } } } } @@ -30723,43 +30706,92 @@ } } } - } + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] } }, - "/api/v1/{deviceToken}/rpc/{requestId}": { + "/api/device": { "post": { "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": "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. Security check is performed to verify that the user has 'WRITE' permission for the entity (entities).", + "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": "requestId", - "in": "path", - "description": "RPC request id from the incoming RPC request", - "required": true, + "name": "entityGroupId", + "in": "query", + "required": false, "schema": { "type": "string" } + }, + { + "name": "entityGroupIds", + "in": "query", + "description": "A list of entity group ids, separated by comma ','", + "required": false, + "schema": { + "type": "array", + "items": { + "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": "Reply to the RPC request, JSON. For example: {\"status\":\"success\"}", + "description": "A JSON value representing the device.", "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/Device" } } }, @@ -30767,31 +30799,32 @@ }, "responses": { "200": { - "description": "RPC reply to command request was sent to Core.", + "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 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 request body", + "errorCode": 31, + "timestamp": 1609459200000 + } + } } } } @@ -30880,75 +30913,94 @@ } } } - } + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] } }, - "/api/v1/{deviceToken}/software": { - "get": { + "/api/device-with-credentials": { + "post": { "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": "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\":\"5636aba0-1022-11ee-9631-51fb57f69174\",\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. Security check is performed to verify that the user has 'WRITE' permission for the entity (entities).", + "operationId": "saveDeviceWithCredentials", "parameters": [ { - "name": "deviceToken", - "in": "path", - "description": "Your device access token.", - "required": true, + "name": "entityGroupId", + "in": "query", + "required": false, "schema": { "type": "string" } }, { - "name": "title", + "name": "entityGroupIds", "in": "query", - "description": "Title of the software, corresponds to the value of 'sw_title' attribute.", - "required": true, + "description": "A list of entity group ids, separated by comma ','", + "required": false, "schema": { - "type": "string" + "type": "array", + "items": { + "type": "string" + } } }, { - "name": "version", + "name": "nameConflictPolicy", "in": "query", - "description": "Version of the software, corresponds to the value of 'sw_version' attribute.", - "required": true, + "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": "size", + "name": "uniquifySeparator", "in": "query", - "description": "Size of the chunk. Optional. Omit to download the entire file without using chunks.", + "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": "integer", - "format": "int32", - "default": 0 + "type": "string", + "default": "_" } }, { - "name": "chunk", + "name": "uniquifyStrategy", "in": "query", - "description": "Index of the chunk. Optional. Omit to download the entire file without using chunks.", + "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": "integer", - "format": "int32", - "default": 0 + "$ref": "#/components/schemas/UniquifyStrategy", + "default": "RANDOM" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SaveDeviceWithCredentialsRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/Device" } } } @@ -30965,7 +31017,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -31058,33 +31110,30 @@ } } } - } + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] } }, - "/api/v1/{deviceToken}/telemetry": { + "/api/device/bulk_import": { "post": { "tags": [ - "device-api-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", - "parameters": [ - { - "name": "deviceToken", - "in": "path", - "description": "Your device access token.", - "required": true, - "schema": { - "type": "string" - } - } + "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. Security check is performed to verify that the user has 'WRITE' permission for the entity (entities).", + "operationId": "processDevicesBulkImport", "requestBody": { "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/BulkImportRequest" } } }, @@ -31096,7 +31145,7 @@ "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/BulkImportResultDevice" } } } @@ -31206,36 +31255,42 @@ } } } - } + }, + "security": [ + { + "HttpLoginForm": [] + }, + { + "ApiKeyForm": [] + } + ] } }, - "/api/device-connectivity/gateway-launch/{deviceId}/docker-compose/download": { - "get": { + "/api/device/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", - "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": "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" } } } @@ -31252,7 +31307,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -31356,14 +31411,14 @@ ] } }, - "/api/device-connectivity/{deviceId}": { + "/api/device/info/{deviceId}": { "get": { "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", + "summary": "Get Device (getDeviceInfoById)", + "description": "Fetch the Device info object based on the provided Device Id. Device Info is an extension of the default Device object that contains information about the owner name. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "getDeviceInfoById", "parameters": [ { "name": "deviceId", @@ -31381,919 +31436,7 @@ "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}" - } - } - } - } - }, - "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/device-connectivity/{protocol}/certificate/download": { - "get": { - "tags": [ - "device-connectivity-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" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/octet-stream": { - "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/customer/device/{deviceName}/claim": { - "post": { - "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. Security check is performed to verify that the user has 'CLAIM_DEVICES' permission for the entity (entities).", - "operationId": "claimDevice", - "parameters": [ - { - "name": "deviceName", - "in": "path", - "description": "Unique name of the device which is going to be claimed", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "subCustomerId", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ClaimRequest" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "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 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": [ - "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. Security check is performed to verify that the user has 'CLAIM_DEVICES' permission for the entity (entities).", - "operationId": "reClaimDevice", - "parameters": [ - { - "name": "deviceName", - "in": "path", - "description": "Unique name of the device which is going to be reclaimed", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "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 - } - } - } - } - } - }, - "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/customer/{customerId}/deviceInfos": { - "get": { - "tags": [ - "device-controller" - ], - "summary": "Get Customer Device Infos (getCustomerDeviceInfos)", - "description": "Returns a page of device info objects owned by the specified customer. Device Info is an extension of the default Device object that contains information about the owner name. 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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getCustomerDeviceInfos", - "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": "includeCustomers", - "in": "query", - "description": "Include customer or sub-customer entities", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "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": { - "$ref": "#/components/schemas/PageDataDeviceInfo" - } - } - } - }, - "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/customer/{customerId}/devices": { - "get": { - "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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "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" - ] - } - }, - { - "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/PageDataDevice" + "$ref": "#/components/schemas/DeviceInfo" } } } @@ -32414,290 +31557,24 @@ ] } }, - "/api/device": { - "post": { - "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. Security check is performed to verify that the user has 'WRITE' permission for the entity (entities).", - "operationId": "saveDevice", - "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": "entityGroupId", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "entityGroupIds", - "in": "query", - "description": "A list of entity group ids, separated by comma ','", - "required": false, - "schema": { - "type": "array", - "items": { - "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": { - "$ref": "#/components/schemas/Device" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$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/device-with-credentials": { - "post": { + "/api/device/types": { + "get": { "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\":\"5636aba0-1022-11ee-9631-51fb57f69174\",\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. Security check is performed to verify that the user has 'WRITE' permission for the entity (entities).", - "operationId": "saveDeviceWithCredentials", - "parameters": [ - { - "name": "entityGroupId", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "entityGroupIds", - "in": "query", - "description": "A list of entity group ids, separated by comma ','", - "required": false, - "schema": { - "type": "array", - "items": { - "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": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SaveDeviceWithCredentialsRequest" - } - } - }, - "required": true - }, + "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": { - "$ref": "#/components/schemas/Device" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntitySubtype" + } } } } @@ -32714,7 +31591,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -32808,6 +31685,7 @@ } } }, + "deprecated": true, "security": [ { "HttpLoginForm": [] @@ -32818,31 +31696,32 @@ ] } }, - "/api/device/bulk_import": { - "post": { + "/api/device/{deviceId}": { + "get": { "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. Security check is performed to verify that the user has 'WRITE' permission for the entity (entities).", - "operationId": "processDevicesBulkImport", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BulkImportRequest" - } + "summary": "Get Device (getDeviceById)", + "description": "Fetch the Device object based on the provided Device Id. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "getDeviceById", + "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": { "schema": { - "$ref": "#/components/schemas/BulkImportResultDevice" + "$ref": "#/components/schemas/Device" } } } @@ -32859,7 +31738,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -32961,36 +31840,28 @@ "ApiKeyForm": [] } ] - } - }, - "/api/device/credentials": { - "post": { + }, + "delete": { "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": "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' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'DELETE' permission for the entity (entities).", + "operationId": "deleteDevice", + "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": { - "schema": { - "$ref": "#/components/schemas/DeviceCredentials" - } - } - } + "description": "OK" }, "400": { "description": "Bad Request", @@ -33004,7 +31875,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -33108,14 +31979,14 @@ ] } }, - "/api/device/info/{deviceId}": { + "/api/device/{deviceId}/credentials": { "get": { "tags": [ "device-controller" ], - "summary": "Get Device (getDeviceInfoById)", - "description": "Fetch the Device info object based on the provided Device Id. Device Info is an extension of the default Device object that contains information about the owner name. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getDeviceInfoById", + "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. Security check is performed to verify that the user has 'READ_CREDENTIALS' permission for the entity (entities).", + "operationId": "getDeviceCredentialsByDeviceId", "parameters": [ { "name": "deviceId", @@ -33133,7 +32004,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeviceInfo" + "$ref": "#/components/schemas/DeviceCredentials" } } } @@ -33254,24 +32125,108 @@ ] } }, - "/api/device/types": { + "/api/deviceInfos/all": { "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 All Device Infos for current user (getAllDeviceInfos)", + "description": "Returns a page of device info objects owned by the tenant or the customer of a current user. Device Info is an extension of the default Device object that contains information about the owner name. 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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "getAllDeviceInfos", + "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": "includeCustomers", + "in": "query", + "description": "Include customer or sub-customer entities", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "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" } } } @@ -33382,7 +32337,6 @@ } } }, - "deprecated": true, "security": [ { "HttpLoginForm": [] @@ -33393,22 +32347,25 @@ ] } }, - "/api/device/{deviceId}": { + "/api/devices": { "get": { "tags": [ "device-controller" ], - "summary": "Get Device (getDeviceById)", - "description": "Fetch the Device object based on the provided Device Id. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getDeviceById", + "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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "getDevicesByIds", "parameters": [ { - "name": "deviceId", - "in": "path", - "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "name": "deviceIds", + "in": "query", + "description": "A list of devices ids, separated by comma ','", "required": true, "schema": { - "type": "string" + "type": "array", + "items": { + "type": "string" + } } } ], @@ -33418,7 +32375,10 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Device" + "type": "array", + "items": { + "$ref": "#/components/schemas/Device" + } } } } @@ -33538,27 +32498,36 @@ } ] }, - "delete": { + "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' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'DELETE' permission for the entity (entities).", - "operationId": "deleteDevice", - "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": "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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "findDevicesByQuery", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceSearchQuery" + } } - } - ], + }, + "required": true + }, "responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Device" + } + } + } + } }, "400": { "description": "Bad Request", @@ -33572,7 +32541,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -33676,19 +32645,32 @@ ] } }, - "/api/device/{deviceId}/credentials": { + "/api/devices/count/{otaPackageType}/{deviceProfileId}": { "get": { "tags": [ "device-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. Security check is performed to verify that the user has 'READ_CREDENTIALS' permission for the entity (entities).", - "operationId": "getDeviceCredentialsByDeviceId", + "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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "countByDeviceProfileAndEmptyOtaPackage", "parameters": [ { - "name": "deviceId", + "name": "otaPackageType", "in": "path", - "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "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, "schema": { "type": "string" @@ -33701,7 +32683,8 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeviceCredentials" + "type": "integer", + "format": "int64" } } } @@ -33822,99 +32805,43 @@ ] } }, - "/api/deviceInfos/all": { + "/api/devices/count/{otaPackageType}/{otaPackageId}/{entityGroupId}": { "get": { "tags": [ "device-controller" ], - "summary": "Get All Device Infos for current user (getAllDeviceInfos)", - "description": "Returns a page of device info objects owned by the tenant or the customer of a current user. Device Info is an extension of the default Device object that contains information about the owner name. 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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getAllDeviceInfos", + "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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "countByDeviceGroupAndEmptyOtaPackage", "parameters": [ { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", + "name": "otaPackageType", + "in": "path", + "description": "OTA package type", "required": true, "schema": { - "type": "integer", - "format": "int32" + "type": "string", + "enum": [ + "FIRMWARE", + "SOFTWARE" + ] } }, { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", + "name": "otaPackageId", + "in": "path", "required": true, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "includeCustomers", - "in": "query", - "description": "Include customer or sub-customer entities", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "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, + "name": "entityGroupId", + "in": "path", + "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": { @@ -33923,7 +32850,8 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataDeviceInfo" + "type": "integer", + "format": "int64" } } } @@ -34044,25 +32972,80 @@ ] } }, - "/api/devices": { + "/api/entityGroup/{entityGroupId}/devices": { "get": { "tags": [ "device-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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getDevicesByIds", + "summary": "Get devices by Entity Group Id (getDevicesByEntityGroupId)", + "description": "Returns a page of Device objects that belongs to specified Entity Group Id. 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. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getDevicesByEntityGroupId", "parameters": [ { - "name": "deviceIds", + "name": "entityGroupId", + "in": "path", + "description": "A string value representing the Entity Group Id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "pageSize", "in": "query", - "description": "A list of devices ids, separated by comma ','", + "description": "Maximum amount of entities in a one page", "required": true, "schema": { - "type": "array", - "items": { - "type": "string" - } + "type": "string", + "minimum": 1 + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "string", + "minimum": 0 + } + }, + { + "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" + ] } } ], @@ -34072,10 +33055,7 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Device" - } + "$ref": "#/components/schemas/PageDataDevice" } } } @@ -34194,34 +33174,34 @@ "ApiKeyForm": [] } ] - }, - "post": { + } + }, + "/api/tenant/device": { + "get": { "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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "findDevicesByQuery", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeviceSearchQuery" - } + "summary": "Get Tenant Device (getTenantDevice)", + "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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "getTenantDeviceByName", + "parameters": [ + { + "name": "deviceName", + "in": "query", + "description": "A string value representing the Device name.", + "required": true, + "schema": { + "type": "string" } - }, - "required": true - }, + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Device" - } + "$ref": "#/components/schemas/Device" } } } @@ -34238,7 +33218,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -34342,35 +33322,80 @@ ] } }, - "/api/devices/count/{otaPackageType}/{deviceProfileId}": { + "/api/tenant/devices": { "get": { "tags": [ "device-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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "countByDeviceProfileAndEmptyOtaPackage", + "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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "getTenantDevices", "parameters": [ { - "name": "otaPackageType", - "in": "path", - "description": "OTA package type", + "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": [ - "FIRMWARE", - "SOFTWARE" + "createdTime", + "name", + "deviceProfileName", + "label", + "customerTitle" ] } }, { - "name": "deviceProfileId", - "in": "path", - "description": "Device Profile Id. I.g. '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, "schema": { - "type": "string" + "type": "string", + "enum": [ + "ASC", + "DESC" + ] } } ], @@ -34380,8 +33405,7 @@ "content": { "application/json": { "schema": { - "type": "integer", - "format": "int64" + "$ref": "#/components/schemas/PageDataDevice" } } } @@ -34502,39 +33526,28 @@ ] } }, - "/api/devices/count/{otaPackageType}/{otaPackageId}/{entityGroupId}": { - "get": { + "/api/tenant/{tenantId}/device/{deviceId}": { + "post": { "tags": [ "device-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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "countByDeviceGroupAndEmptyOtaPackage", + "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. Security check is performed to verify that the user has 'ASSIGN_TO_TENANT' permission for the entity (entities).", + "operationId": "assignDeviceToTenant", "parameters": [ { - "name": "otaPackageType", - "in": "path", - "description": "OTA package type", - "required": true, - "schema": { - "type": "string", - "enum": [ - "FIRMWARE", - "SOFTWARE" - ] - } - }, - { - "name": "otaPackageId", + "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": "entityGroupId", + "name": "deviceId", "in": "path", + "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" @@ -34547,8 +33560,7 @@ "content": { "application/json": { "schema": { - "type": "integer", - "format": "int64" + "$ref": "#/components/schemas/Device" } } } @@ -34565,7 +33577,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -34669,24 +33681,15 @@ ] } }, - "/api/entityGroup/{entityGroupId}/devices": { + "/api/user/devices": { "get": { "tags": [ "device-controller" ], - "summary": "Get devices by Entity Group Id (getDevicesByEntityGroupId)", - "description": "Returns a page of Device objects that belongs to specified Entity Group Id. 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. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getDevicesByEntityGroupId", + "summary": "Get Devices (getUserDevices)", + "description": "Returns a page of devices that are available for the current user. 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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "getUserDevices", "parameters": [ - { - "name": "entityGroupId", - "in": "path", - "description": "A string value representing the Entity Group Id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, { "name": "pageSize", "in": "query", @@ -34707,6 +33710,15 @@ "minimum": 0 } }, + { + "name": "type", + "in": "query", + "description": "Device type as the name of the device profile", + "required": false, + "schema": { + "type": "string" + } + }, { "name": "textSearch", "in": "query", @@ -34873,236 +33885,30 @@ ] } }, - "/api/tenant/device": { - "get": { - "tags": [ - "device-controller" - ], - "summary": "Get Tenant Device (getTenantDevice)", - "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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getTenantDeviceByName", - "parameters": [ - { - "name": "deviceName", - "in": "query", - "description": "A string value representing the Device name.", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$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 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/devices": { - "get": { + "/api/deviceGroupOtaPackage": { + "post": { "tags": [ - "device-controller" + "device-group-ota-package-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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getTenantDevices", - "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": "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": "saveDeviceGroupOtaPackage", + "operationId": "saveDeviceGroupOtaPackage", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceGroupOtaPackage" + } } }, - { - "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" + "$ref": "#/components/schemas/DeviceGroupOtaPackage" } } } @@ -35119,7 +33925,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -35223,28 +34029,25 @@ ] } }, - "/api/tenant/{tenantId}/device/{deviceId}": { - "post": { + "/api/deviceGroupOtaPackage/{groupId}/{firmwareType}": { + "get": { "tags": [ - "device-controller" + "device-group-ota-package-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. Security check is performed to verify that the user has 'ASSIGN_TO_TENANT' permission for the entity (entities).", - "operationId": "assignDeviceToTenant", + "summary": "getFirmwareById", + "operationId": "getFirmwareById", "parameters": [ { - "name": "tenantId", + "name": "groupId", "in": "path", - "description": "A string value representing the tenant id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" } }, { - "name": "deviceId", + "name": "firmwareType", "in": "path", - "description": "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" @@ -35257,7 +34060,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Device" + "$ref": "#/components/schemas/DeviceGroupOtaPackage" } } } @@ -35274,7 +34077,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -35378,93 +34181,26 @@ ] } }, - "/api/user/devices": { - "get": { + "/api/deviceGroupOtaPackage/{id}": { + "delete": { "tags": [ - "device-controller" + "device-group-ota-package-controller" ], - "summary": "Get Devices (getUserDevices)", - "description": "Returns a page of devices that are available for the current user. 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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getUserDevices", + "summary": "deleteDeviceGroupOtaPackage", + "operationId": "deleteDeviceGroupOtaPackage", "parameters": [ { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "string", - "minimum": 1 - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", + "name": "id", + "in": "path", "required": true, - "schema": { - "type": "string", - "minimum": 0 - } - }, - { - "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": { "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PageDataDevice" - } - } - } + "description": "OK" }, "400": { "description": "Bad Request", @@ -35582,18 +34318,19 @@ ] } }, - "/api/deviceGroupOtaPackage": { + "/api/deviceProfile": { "post": { "tags": [ - "device-group-ota-package-controller" + "device-profile-controller" ], - "summary": "saveDeviceGroupOtaPackage", - "operationId": "saveDeviceGroupOtaPackage", + "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/DeviceGroupOtaPackage" + "$ref": "#/components/schemas/DeviceProfile" } } }, @@ -35605,7 +34342,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeviceGroupOtaPackage" + "$ref": "#/components/schemas/DeviceProfile" } } } @@ -35726,26 +34463,20 @@ ] } }, - "/api/deviceGroupOtaPackage/{groupId}/{firmwareType}": { + "/api/deviceProfile/devices/keys/attributes": { "get": { "tags": [ - "device-group-ota-package-controller" + "device-profile-controller" ], - "summary": "getFirmwareById", - "operationId": "getFirmwareById", + "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": "groupId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "firmwareType", - "in": "path", - "required": true, + "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" } @@ -35757,7 +34488,10 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeviceGroupOtaPackage" + "type": "array", + "items": { + "type": "string" + } } } } @@ -35878,18 +34612,20 @@ ] } }, - "/api/deviceGroupOtaPackage/{id}": { - "delete": { + "/api/deviceProfile/devices/keys/timeseries": { + "get": { "tags": [ - "device-group-ota-package-controller" + "device-profile-controller" ], - "summary": "deleteDeviceGroupOtaPackage", - "operationId": "deleteDeviceGroupOtaPackage", + "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": "id", - "in": "path", - "required": true, + "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" } @@ -35897,7 +34633,17 @@ ], "responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } }, "400": { "description": "Bad Request", @@ -36015,31 +34761,36 @@ ] } }, - "/api/deviceProfile": { - "post": { + "/api/deviceProfile/names": { + "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 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": "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": "boolean", + "default": false } - }, - "required": true - }, + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeviceProfile" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityInfo" + } } } } @@ -36056,7 +34807,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -36160,23 +34911,32 @@ ] } }, - "/api/deviceProfile/devices/keys/attributes": { + "/api/deviceProfile/{deviceProfileId}": { "get": { "tags": [ "device-profile-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": "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": "deviceProfileId", - "in": "query", + "in": "path", "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": false, + "required": true, "schema": { "type": "string" } + }, + { + "name": "inlineImages", + "in": "query", + "description": "Inline images as a data URL (Base64)", + "required": false, + "schema": { + "type": "boolean" + } } ], "responses": { @@ -36185,10 +34945,7 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "type": "string" - } + "$ref": "#/components/schemas/DeviceProfile" } } } @@ -36307,22 +35064,20 @@ "ApiKeyForm": [] } ] - } - }, - "/api/deviceProfile/devices/keys/timeseries": { - "get": { + }, + "delete": { "tags": [ "device-profile-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": "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": "deviceProfileId", - "in": "query", + "in": "path", "description": "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": false, + "required": true, "schema": { "type": "string" } @@ -36330,17 +35085,7 @@ ], "responses": { "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - } - } + "description": "OK" }, "400": { "description": "Bad Request", @@ -36458,23 +35203,22 @@ ] } }, - "/api/deviceProfile/names": { - "get": { + "/api/deviceProfile/{deviceProfileId}/default": { + "post": { "tags": [ "device-profile-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": "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": "activeOnly", - "in": "query", - "description": "Flag indicating whether to retrieve exclusively the names of device profiles that are referenced by tenant's devices.", - "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": "boolean", - "default": false + "type": "string" } } ], @@ -36484,10 +35228,7 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityInfo" - } + "$ref": "#/components/schemas/DeviceProfile" } } } @@ -36504,7 +35245,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -36608,181 +35349,24 @@ ] } }, - "/api/deviceProfile/{deviceProfileId}": { + "/api/deviceProfileInfo/default": { "get": { "tags": [ "device-profile-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", - "parameters": [ - { - "name": "deviceProfileId", - "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" - } - } - ], + "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/DeviceProfile" - } - } - } - }, - "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/DeviceProfileInfo" } } } - } - }, - "security": [ - { - "HttpLoginForm": [] - }, - { - "ApiKeyForm": [] - } - ] - }, - "delete": { - "tags": [ - "device-profile-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", - "parameters": [ - { - "name": "deviceProfileId", - "in": "path", - "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" }, "400": { "description": "Bad Request", @@ -36900,14 +35484,14 @@ ] } }, - "/api/deviceProfile/{deviceProfileId}/default": { - "post": { + "/api/deviceProfileInfo/{deviceProfileId}": { + "get": { "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", + "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": "deviceProfileId", @@ -36925,7 +35509,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeviceProfile" + "$ref": "#/components/schemas/DeviceProfileInfo" } } } @@ -36942,7 +35526,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -37046,21 +35630,98 @@ ] } }, - "/api/deviceProfileInfo/default": { + "/api/deviceProfileInfos": { "get": { "tags": [ "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", + "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", + "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 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" + ] + } + }, + { + "name": "transportType", + "in": "query", + "description": "Type of the transport", + "required": false, + "schema": { + "type": "string", + "enum": [ + "DEFAULT", + "MQTT", + "COAP", + "LWM2M", + "SNMP" + ] + } + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeviceProfileInfo" + "$ref": "#/components/schemas/PageDataDeviceProfileInfo" } } } @@ -37181,22 +35842,25 @@ ] } }, - "/api/deviceProfileInfo/{deviceProfileId}": { + "/api/deviceProfileInfos/list": { "get": { "tags": [ "device-profile-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": "Get Device Profile Infos By Ids (getDeviceProfileInfosByIds)", + "description": "Requested device profiles must be owned by tenant which is performing the request. \n\n Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "getDeviceProfileInfosByIds", "parameters": [ { - "name": "deviceProfileId", - "in": "path", - "description": "A string value representing the device profile 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" + } } } ], @@ -37206,7 +35870,10 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeviceProfileInfo" + "type": "array", + "items": { + "$ref": "#/components/schemas/DeviceProfileInfo" + } } } } @@ -37327,14 +35994,14 @@ ] } }, - "/api/deviceProfileInfos": { + "/api/deviceProfiles": { "get": { "tags": [ "device-profile-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 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", @@ -37394,22 +36061,6 @@ "DESC" ] } - }, - { - "name": "transportType", - "in": "query", - "description": "Type of the transport", - "required": false, - "schema": { - "type": "string", - "enum": [ - "DEFAULT", - "MQTT", - "COAP", - "LWM2M", - "SNMP" - ] - } } ], "responses": { @@ -37418,7 +36069,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataDeviceProfileInfo" + "$ref": "#/components/schemas/PageDataDeviceProfile" } } } @@ -37539,20 +36190,20 @@ ] } }, - "/api/deviceProfileInfos/list": { - "get": { + "/api/domain": { + "post": { "tags": [ - "device-profile-controller" + "domain-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 Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getDeviceProfileInfosByIds", + "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' or 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "saveDomain", "parameters": [ { - "name": "deviceProfileIds", + "name": "oauth2ClientIds", "in": "query", - "description": "A list of device profile ids, separated by comma ','", - "required": true, + "description": "A list of oauth2 client registration ids, separated by comma ','", + "required": false, "schema": { "type": "array", "items": { @@ -37561,16 +36212,23 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Domain" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/DeviceProfileInfo" - } + "$ref": "#/components/schemas/Domain" } } } @@ -37587,7 +36245,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -37691,72 +36349,22 @@ ] } }, - "/api/deviceProfiles": { + "/api/domain/info/{id}": { "get": { "tags": [ - "device-profile-controller" + "domain-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 Domain info by Id (getDomainInfoById)", + "description": "\n\nAvailable for users with 'SYS_ADMIN' or 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getDomainInfoById", "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": "id", + "in": "path", "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" - ] + "format": "uuid" } } ], @@ -37766,7 +36374,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataDeviceProfile" + "$ref": "#/components/schemas/DomainInfo" } } } @@ -37887,45 +36495,70 @@ ] } }, - "/api/domain": { - "post": { + "/api/domain/infos": { + "get": { "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' or 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "saveDomain", + "summary": "Get Domain infos (getDomainInfos)", + "description": "\n\nAvailable for users with 'SYS_ADMIN' or 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "getDomainInfos", "parameters": [ { - "name": "oauth2ClientIds", + "name": "pageSize", "in": "query", - "description": "A list of oauth2 client registration ids, separated by comma ','", + "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": "array", - "items": { - "type": "string" - } + "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Domain" - } + }, + { + "name": "sortProperty", + "in": "query", + "description": "Property of entity to sort by", + "required": false, + "schema": { + "type": "string" } }, - "required": true - }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "required": false, + "schema": { + "type": "string" + } + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Domain" + "$ref": "#/components/schemas/PageDataDomainInfo" } } } @@ -37942,7 +36575,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -38046,14 +36679,14 @@ ] } }, - "/api/domain/info/{id}": { - "get": { + "/api/domain/{id}": { + "delete": { "tags": [ "domain-controller" ], - "summary": "Get Domain info by Id (getDomainInfoById)", - "description": "\n\nAvailable for users with 'SYS_ADMIN' or 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getDomainInfoById", + "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' or 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "deleteDomain", "parameters": [ { "name": "id", @@ -38067,14 +36700,7 @@ ], "responses": { "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DomainInfo" - } - } - } + "description": "OK" }, "400": { "description": "Bad Request", @@ -38192,74 +36818,43 @@ ] } }, - "/api/domain/infos": { - "get": { + "/api/domain/{id}/oauth2Clients": { + "put": { "tags": [ "domain-controller" ], - "summary": "Get Domain infos (getDomainInfos)", - "description": "\n\nAvailable for users with 'SYS_ADMIN' or 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "getDomainInfos", + "summary": "Update oauth2 clients (updateOauth2Clients)", + "description": "Update oauth2 clients for the specified domain. \n\nAvailable for users with 'SYS_ADMIN' or 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", + "operationId": "updateOauth2Clients", "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": "id", + "in": "path", "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" + "type": "string", + "format": "uuid" } } ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PageDataDomainInfo" + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" } } } }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, "400": { "description": "Bad Request", "content": { @@ -38376,28 +36971,111 @@ ] } }, - "/api/domain/{id}": { - "delete": { + "/api/customer/{customerId}/edgeInfos": { + "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' or 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "deleteDomain", + "summary": "Get Customer Edge Infos (getCustomerEdgeInfos)", + "description": "Returns a page of edge info objects owned by the specified 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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "getCustomerEdgeInfos", "parameters": [ { - "name": "id", + "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": "includeCustomers", + "in": "query", + "description": "Include customer or sub-customer entities", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "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", - "format": "uuid" + "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" + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageDataEdgeInfo" + } + } + } }, "400": { "description": "Bad Request", @@ -38515,43 +37193,103 @@ ] } }, - "/api/domain/{id}/oauth2Clients": { - "put": { + "/api/customer/{customerId}/edges": { + "get": { "tags": [ - "domain-controller" + "edge-controller" ], - "summary": "Update oauth2 clients (updateOauth2Clients)", - "description": "Update oauth2 clients for the specified domain. \n\nAvailable for users with 'SYS_ADMIN' or 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.", - "operationId": "updateOauth2Clients", + "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": "id", + "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": "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", - "format": "uuid" + "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" + ] } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "string", - "format": "uuid" + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageDataEdge" } } } }, - "required": true - }, - "responses": { - "200": { - "description": "OK" - }, "400": { "description": "Bad Request", "content": { @@ -38668,108 +37406,53 @@ ] } }, - "/api/customer/{customerId}/edgeInfos": { - "get": { + "/api/edge": { + "post": { "tags": [ "edge-controller" ], - "summary": "Get Customer Edge Infos (getCustomerEdgeInfos)", - "description": "Returns a page of edge info objects owned by the specified 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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getCustomerEdgeInfos", + "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. ", + "operationId": "saveEdge", "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": "includeCustomers", - "in": "query", - "description": "Include customer or sub-customer entities", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "name": "type", - "in": "query", - "description": "A string value representing the edge type. For example, 'default'", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "textSearch", + "name": "entityGroupId", "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", + "name": "entityGroupIds", "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", + "description": "A list of entity group ids, separated by comma ','", "required": false, "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] + "type": "array", + "items": { + "type": "string" + } } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edge" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEdgeInfo" + "$ref": "#/components/schemas/Edge" } } } @@ -38786,7 +37469,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -38890,99 +37573,31 @@ ] } }, - "/api/customer/{customerId}/edges": { - "get": { + "/api/edge/bulk_import": { + "post": { "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", - "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": "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": "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' or 'CUSTOMER_USER' authority.", + "operationId": "processEdgesBulkImport", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkImportRequest" + } } }, - { - "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" + "$ref": "#/components/schemas/BulkImportResultEdge" } } } @@ -38999,7 +37614,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -39103,53 +37718,32 @@ ] } }, - "/api/edge": { - "post": { + "/api/edge/info/{edgeId}": { + "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. ", - "operationId": "saveEdge", + "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": "entityGroupId", - "in": "query", - "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" } - }, - { - "name": "entityGroupIds", - "in": "query", - "description": "A list of entity group ids, separated by comma ','", - "required": false, - "schema": { - "type": "array", - "items": { - "type": "string" - } - } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Edge" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Edge" + "$ref": "#/components/schemas/EdgeInfo" } } } @@ -39166,7 +37760,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -39270,31 +37864,46 @@ ] } }, - "/api/edge/bulk_import": { - "post": { + "/api/edge/instructions/install/{edgeId}/{method}": { + "get": { "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' or 'CUSTOMER_USER' authority.", - "operationId": "processEdgesBulkImport", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BulkImportRequest" - } + "summary": "Get Edge Install Instructions (getEdgeInstallInstructions)", + "description": "Get an install instructions for 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": "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" } }, - "required": true - }, + { + "name": "method", + "in": "path", + "description": "Installation method ('docker', 'ubuntu' or 'centos')", + "required": true, + "schema": { + "type": "string", + "enum": [ + "docker", + "ubuntu", + "centos" + ] + } + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BulkImportResultEdge" + "$ref": "#/components/schemas/EdgeInstructions" } } } @@ -39311,7 +37920,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -39415,23 +38024,37 @@ ] } }, - "/api/edge/info/{edgeId}": { + "/api/edge/instructions/upgrade/{edgeVersion}/{method}": { "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 Edge Upgrade Instructions (getEdgeUpgradeInstructions)", + "description": "Get an upgrade instructions for provided edge version.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": "getEdgeUpgradeInstructions", "parameters": [ { - "name": "edgeId", + "name": "edgeVersion", "in": "path", - "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "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" + ] + } } ], "responses": { @@ -39440,7 +38063,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EdgeInfo" + "$ref": "#/components/schemas/EdgeInstructions" } } } @@ -39561,14 +38184,14 @@ ] } }, - "/api/edge/instructions/install/{edgeId}/{method}": { + "/api/edge/missingToRelatedRuleChains/{edgeId}": { "get": { "tags": [ "edge-controller" ], - "summary": "Get Edge Install Instructions (getEdgeInstallInstructions)", - "description": "Get an install instructions for 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": "getEdgeInstallInstructions", + "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", @@ -39578,20 +38201,6 @@ "schema": { "type": "string" } - }, - { - "name": "method", - "in": "path", - "description": "Installation method ('docker', 'ubuntu' or 'centos')", - "required": true, - "schema": { - "type": "string", - "enum": [ - "docker", - "ubuntu", - "centos" - ] - } } ], "responses": { @@ -39600,7 +38209,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EdgeInstructions" + "type": "string" } } } @@ -39721,37 +38330,23 @@ ] } }, - "/api/edge/instructions/upgrade/{edgeVersion}/{method}": { - "get": { + "/api/edge/sync/{edgeId}": { + "post": { "tags": [ "edge-controller" ], - "summary": "Get Edge Upgrade Instructions (getEdgeUpgradeInstructions)", - "description": "Get an upgrade instructions for provided edge version.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": "getEdgeUpgradeInstructions", + "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": "edgeVersion", + "name": "edgeId", "in": "path", - "description": "Edge version", + "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": "Upgrade method ('docker', 'ubuntu' or 'centos')", - "required": true, - "schema": { - "type": "string", - "enum": [ - "docker", - "ubuntu", - "centos" - ] - } } ], "responses": { @@ -39760,7 +38355,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EdgeInstructions" + "type": "string" } } } @@ -39777,7 +38372,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -39881,32 +38476,24 @@ ] } }, - "/api/edge/missingToRelatedRuleChains/{edgeId}": { + "/api/edge/types": { "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", - "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 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": { - "type": "string" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntitySubtype" + } } } } @@ -40027,14 +38614,14 @@ ] } }, - "/api/edge/sync/{edgeId}": { - "post": { + "/api/edge/{edgeId}": { + "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 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": "edgeId", @@ -40052,145 +38639,7 @@ "content": { "application/json": { "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 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/edge/types": { - "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", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntitySubtype" - } + "$ref": "#/components/schemas/Edge" } } } @@ -40309,16 +38758,14 @@ "ApiKeyForm": [] } ] - } - }, - "/api/edge/{edgeId}": { - "get": { + }, + "delete": { "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": "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": "edgeId", @@ -40332,14 +38779,7 @@ ], "responses": { "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Edge" - } - } - } + "description": "OK" }, "400": { "description": "Bad Request", @@ -40455,14 +38895,16 @@ "ApiKeyForm": [] } ] - }, - "delete": { + } + }, + "/api/edge/{edgeId}/upgrade/available": { + "get": { "tags": [ "edge-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": "Is edge upgrade enabled (isEdgeUpgradeAvailable)", + "description": "Returns 'true' if upgrade available for connected edge, 'false' - otherwise.", + "operationId": "isEdgeUpgradeAvailable", "parameters": [ { "name": "edgeId", @@ -40476,7 +38918,14 @@ ], "responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } }, "400": { "description": "Bad Request", @@ -40594,14 +39043,14 @@ ] } }, - "/api/edge/{edgeId}/upgrade/available": { - "get": { + "/api/edge/{edgeId}/{ruleChainId}/root": { + "post": { "tags": [ "edge-controller" ], - "summary": "Is edge upgrade enabled (isEdgeUpgradeAvailable)", - "description": "Returns 'true' if upgrade available for connected edge, 'false' - otherwise.", - "operationId": "isEdgeUpgradeAvailable", + "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", @@ -40611,6 +39060,15 @@ "schema": { "type": "string" } + }, + { + "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": { @@ -40619,7 +39077,7 @@ "content": { "application/json": { "schema": { - "type": "boolean" + "$ref": "#/components/schemas/Edge" } } } @@ -40636,7 +39094,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -40740,32 +39198,90 @@ ] } }, - "/api/edge/{edgeId}/{ruleChainId}/root": { - "post": { + "/api/edgeInfos/all": { + "get": { "tags": [ "edge-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": "Get All Edge Infos for current user (getAllEdgeInfos)", + "description": "Returns a page of edge info objects owned by the tenant or the customer of a current user. 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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "getAllEdgeInfos", "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": "string" + "type": "integer", + "format": "int32" } }, { - "name": "ruleChainId", - "in": "path", - "description": "A string value representing the rule chain id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "includeCustomers", + "in": "query", + "description": "Include customer or sub-customer entities", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "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": { @@ -40774,7 +39290,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Edge" + "$ref": "#/components/schemas/PageDataEdgeInfo" } } } @@ -40791,7 +39307,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -40895,14 +39411,14 @@ ] } }, - "/api/edgeInfos/all": { + "/api/edges": { "get": { "tags": [ "edge-controller" ], - "summary": "Get All Edge Infos for current user (getAllEdgeInfos)", - "description": "Returns a page of edge info objects owned by the tenant or the customer of a current user. 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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getAllEdgeInfos", + "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", @@ -40924,24 +39440,6 @@ "format": "int32" } }, - { - "name": "includeCustomers", - "in": "query", - "description": "Include customer or sub-customer entities", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "name": "type", - "in": "query", - "description": "A string value representing the edge type. For example, 'default'", - "required": false, - "schema": { - "type": "string" - } - }, { "name": "textSearch", "in": "query", @@ -40987,7 +39485,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEdgeInfo" + "$ref": "#/components/schemas/PageDataEdge" } } } @@ -41106,83 +39604,34 @@ "ApiKeyForm": [] } ] - } - }, - "/api/edges": { - "get": { + }, + "post": { "tags": [ "edge-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": "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": "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": "array", + "items": { + "$ref": "#/components/schemas/Edge" + } } } } @@ -41199,7 +39648,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -41301,34 +39750,23 @@ "ApiKeyForm": [] } ] - }, - "post": { + } + }, + "/api/edges/enabled": { + "get": { "tags": [ "edge-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" - } - } - }, - "required": true - }, + "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": "array", - "items": { - "$ref": "#/components/schemas/Edge" - } + "type": "boolean" } } } @@ -41345,7 +39783,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -41449,21 +39887,38 @@ ] } }, - "/api/edges/enabled": { + "/api/edges/list": { "get": { "tags": [ "edge-controller" ], - "summary": "Is edges support enabled (isEdgesSupportEnabled)", - "description": "Returns 'true' if edges support enabled on server, 'false' - otherwise.", - "operationId": "isEdgesSupportEnabled", + "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": "edgeIds", + "in": "query", + "description": "A list of edges ids, separated by comma ','", + "required": true, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "boolean" + "type": "array", + "items": { + "$ref": "#/components/schemas/Edge" + } } } } @@ -41584,25 +40039,80 @@ ] } }, - "/api/edges/list": { + "/api/entityGroup/{entityGroupId}/edges": { "get": { "tags": [ "edge-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": "Get edges by Entity Group Id (getEdgesByEntityGroupId)", + "description": "Returns a page of Edge objects that belongs to specified Entity Group Id. 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. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getEdgesByEntityGroupId", "parameters": [ { - "name": "edgeIds", + "name": "entityGroupId", + "in": "path", + "description": "A string value representing the Entity Group Id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "pageSize", "in": "query", - "description": "A list of edges ids, separated by comma ','", + "description": "Maximum amount of entities in a one page", "required": true, "schema": { - "type": "array", - "items": { - "type": "string" - } + "type": "string", + "minimum": 1 + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "string", + "minimum": 1 + } + }, + { + "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" + ] } } ], @@ -41612,10 +40122,7 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Edge" - } + "$ref": "#/components/schemas/PageDataEdge" } } } @@ -41736,81 +40243,30 @@ ] } }, - "/api/entityGroup/{entityGroupId}/edges": { - "get": { + "/api/license/activateInstance": { + "post": { "tags": [ "edge-controller" ], - "summary": "Get edges by Entity Group Id (getEdgesByEntityGroupId)", - "description": "Returns a page of Edge objects that belongs to specified Entity Group Id. 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. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getEdgesByEntityGroupId", + "summary": "Activate edge instance (activateInstance)", + "description": "Activates edge license on license portal.", + "operationId": "activateInstance", "parameters": [ { - "name": "entityGroupId", - "in": "path", - "description": "A string value representing the Entity Group Id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "pageSize", + "name": "licenseSecret", "in": "query", - "description": "Maximum amount of entities in a one page", "required": true, "schema": { - "type": "string", - "minimum": 1 + "type": "string" } }, { - "name": "page", + "name": "releaseDate", "in": "query", - "description": "Sequence number of page starting from 0", "required": true, - "schema": { - "type": "string", - "minimum": 1 - } - }, - { - "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": { @@ -41819,7 +40275,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEdge" + "$ref": "#/components/schemas/JsonNode" } } } @@ -41836,7 +40292,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -41940,32 +40396,24 @@ ] } }, - "/api/license/activateInstance": { + "/api/license/checkInstance": { "post": { "tags": [ "edge-controller" ], - "summary": "Activate edge instance (activateInstance)", - "description": "Activates edge license on license portal.", - "operationId": "activateInstance", - "parameters": [ - { - "name": "licenseSecret", - "in": "query", - "required": true, - "schema": { - "type": "string" + "summary": "Check edge license (checkInstance)", + "description": "Checks license request from edge service by forwarding request to license portal.", + "operationId": "checkInstance", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JsonNode" + } } }, - { - "name": "releaseDate", - "in": "query", - "required": true, - "schema": { - "type": "string" - } - } - ], + "required": true + }, "responses": { "200": { "description": "OK", @@ -42093,31 +40541,32 @@ ] } }, - "/api/license/checkInstance": { - "post": { + "/api/tenant/edge": { + "get": { "tags": [ "edge-controller" ], - "summary": "Check edge license (checkInstance)", - "description": "Checks license request from edge service by forwarding request to license portal.", - "operationId": "checkInstance", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/JsonNode" - } + "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": "edgeName", + "in": "query", + "description": "Unique name of the edge", + "required": true, + "schema": { + "type": "string" } - }, - "required": true - }, + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/JsonNode" + "$ref": "#/components/schemas/Edge" } } } @@ -42134,7 +40583,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -42238,23 +40687,81 @@ ] } }, - "/api/tenant/edge": { + "/api/tenant/edges": { "get": { "tags": [ "edge-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 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": "edgeName", + "name": "pageSize", "in": "query", - "description": "Unique name of the edge", + "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": { @@ -42263,7 +40770,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Edge" + "$ref": "#/components/schemas/PageDataEdge" } } } @@ -42384,14 +40891,14 @@ ] } }, - "/api/tenant/edges": { + "/api/user/edges": { "get": { "tags": [ "edge-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", + "summary": "Get Edges (getUserEdges)", + "description": "Returns a page of edges available for current user. 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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "getUserEdges", "parameters": [ { "name": "pageSize", @@ -42399,8 +40906,8 @@ "description": "Maximum amount of entities in a one page", "required": true, "schema": { - "type": "integer", - "format": "int32" + "type": "string", + "minimum": 1 } }, { @@ -42409,8 +40916,8 @@ "description": "Sequence number of page starting from 0", "required": true, "schema": { - "type": "integer", - "format": "int32" + "type": "string", + "minimum": 0 } }, { @@ -42588,48 +41095,48 @@ ] } }, - "/api/user/edges": { + "/api/edge/{edgeId}/events": { "get": { "tags": [ - "edge-controller" + "edge-event-controller" ], - "summary": "Get Edges (getUserEdges)", - "description": "Returns a page of edges available for current user. 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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getUserEdges", + "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": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", + "name": "edgeId", + "in": "path", + "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { - "type": "string", - "minimum": 1 + "type": "string" } }, { - "name": "page", + "name": "pageSize", "in": "query", - "description": "Sequence number of page starting from 0", + "description": "Maximum amount of entities in a one page", "required": true, "schema": { - "type": "string", - "minimum": 0 + "type": "integer", + "format": "int32" } }, { - "name": "type", + "name": "page", "in": "query", - "description": "A string value representing the edge type. For example, 'default'", - "required": false, + "description": "Sequence number of page starting from 0", + "required": true, "schema": { - "type": "string" + "type": "integer", + "format": "int32" } }, { "name": "textSearch", "in": "query", - "description": "The case insensitive 'substring' filter based on the edge name.", + "description": "The case insensitive 'substring' filter based on the edge event type name.", "required": false, "schema": { "type": "string" @@ -42663,6 +41170,26 @@ "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": { @@ -42671,7 +41198,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEdge" + "$ref": "#/components/schemas/PageDataEdgeEvent" } } } @@ -42792,100 +41319,179 @@ ] } }, - "/api/edge/{edgeId}/events": { + "/api/entities/vc/branches": { "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", - "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": "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": "array", + "items": { + "$ref": "#/components/schemas/BranchInfo" + } + } + } } }, - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "integer", - "format": "int32" + "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": "page", - "in": "query", - "description": "Sequence number of page starting from 0", - "required": true, - "schema": { - "type": "integer", - "format": "int32" + "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": "textSearch", - "in": "query", - "description": "The case insensitive 'substring' filter based on the edge event type name.", - "required": false, - "schema": { - "type": "string" + "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": "sortProperty", - "in": "query", - "description": "Property of entity to sort by", - "required": false, - "schema": { - "type": "string", - "enum": [ - "createdTime", - "name", - "type", - "label", - "customerTitle" - ] + "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": [] }, { - "name": "sortOrder", - "in": "query", - "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", - "required": false, + "ApiKeyForm": [] + } + ] + } + }, + "/api/entities/vc/diff/{entityType}/{internalEntityUuid}": { + "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", + "parameters": [ + { + "name": "entityType", + "in": "path", + "description": "A string value representing the entity type. For example, 'DEVICE'", + "required": true, "schema": { - "type": "string", - "enum": [ - "ASC", - "DESC" - ] + "$ref": "#/components/schemas/EntityType" } }, { - "name": "startTime", - "in": "query", - "description": "Timestamp. Edge events with creation time before it won't be queried", - "required": false, + "name": "internalEntityUuid", + "in": "path", + "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, "schema": { - "type": "integer", - "format": "int64" + "type": "string", + "format": "uuid" } }, { - "name": "endTime", + "name": "versionId", "in": "query", - "description": "Timestamp. Edge events with creation time after it won't be queried", - "required": false, + "description": "Version id, for example fd82625bdd7d6131cf8027b44ee967012ecaf990. Represents commit hash.", + "required": true, "schema": { - "type": "integer", - "format": "int64" + "type": "string" } } ], @@ -42895,7 +41501,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEdgeEvent" + "$ref": "#/components/schemas/EntityDataDiff" } } } @@ -43016,24 +41622,32 @@ ] } }, - "/api/entities/vc/branches": { - "get": { + "/api/entities/vc/entity": { + "post": { "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": "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, CONVERTER, INTEGRATION, ROLE and USER group.\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`), internal entity id (`internalEntityId`) 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- `loadPermissions` - when loading user group, to update group permission list;\n- `loadGroupEntities` - when loading an entity group, to load its entities as well;\n- `autoGenerateIntegrationKey` - if loading integration version, to autogenerate routing key.\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" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/BranchInfo" - } + "type": "string", + "format": "uuid" } } } @@ -43050,7 +41664,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -43154,14 +41768,14 @@ ] } }, - "/api/entities/vc/diff/{entityType}/{internalEntityUuid}": { + "/api/entities/vc/entity/{entityType}/{versionId}": { "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": "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", @@ -43172,19 +41786,9 @@ "$ref": "#/components/schemas/EntityType" } }, - { - "name": "internalEntityUuid", - "in": "path", - "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", + "in": "path", "description": "Version id, for example fd82625bdd7d6131cf8027b44ee967012ecaf990. Represents commit hash.", "required": true, "schema": { @@ -43198,7 +41802,10 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EntityDataDiff" + "type": "array", + "items": { + "$ref": "#/components/schemas/VersionedEntityInfo" + } } } } @@ -43319,32 +41926,33 @@ ] } }, - "/api/entities/vc/entity": { - "post": { + "/api/entities/vc/entity/{requestId}/status": { + "get": { "tags": [ "entities-version-control-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, CONVERTER, INTEGRATION, ROLE and USER group.\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`), internal entity id (`internalEntityId`) 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- `loadPermissions` - when loading user group, to update group permission list;\n- `loadGroupEntities` - when loading an entity group, to load its entities as well;\n- `autoGenerateIntegrationKey` - if loading integration version, to autogenerate routing key.\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" - } + "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 - `groupsCreated` - created entity groups count;\n - `groupsUpdated` - updated entity groups count;\n - `groupsDeleted` - removed entity groups 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 \"groupsCreated\": 1,\n \"groupsUpdated\": 1,\n \"groupsDeleted\": 1\n },\n {\n \"entityType\": \"ASSET\",\n \"created\": 4,\n \"updated\": 0,\n \"deleted\": 8,\n \"groupsCreated\": 1,\n \"groupsUpdated\": 0,\n \"groupsDeleted\": 2\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" } - }, - "required": true - }, + } + ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "string", - "format": "uuid" + "$ref": "#/components/schemas/VersionLoadResult" } } } @@ -43361,7 +41969,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -43465,24 +42073,15 @@ ] } }, - "/api/entities/vc/entity/{entityType}/{versionId}": { + "/api/entities/vc/entity/{versionId}": { "get": { "tags": [ "entities-version-control-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", + "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": "entityType", - "in": "path", - "description": "A string value representing the entity type. For example, 'DEVICE'", - "required": true, - "schema": { - "$ref": "#/components/schemas/EntityType" - } - }, { "name": "versionId", "in": "path", @@ -43623,169 +42222,51 @@ ] } }, - "/api/entities/vc/entity/{requestId}/status": { + "/api/entities/vc/info/{versionId}/{entityType}/{externalEntityUuid}": { "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 - `groupsCreated` - created entity groups count;\n - `groupsUpdated` - updated entity groups count;\n - `groupsDeleted` - removed entity groups 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 \"groupsCreated\": 1,\n \"groupsUpdated\": 1,\n \"groupsDeleted\": 1\n },\n {\n \"entityType\": \"ASSET\",\n \"created\": 4,\n \"updated\": 0,\n \"deleted\": 8,\n \"groupsCreated\": 1,\n \"groupsUpdated\": 0,\n \"groupsDeleted\": 2\n }\n ]\n}\n```\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getVersionLoadRequestStatus", + "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), `hasCredentials` (whether stored device data has credentials), `hasPermissions` (user group data contains group permission list) and `hasGroupEntities` (entity group data contains group entities).\n\nAvailable for users with 'TENANT_ADMIN' authority.", + "operationId": "getEntityDataInfo", "parameters": [ { - "name": "requestId", + "name": "versionId", "in": "path", - "description": "A string value representing the version control request id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "Version id, for example fd82625bdd7d6131cf8027b44ee967012ecaf990. Represents commit hash.", "required": true, "schema": { - "type": "string", - "format": "uuid" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/VersionLoadResult" - } - } - } - }, - "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 - } - } - } - } + "type": "string" } }, - "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": [] + "name": "entityType", + "in": "path", + "description": "A string value representing the entity type. For example, 'DEVICE'", + "required": true, + "schema": { + "$ref": "#/components/schemas/EntityType" + } }, { - "ApiKeyForm": [] - } - ] - } - }, - "/api/entities/vc/entity/{versionId}": { - "get": { - "tags": [ - "entities-version-control-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", + "name": "externalEntityUuid", "in": "path", - "description": "Version id, for example fd82625bdd7d6131cf8027b44ee967012ecaf990. Represents commit hash.", + "description": "A string value representing external entity id", "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" + } + }, + { + "name": "internalEntityId", + "in": "query", + "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": false, + "schema": { + "type": "string", + "format": "uuid" } } ], @@ -43795,10 +42276,7 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/VersionedEntityInfo" - } + "$ref": "#/components/schemas/EntityDataInfo" } } } @@ -43919,51 +42397,76 @@ ] } }, - "/api/entities/vc/info/{versionId}/{entityType}/{externalEntityUuid}": { + "/api/entities/vc/version": { "get": { "tags": [ "entities-version-control-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), `hasCredentials` (whether stored device data has credentials), `hasPermissions` (user group data contains group permission list) and `hasGroupEntities` (entity group data contains group entities).\n\nAvailable for users with 'TENANT_ADMIN' authority.", - "operationId": "getEntityDataInfo", + "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": "versionId", - "in": "path", - "description": "Version id, for example fd82625bdd7d6131cf8027b44ee967012ecaf990. Represents commit hash.", + "name": "branch", + "in": "query", + "description": "The name of the working branch, for example 'master'", "required": true, "schema": { "type": "string" } }, { - "name": "entityType", - "in": "path", - "description": "A string value representing the entity type. For example, 'DEVICE'", + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", "required": true, "schema": { - "$ref": "#/components/schemas/EntityType" + "type": "integer", + "format": "int32" } }, { - "name": "externalEntityUuid", - "in": "path", - "description": "A string value representing external entity id", + "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", - "format": "uuid" + "enum": [ + "timestamp" + ] } }, { - "name": "internalEntityId", + "name": "sortOrder", "in": "query", - "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "Sort order. ASC (ASCENDING) or DESC (DESCENDING)", "required": false, "schema": { "type": "string", - "format": "uuid" + "enum": [ + "ASC", + "DESC" + ] } } ], @@ -43973,7 +42476,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EntityDataInfo" + "$ref": "#/components/schemas/PageDataEntityVersion" } } } @@ -44092,88 +42595,32 @@ "ApiKeyForm": [] } ] - } - }, - "/api/entities/vc/version": { - "get": { + }, + "post": { "tags": [ "entities-version-control-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": "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, CONVERTER, INTEGRATION, ROLE and USER group.\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- `savePermissions` - when saving a user group - to save group permission list;\n- `saveGroupEntities` - when saving an entity group - to save its entities as well.\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 `entityIds` - in case entity type is group entity, list of specific entity groups, or if not - list of entities;\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/PageDataEntityVersion" + "type": "string", + "format": "uuid" } } } @@ -44190,7 +42637,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -44292,32 +42739,97 @@ "ApiKeyForm": [] } ] - }, - "post": { + } + }, + "/api/entities/vc/version/{entityType}": { + "get": { "tags": [ "entities-version-control-controller" ], - "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, CONVERTER, INTEGRATION, ROLE and USER group.\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- `savePermissions` - when saving a user group - to save group permission list;\n- `saveGroupEntities` - when saving an entity group - to save its entities as well.\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 `entityIds` - in case entity type is group entity, list of specific entity groups, or if not - list of entities;\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" - } + "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": "entityType", + "in": "path", + "description": "A string value representing the entity type. For example, 'DEVICE'", + "required": true, + "schema": { + "$ref": "#/components/schemas/EntityType" } }, - "required": true - }, + { + "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": "string", - "format": "uuid" + "$ref": "#/components/schemas/PageDataEntityVersion" } } } @@ -44334,7 +42846,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -44438,14 +42950,14 @@ ] } }, - "/api/entities/vc/version/{entityType}": { + "/api/entities/vc/version/{entityType}/{externalEntityUuid}": { "get": { "tags": [ "entities-version-control-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": "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", @@ -44456,6 +42968,16 @@ "$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", @@ -44465,6 +42987,15 @@ "type": "string" } }, + { + "name": "internalEntityId", + "in": "query", + "required": false, + "schema": { + "type": "string", + "format": "uuid" + } + }, { "name": "pageSize", "in": "query", @@ -44647,105 +43178,24 @@ ] } }, - "/api/entities/vc/version/{entityType}/{externalEntityUuid}": { + "/api/entities/vc/version/{requestId}/status": { "get": { "tags": [ "entities-version-control-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 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": "externalEntityUuid", + "name": "requestId", "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.", + "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": "branch", - "in": "query", - "description": "The name of the working branch, for example 'master'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "internalEntityId", - "in": "query", - "required": false, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "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": { @@ -44754,7 +43204,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEntityVersion" + "$ref": "#/components/schemas/VersionCreationResult" } } } @@ -44875,23 +43325,38 @@ ] } }, - "/api/entities/vc/version/{requestId}/status": { + "/api/allEntityGroups/edge/{edgeId}/{groupType}": { "get": { "tags": [ - "entities-version-control-controller" + "entity-group-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", + "summary": "Get All Edge Entity Groups by entity type (getAllEdgeEntityGroups)", + "description": "Fetch the list of Entity Group Info objects based on the provided Entity Type and assigned to the provided Edge entity. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "getAllEdgeEntityGroups", "parameters": [ { - "name": "requestId", + "name": "edgeId", "in": "path", - "description": "A string value representing the version control request 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" + } + }, + { + "name": "groupType", + "in": "path", + "description": "EntityGroup type", "required": true, "schema": { "type": "string", - "format": "uuid" + "enum": [ + "ASSET", + "DEVICE", + "USER", + "ENTITY_VIEW", + "DASHBOARD" + ] } } ], @@ -44901,7 +43366,10 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/VersionCreationResult" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityGroupInfo" + } } } } @@ -45022,14 +43490,14 @@ ] } }, - "/api/allEntityGroups/edge/{edgeId}/{groupType}": { - "get": { + "/api/edge/{edgeId}/entityGroup/{entityGroupId}/{groupType}": { + "post": { "tags": [ "entity-group-controller" ], - "summary": "Get All Edge Entity Groups by entity type (getAllEdgeEntityGroups)", - "description": "Fetch the list of Entity Group Info objects based on the provided Entity Type and assigned to the provided Edge entity. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getAllEdgeEntityGroups", + "summary": "Assign entity group to edge (assignEntityGroupToEdge)", + "description": "Creates assignment of an existing entity group 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 group (Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform). Third, once entity group will be delivered to edge service, edge will request entities of this group to be send to edge. Once entities will be delivered to edge service, they are going to be available for usage on remote edge instance.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for the entity (entities).", + "operationId": "assignEntityGroupToEdge", "parameters": [ { "name": "edgeId", @@ -45055,6 +43523,15 @@ "DASHBOARD" ] } + }, + { + "name": "entityGroupId", + "in": "path", + "description": "A string value representing the Entity Group Id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } } ], "responses": { @@ -45063,10 +43540,7 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityGroupInfo" - } + "$ref": "#/components/schemas/EntityGroup" } } } @@ -45083,7 +43557,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -45185,16 +43659,14 @@ "ApiKeyForm": [] } ] - } - }, - "/api/edge/{edgeId}/entityGroup/{entityGroupId}/{groupType}": { - "post": { + }, + "delete": { "tags": [ "entity-group-controller" ], - "summary": "Assign entity group to edge (assignEntityGroupToEdge)", - "description": "Creates assignment of an existing entity group 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 group (Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform). Third, once entity group will be delivered to edge service, edge will request entities of this group to be send to edge. Once entities will be delivered to edge service, they are going to be available for usage on remote edge instance.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for the entity (entities).", - "operationId": "assignEntityGroupToEdge", + "summary": "Unassign entity group from edge (unassignEntityGroupFromEdge)", + "description": "Clears assignment of the entity group 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 group (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 group and entities inside this group locally.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for the entity (entities).", + "operationId": "unassignEntityGroupFromEdge", "parameters": [ { "name": "edgeId", @@ -45254,7 +43726,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -45356,57 +43828,33 @@ "ApiKeyForm": [] } ] - }, - "delete": { + } + }, + "/api/entityGroup": { + "post": { "tags": [ "entity-group-controller" ], - "summary": "Unassign entity group from edge (unassignEntityGroupFromEdge)", - "description": "Clears assignment of the entity group 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 group (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 group and entities inside this group locally.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for the entity (entities).", - "operationId": "unassignEntityGroupFromEdge", - "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": "groupType", - "in": "path", - "description": "EntityGroup type", - "required": true, - "schema": { - "type": "string", - "enum": [ - "ASSET", - "DEVICE", - "USER", - "ENTITY_VIEW", - "DASHBOARD" - ] + "summary": "Create Or Update Entity Group (saveEntityGroup)", + "description": "Create or update the Entity Group. When creating Entity Group, platform generates Entity Group Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)). The newly created Entity Group Id will be present in the response. Specify existing Entity Group Id to update the group. Referencing non-existing Entity Group Id will cause 'Not Found' error.Remove 'id', 'tenantId' and optionally 'ownerId' from the request body example (below) to create new Entity Group entity. When 'ownerId' is not set (or null), it defaults to the current user's owner (Tenant for tenant admins, Customer for customer users). \n\nEntity group name is unique in the scope of owner and entity type. For example, you can't create two tenant device groups called 'Water meters'. However, you may create device and asset group with the same name. And also you may create groups with the same name for two different customers of the same tenant. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for specified group.", + "operationId": "saveEntityGroup", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityGroup" + } } }, - { - "name": "entityGroupId", - "in": "path", - "description": "A string value representing the Entity Group 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/EntityGroup" + "$ref": "#/components/schemas/EntityGroupInfo" } } } @@ -45423,7 +43871,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -45527,24 +43975,57 @@ ] } }, - "/api/entityGroup": { - "post": { + "/api/entityGroup/all/{ownerType}/{ownerId}/{groupType}": { + "get": { "tags": [ "entity-group-controller" ], - "summary": "Create Or Update Entity Group (saveEntityGroup)", - "description": "Create or update the Entity Group. When creating Entity Group, platform generates Entity Group Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)). The newly created Entity Group Id will be present in the response. Specify existing Entity Group Id to update the group. Referencing non-existing Entity Group Id will cause 'Not Found' error.Remove 'id', 'tenantId' and optionally 'ownerId' from the request body example (below) to create new Entity Group entity. When 'ownerId' is not set (or null), it defaults to the current user's owner (Tenant for tenant admins, Customer for customer users). \n\nEntity group name is unique in the scope of owner and entity type. For example, you can't create two tenant device groups called 'Water meters'. However, you may create device and asset group with the same name. And also you may create groups with the same name for two different customers of the same tenant. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for specified group.", - "operationId": "saveEntityGroup", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EntityGroup" - } + "summary": "Get special group All by owner and entity type (getEntityGroupsByOwnerAndType)", + "description": "Fetch reserved group 'All' based on the provided Owner Id and Entity Type. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getEntityGroupAllByOwnerAndType", + "parameters": [ + { + "name": "ownerType", + "in": "path", + "description": "Tenant or Customer", + "required": true, + "schema": { + "type": "string", + "enum": [ + "TENANT", + "CUSTOMER" + ] } }, - "required": true - }, + { + "name": "ownerId", + "in": "path", + "description": "A string value representing the Tenant or Customer id", + "required": true, + "schema": { + "type": "string" + }, + "example": "784f394c-42b6-435a-983c-b7beff2784f9" + }, + { + "name": "groupType", + "in": "path", + "description": "Entity Group type", + "required": true, + "schema": { + "type": "string", + "enum": [ + "CUSTOMER", + "ASSET", + "DEVICE", + "USER", + "ENTITY_VIEW", + "DASHBOARD", + "EDGE" + ] + } + } + ], "responses": { "200": { "description": "OK", @@ -45568,7 +44049,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -45672,54 +44153,22 @@ ] } }, - "/api/entityGroup/all/{ownerType}/{ownerId}/{groupType}": { + "/api/entityGroup/{entityGroupId}": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get special group All by owner and entity type (getEntityGroupsByOwnerAndType)", - "description": "Fetch reserved group 'All' based on the provided Owner Id and Entity Type. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getEntityGroupAllByOwnerAndType", + "summary": "Get Entity Group Info (getEntityGroupById)", + "description": "Fetch the Entity Group object based on the provided Entity Group Id. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.\n\nEntity group name is unique in the scope of owner and entity type. For example, you can't create two tenant device groups called 'Water meters'. However, you may create device and asset group with the same name. And also you may create groups with the same name for two different customers of the same tenant. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getEntityGroupById", "parameters": [ { - "name": "ownerType", - "in": "path", - "description": "Tenant or Customer", - "required": true, - "schema": { - "type": "string", - "enum": [ - "TENANT", - "CUSTOMER" - ] - } - }, - { - "name": "ownerId", + "name": "entityGroupId", "in": "path", - "description": "A string value representing the Tenant or Customer id", + "description": "A string value representing the Entity Group Id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" - }, - "example": "784f394c-42b6-435a-983c-b7beff2784f9" - }, - { - "name": "groupType", - "in": "path", - "description": "Entity Group type", - "required": true, - "schema": { - "type": "string", - "enum": [ - "CUSTOMER", - "ASSET", - "DEVICE", - "USER", - "ENTITY_VIEW", - "DASHBOARD", - "EDGE" - ] } } ], @@ -45848,16 +44297,14 @@ "ApiKeyForm": [] } ] - } - }, - "/api/entityGroup/{entityGroupId}": { - "get": { + }, + "delete": { "tags": [ "entity-group-controller" ], - "summary": "Get Entity Group Info (getEntityGroupById)", - "description": "Fetch the Entity Group object based on the provided Entity Group Id. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.\n\nEntity group name is unique in the scope of owner and entity type. For example, you can't create two tenant device groups called 'Water meters'. However, you may create device and asset group with the same name. And also you may create groups with the same name for two different customers of the same tenant. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getEntityGroupById", + "summary": "Delete Entity Group (deleteEntityGroup)", + "description": "Deletes the entity group but does not delete the entities in the group, since they are also present in reserved group 'All'. Referencing non-existing Entity Group Id will cause an error.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'DELETE' permission for specified group.", + "operationId": "deleteEntityGroup", "parameters": [ { "name": "entityGroupId", @@ -45871,14 +44318,7 @@ ], "responses": { "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EntityGroupInfo" - } - } - } + "description": "OK" }, "400": { "description": "Bad Request", @@ -45994,14 +44434,16 @@ "ApiKeyForm": [] } ] - }, - "delete": { + } + }, + "/api/entityGroup/{entityGroupId}/addEntities": { + "post": { "tags": [ "entity-group-controller" ], - "summary": "Delete Entity Group (deleteEntityGroup)", - "description": "Deletes the entity group but does not delete the entities in the group, since they are also present in reserved group 'All'. Referencing non-existing Entity Group Id will cause an error.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'DELETE' permission for specified group.", - "operationId": "deleteEntityGroup", + "summary": "Add entities to the group (addEntitiesToEntityGroup)", + "description": "Add entities to the specified entity group. This operation is idempotent: entities that are already members of the group are silently ignored. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'ADD_TO_GROUP' permission for specified group.", + "operationId": "addEntitiesToEntityGroup", "parameters": [ { "name": "entityGroupId", @@ -46013,6 +44455,20 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "array", + "description": "A list of entity ids", + "items": { + "type": "string" + } + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK" @@ -46029,7 +44485,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -46133,14 +44589,14 @@ ] } }, - "/api/entityGroup/{entityGroupId}/addEntities": { + "/api/entityGroup/{entityGroupId}/deleteEntities": { "post": { "tags": [ "entity-group-controller" ], - "summary": "Add entities to the group (addEntitiesToEntityGroup)", - "description": "Add entities to the specified entity group. This operation is idempotent: entities that are already members of the group are silently ignored. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'ADD_TO_GROUP' permission for specified group.", - "operationId": "addEntitiesToEntityGroup", + "summary": "Remove entities from the group (removeEntitiesFromEntityGroup)", + "description": "Removes entities from the specified entity group. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'REMOVE_FROM_GROUP' permission for specified group.", + "operationId": "removeEntitiesFromEntityGroup", "parameters": [ { "name": "entityGroupId", @@ -46286,14 +44742,14 @@ ] } }, - "/api/entityGroup/{entityGroupId}/deleteEntities": { - "post": { + "/api/entityGroup/{entityGroupId}/entities": { + "get": { "tags": [ "entity-group-controller" ], - "summary": "Remove entities from the group (removeEntitiesFromEntityGroup)", - "description": "Removes entities from the specified entity group. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'REMOVE_FROM_GROUP' permission for specified group.", - "operationId": "removeEntitiesFromEntityGroup", + "summary": "Get Group Entities (getEntities)", + "description": "Returns a page of Short Entity View objects that belongs to specified Entity Group Id. Short Entity View object contains the entity id and number of fields (attributes, telemetry, etc). List of those fields is configurable and defined in the group configuration.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. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getEntities", "parameters": [ { "name": "entityGroupId", @@ -46303,26 +44759,70 @@ "schema": { "type": "string" } + }, + { + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", + "required": true, + "schema": { + "type": "string", + "minimum": 1 + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "string", + "minimum": 0 + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'startsWith' filter based on the entity group 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", + "enum": [ + "ASC", + "DESC" + ] + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "array", - "description": "A list of entity ids", - "items": { - "type": "string" + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageDataShortEntityView" } } } }, - "required": true - }, - "responses": { - "200": { - "description": "OK" - }, "400": { "description": "Bad Request", "content": { @@ -46335,7 +44835,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -46439,14 +44939,14 @@ ] } }, - "/api/entityGroup/{entityGroupId}/entities": { - "get": { + "/api/entityGroup/{entityGroupId}/makePrivate": { + "post": { "tags": [ "entity-group-controller" ], - "summary": "Get Group Entities (getEntities)", - "description": "Returns a page of Short Entity View objects that belongs to specified Entity Group Id. Short Entity View object contains the entity id and number of fields (attributes, telemetry, etc). List of those fields is configurable and defined in the group configuration.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. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getEntities", + "summary": "Make Entity Group Private (makeEntityGroupPrivate)", + "description": "Make the entity group not available for non authorized users. Every group is private by default. This call is useful to hide the group that was previously made public.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for specified group.", + "operationId": "makeEntityGroupPrivate", "parameters": [ { "name": "entityGroupId", @@ -46456,69 +44956,11 @@ "schema": { "type": "string" } - }, - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "string", - "minimum": 1 - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", - "required": true, - "schema": { - "type": "string", - "minimum": 0 - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'startsWith' filter based on the entity group 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", - "enum": [ - "ASC", - "DESC" - ] - } } ], "responses": { "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PageDataShortEntityView" - } - } - } + "description": "OK" }, "400": { "description": "Bad Request", @@ -46532,7 +44974,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -46636,14 +45078,14 @@ ] } }, - "/api/entityGroup/{entityGroupId}/makePrivate": { + "/api/entityGroup/{entityGroupId}/makePublic": { "post": { "tags": [ "entity-group-controller" ], - "summary": "Make Entity Group Private (makeEntityGroupPrivate)", - "description": "Make the entity group not available for non authorized users. Every group is private by default. This call is useful to hide the group that was previously made public.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for specified group.", - "operationId": "makeEntityGroupPrivate", + "summary": "Make Entity Group Publicly available (makeEntityGroupPublic)", + "description": "Make the entity group available for non authorized users. Useful for public dashboards that will be embedded into the public websites. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for specified group.", + "operationId": "makeEntityGroupPublic", "parameters": [ { "name": "entityGroupId", @@ -46775,14 +45217,14 @@ ] } }, - "/api/entityGroup/{entityGroupId}/makePublic": { + "/api/entityGroup/{entityGroupId}/share": { "post": { "tags": [ "entity-group-controller" ], - "summary": "Make Entity Group Publicly available (makeEntityGroupPublic)", - "description": "Make the entity group available for non authorized users. Useful for public dashboards that will be embedded into the public websites. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for specified group.", - "operationId": "makeEntityGroupPublic", + "summary": "Share the Entity Group (shareEntityGroup)", + "description": "Share the entity group with certain user group based on the provided Share Group Request. The request is quite flexible and processing of the request involves multiple security checks using platform RBAC feature.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for specified group.", + "operationId": "shareEntityGroup", "parameters": [ { "name": "entityGroupId", @@ -46794,6 +45236,16 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ShareGroupRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK" @@ -46914,14 +45366,14 @@ ] } }, - "/api/entityGroup/{entityGroupId}/share": { - "post": { + "/api/entityGroup/{entityGroupId}/{entityId}": { + "get": { "tags": [ "entity-group-controller" ], - "summary": "Share the Entity Group (shareEntityGroup)", - "description": "Share the entity group with certain user group based on the provided Share Group Request. The request is quite flexible and processing of the request involves multiple security checks using platform RBAC feature.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for specified group.", - "operationId": "shareEntityGroup", + "summary": "Get Group Entity (getGroupEntity)", + "description": "Fetch the Short Entity View object based on the group and entity id. Short Entity View object contains the entity id and number of fields (attributes, telemetry, etc). List of those fields is configurable and defined in the group configuration.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getGroupEntity", "parameters": [ { "name": "entityGroupId", @@ -46931,18 +45383,181 @@ "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" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ShareGroupRequest" + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ShortEntityView" + } } } }, - "required": true + "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/entityGroup/{entityGroupId}/{userGroupId}/{roleId}/share": { + "post": { + "tags": [ + "entity-group-controller" + ], + "summary": "Share the Entity Group with User group (shareEntityGroupToChildOwnerUserGroup)", + "description": "Share the entity group with specified user group using specified role. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for specified group.", + "operationId": "shareEntityGroupToChildOwnerUserGroup", + "parameters": [ + { + "name": "entityGroupId", + "in": "path", + "description": "A string value representing the Entity Group Id that you would like to share. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "userGroupId", + "in": "path", + "description": "A string value representing the Entity(User) Group Id that you would like to share with. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "roleId", + "in": "path", + "description": "A string value representing the Role Id that describes set of permissions you would like to share (read, write, etc). For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "required": true, + "schema": { + "type": "string" + } + } + ], "responses": { "200": { "description": "OK" @@ -47063,28 +45678,60 @@ ] } }, - "/api/entityGroup/{entityGroupId}/{entityId}": { + "/api/entityGroup/{ownerType}/{ownerId}/{groupType}/{groupName}": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Group Entity (getGroupEntity)", - "description": "Fetch the Short Entity View object based on the group and entity id. Short Entity View object contains the entity id and number of fields (attributes, telemetry, etc). List of those fields is configurable and defined in the group configuration.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getGroupEntity", + "summary": "Get Entity Group by owner, type and name (getEntityGroupByOwnerAndNameAndType)", + "description": "Fetch the Entity Group object based on the provided Entity Group Id. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.\n\nEntity group name is unique in the scope of owner and entity type. For example, you can't create two tenant device groups called 'Water meters'. However, you may create device and asset group with the same name. And also you may create groups with the same name for two different customers of the same tenant. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getEntityGroupByOwnerAndNameAndType", "parameters": [ { - "name": "entityGroupId", + "name": "ownerType", "in": "path", - "description": "A string value representing the Entity Group Id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "Tenant or Customer", + "required": true, + "schema": { + "type": "string", + "enum": [ + "TENANT", + "CUSTOMER" + ] + } + }, + { + "name": "ownerId", + "in": "path", + "description": "A string value representing the Tenant or Customer id", "required": true, "schema": { "type": "string" + }, + "example": "784f394c-42b6-435a-983c-b7beff2784f9" + }, + { + "name": "groupType", + "in": "path", + "description": "Entity Group type", + "required": true, + "schema": { + "type": "string", + "enum": [ + "CUSTOMER", + "ASSET", + "DEVICE", + "USER", + "ENTITY_VIEW", + "DASHBOARD", + "EDGE" + ] } }, { - "name": "entityId", + "name": "groupName", "in": "path", - "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "Entity Group name", "required": true, "schema": { "type": "string" @@ -47097,7 +45744,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ShortEntityView" + "$ref": "#/components/schemas/EntityGroupInfo" } } } @@ -47218,37 +45865,19 @@ ] } }, - "/api/entityGroup/{entityGroupId}/{userGroupId}/{roleId}/share": { - "post": { + "/api/entityGroupInfo/{entityGroupId}": { + "get": { "tags": [ "entity-group-controller" ], - "summary": "Share the Entity Group with User group (shareEntityGroupToChildOwnerUserGroup)", - "description": "Share the entity group with specified user group using specified role. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for specified group.", - "operationId": "shareEntityGroupToChildOwnerUserGroup", + "summary": "Get Entity Group Entity Info (getEntityGroupEntityInfoById)", + "description": "Fetch the Entity Group Entity Info object based on the provided Entity Group Id. Entity Info is a lightweight object that contains only id and name of the entity group. \n\nEntity group name is unique in the scope of owner and entity type. For example, you can't create two tenant device groups called 'Water meters'. However, you may create device and asset group with the same name. And also you may create groups with the same name for two different customers of the same tenant. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getEntityGroupEntityInfoById", "parameters": [ { "name": "entityGroupId", "in": "path", - "description": "A string value representing the Entity Group Id that you would like to share. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "userGroupId", - "in": "path", - "description": "A string value representing the Entity(User) Group Id that you would like to share with. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "roleId", - "in": "path", - "description": "A string value representing the Role Id that describes set of permissions you would like to share (read, write, etc). For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "A string value representing the Entity Group Id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" @@ -47257,7 +45886,14 @@ ], "responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityInfo" + } + } + } }, "400": { "description": "Bad Request", @@ -47271,7 +45907,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid request body", + "message": "Invalid UUID string: 123", "errorCode": 31, "timestamp": 1609459200000 } @@ -47375,63 +46011,25 @@ ] } }, - "/api/entityGroup/{ownerType}/{ownerId}/{groupType}/{groupName}": { + "/api/entityGroupInfos": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Entity Group by owner, type and name (getEntityGroupByOwnerAndNameAndType)", - "description": "Fetch the Entity Group object based on the provided Entity Group Id. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.\n\nEntity group name is unique in the scope of owner and entity type. For example, you can't create two tenant device groups called 'Water meters'. However, you may create device and asset group with the same name. And also you may create groups with the same name for two different customers of the same tenant. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getEntityGroupByOwnerAndNameAndType", + "summary": "Get Entity Group Entity Infos by Ids (getEntityGroupEntityInfosByIds)", + "description": "Fetch the list of Entity Group Entity Info objects based on the provided entity group ids list. Entity Info is a lightweight object that contains only id and name of the entity group. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getEntityGroupEntityInfosByIds", "parameters": [ { - "name": "ownerType", - "in": "path", - "description": "Tenant or Customer", - "required": true, - "schema": { - "type": "string", - "enum": [ - "TENANT", - "CUSTOMER" - ] - } - }, - { - "name": "ownerId", - "in": "path", - "description": "A string value representing the Tenant or Customer id", - "required": true, - "schema": { - "type": "string" - }, - "example": "784f394c-42b6-435a-983c-b7beff2784f9" - }, - { - "name": "groupType", - "in": "path", - "description": "Entity Group type", - "required": true, - "schema": { - "type": "string", - "enum": [ - "CUSTOMER", - "ASSET", - "DEVICE", - "USER", - "ENTITY_VIEW", - "DASHBOARD", - "EDGE" - ] - } - }, - { - "name": "groupName", - "in": "path", - "description": "Entity Group name", + "name": "entityGroupIds", + "in": "query", + "description": "A list of group ids, separated by comma ','", "required": true, "schema": { - "type": "string" + "type": "array", + "items": { + "type": "string" + } } } ], @@ -47441,7 +46039,10 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EntityGroupInfo" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityInfo" + } } } } @@ -47562,23 +46163,92 @@ ] } }, - "/api/entityGroupInfo/{entityGroupId}": { + "/api/entityGroupInfos/{groupType}": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Entity Group Entity Info (getEntityGroupEntityInfoById)", - "description": "Fetch the Entity Group Entity Info object based on the provided Entity Group Id. Entity Info is a lightweight object that contains only id and name of the entity group. \n\nEntity group name is unique in the scope of owner and entity type. For example, you can't create two tenant device groups called 'Water meters'. However, you may create device and asset group with the same name. And also you may create groups with the same name for two different customers of the same tenant. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getEntityGroupEntityInfoById", + "summary": "Get Entity Group Entity Infos by entity type and page link (getEntityGroupEntityInfosByTypeAndPageLink)", + "description": "Returns a page of Entity Group Entity Info objects based on the provided Entity Type and Page Link. Entity Info is a lightweight object that contains only id and name of the entity group. 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. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getEntityGroupEntityInfosByTypeAndPageLink", "parameters": [ { - "name": "entityGroupId", + "name": "groupType", "in": "path", - "description": "A string value representing the Entity Group Id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", + "description": "Entity Group type", "required": true, + "schema": { + "type": "string", + "enum": [ + "CUSTOMER", + "ASSET", + "DEVICE", + "USER", + "ENTITY_VIEW", + "DASHBOARD", + "EDGE" + ] + } + }, + { + "name": "includeShared", + "in": "query", + "description": "Whether to include shared entity groups.", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", + "required": true, + "schema": { + "type": "string", + "minimum": 1 + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "string", + "minimum": 0 + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'startsWith' filter based on the entity group 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", + "enum": [ + "ASC", + "DESC" + ] + } } ], "responses": { @@ -47587,7 +46257,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EntityInfo" + "$ref": "#/components/schemas/PageDataEntityInfo" } } } @@ -47708,25 +46378,82 @@ ] } }, - "/api/entityGroupInfos": { + "/api/entityGroupInfos/{groupType}/shared": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Entity Group Entity Infos by Ids (getEntityGroupEntityInfosByIds)", - "description": "Fetch the list of Entity Group Entity Info objects based on the provided entity group ids list. Entity Info is a lightweight object that contains only id and name of the entity group. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getEntityGroupEntityInfosByIds", + "summary": "Get Shared Entity Group Entity Infos by entity type and page link (getSharedEntityGroupEntityInfosByTypeAndPageLink)", + "description": "Returns a page of Shared Entity Group Entity Info objects based on the provided Entity Type and Page Link. Entity Info is a lightweight object that contains only id and name of the entity group. 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. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getSharedEntityGroupEntityInfosByTypeAndPageLink", "parameters": [ { - "name": "entityGroupIds", + "name": "groupType", + "in": "path", + "description": "Entity Group type", + "required": true, + "schema": { + "type": "string", + "enum": [ + "CUSTOMER", + "ASSET", + "DEVICE", + "USER", + "ENTITY_VIEW", + "DASHBOARD", + "EDGE" + ] + } + }, + { + "name": "pageSize", "in": "query", - "description": "A list of group ids, separated by comma ','", + "description": "Maximum amount of entities in a one page", "required": true, "schema": { - "type": "array", - "items": { - "type": "string" - } + "type": "string", + "minimum": 1 + } + }, + { + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", + "required": true, + "schema": { + "type": "string", + "minimum": 0 + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'startsWith' filter based on the entity group 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", + "enum": [ + "ASC", + "DESC" + ] } } ], @@ -47736,10 +46463,7 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityInfo" - } + "$ref": "#/components/schemas/PageDataEntityInfo" } } } @@ -47860,15 +46584,38 @@ ] } }, - "/api/entityGroupInfos/{groupType}": { + "/api/entityGroupInfos/{ownerType}/{ownerId}/{groupType}": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Entity Group Entity Infos by entity type and page link (getEntityGroupEntityInfosByTypeAndPageLink)", - "description": "Returns a page of Entity Group Entity Info objects based on the provided Entity Type and Page Link. Entity Info is a lightweight object that contains only id and name of the entity group. 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. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getEntityGroupEntityInfosByTypeAndPageLink", + "summary": "Get Entity Group Entity Infos by owner and entity type and page link (getEntityGroupEntityInfosByOwnerAndTypeAndPageLink)", + "description": "Returns a page of Entity Group Entity Info objects based on the provided Owner Id and Entity Type and Page Link. Entity Info is a lightweight object that contains only id and name of the entity group. 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. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getEntityGroupEntityInfosByOwnerAndTypeAndPageLink", "parameters": [ + { + "name": "ownerType", + "in": "path", + "description": "Tenant or Customer", + "required": true, + "schema": { + "type": "string", + "enum": [ + "TENANT", + "CUSTOMER" + ] + } + }, + { + "name": "ownerId", + "in": "path", + "description": "A string value representing the Tenant or Customer id", + "required": true, + "schema": { + "type": "string" + }, + "example": "784f394c-42b6-435a-983c-b7beff2784f9" + }, { "name": "groupType", "in": "path", @@ -47887,15 +46634,6 @@ ] } }, - { - "name": "includeShared", - "in": "query", - "description": "Whether to include shared entity groups.", - "required": false, - "schema": { - "type": "boolean" - } - }, { "name": "pageSize", "in": "query", @@ -48075,15 +46813,38 @@ ] } }, - "/api/entityGroupInfos/{groupType}/shared": { + "/api/entityGroupInfosHierarchy/{ownerType}/{ownerId}/{groupType}": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Shared Entity Group Entity Infos by entity type and page link (getSharedEntityGroupEntityInfosByTypeAndPageLink)", - "description": "Returns a page of Shared Entity Group Entity Info objects based on the provided Entity Type and Page Link. Entity Info is a lightweight object that contains only id and name of the entity group. 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. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getSharedEntityGroupEntityInfosByTypeAndPageLink", + "summary": "Get Entity Group Entity Infos for all owners starting from specified than ending with owner of current user (getEntityGroupEntityInfosHierarchyByOwnerAndTypeAndPageLink)", + "description": "Returns a page of Entity Group Entity Info objects based on the provided Owner Id and Entity Type and Page Link. Entity Info is a lightweight object that contains only id and name of the entity group. 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. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getEntityGroupEntityInfosHierarchyByOwnerAndTypeAndPageLink", "parameters": [ + { + "name": "ownerType", + "in": "path", + "description": "Tenant or Customer", + "required": true, + "schema": { + "type": "string", + "enum": [ + "TENANT", + "CUSTOMER" + ] + } + }, + { + "name": "ownerId", + "in": "path", + "description": "A string value representing the Tenant or Customer id", + "required": true, + "schema": { + "type": "string" + }, + "example": "784f394c-42b6-435a-983c-b7beff2784f9" + }, { "name": "groupType", "in": "path", @@ -48281,53 +47042,37 @@ ] } }, - "/api/entityGroupInfos/{ownerType}/{ownerId}/{groupType}": { + "/api/entityGroups/edge/{edgeId}/{groupType}": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Entity Group Entity Infos by owner and entity type and page link (getEntityGroupEntityInfosByOwnerAndTypeAndPageLink)", - "description": "Returns a page of Entity Group Entity Info objects based on the provided Owner Id and Entity Type and Page Link. Entity Info is a lightweight object that contains only id and name of the entity group. 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. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getEntityGroupEntityInfosByOwnerAndTypeAndPageLink", + "summary": "Get Edge Entity Groups by entity type (getEdgeEntityGroups)", + "description": "Returns a page of Entity Group Info objects based on the provided Entity Type and assigned to the provided Edge entity. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "getEdgeEntityGroups", "parameters": [ { - "name": "ownerType", - "in": "path", - "description": "Tenant or Customer", - "required": true, - "schema": { - "type": "string", - "enum": [ - "TENANT", - "CUSTOMER" - ] - } - }, - { - "name": "ownerId", + "name": "edgeId", "in": "path", - "description": "A string value representing the Tenant or Customer id", + "description": "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string" - }, - "example": "784f394c-42b6-435a-983c-b7beff2784f9" + } }, { "name": "groupType", "in": "path", - "description": "Entity Group type", + "description": "EntityGroup type", "required": true, "schema": { "type": "string", "enum": [ - "CUSTOMER", "ASSET", "DEVICE", "USER", "ENTITY_VIEW", - "DASHBOARD", - "EDGE" + "DASHBOARD" ] } }, @@ -48389,7 +47134,159 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEntityInfo" + "$ref": "#/components/schemas/PageDataEntityGroupInfo" + } + } + } + }, + "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/entityGroups/list": { + "get": { + "tags": [ + "entity-group-controller" + ], + "summary": "Get Entity Groups by Ids (getEntityGroupsByIds)", + "description": "Fetch the list of Entity Group Info objects based on the provided entity group ids list. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getEntityGroupsByIds", + "parameters": [ + { + "name": "entityGroupIds", + "in": "query", + "description": "A list of group 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/EntityGroupInfo" + } } } } @@ -48510,40 +47407,17 @@ ] } }, - "/api/entityGroupInfosHierarchy/{ownerType}/{ownerId}/{groupType}": { + "/api/entityGroups/{entityType}/{entityId}": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Entity Group Entity Infos for all owners starting from specified than ending with owner of current user (getEntityGroupEntityInfosHierarchyByOwnerAndTypeAndPageLink)", - "description": "Returns a page of Entity Group Entity Info objects based on the provided Owner Id and Entity Type and Page Link. Entity Info is a lightweight object that contains only id and name of the entity group. 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. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getEntityGroupEntityInfosHierarchyByOwnerAndTypeAndPageLink", + "summary": "Get Entity Groups by Entity Id (getEntityGroupsForEntity)", + "description": "Returns a list of groups that contain the specified Entity Id. For example, all device groups that contain specific device. The list always contain at least one element - special group 'All'.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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "getEntityGroupsForEntity", "parameters": [ { - "name": "ownerType", - "in": "path", - "description": "Tenant or Customer", - "required": true, - "schema": { - "type": "string", - "enum": [ - "TENANT", - "CUSTOMER" - ] - } - }, - { - "name": "ownerId", - "in": "path", - "description": "A string value representing the Tenant or Customer id", - "required": true, - "schema": { - "type": "string" - }, - "example": "784f394c-42b6-435a-983c-b7beff2784f9" - }, - { - "name": "groupType", + "name": "entityType", "in": "path", "description": "Entity Group type", "required": true, @@ -48561,55 +47435,13 @@ } }, { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "string", - "minimum": 1 - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", + "name": "entityId", + "in": "path", + "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, - "schema": { - "type": "string", - "minimum": 0 - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'startsWith' filter based on the entity group 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", - "enum": [ - "ASC", - "DESC" - ] - } } ], "responses": { @@ -48618,7 +47450,10 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEntityInfo" + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityGroupId" + } } } } @@ -48739,40 +47574,42 @@ ] } }, - "/api/entityGroups/edge/{edgeId}/{groupType}": { + "/api/entityGroups/{groupType}": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Edge Entity Groups by entity type (getEdgeEntityGroups)", - "description": "Returns a page of Entity Group Info objects based on the provided Entity Type and assigned to the provided Edge entity. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getEdgeEntityGroups", + "summary": "Get Entity Groups by entity type and page link (getEntityGroupsByTypeAndPageLink)", + "description": "Returns a page of Entity Group Info objects based on the provided Entity Type and Page Link. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.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. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getEntityGroupsByTypeAndPageLink", "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": "groupType", "in": "path", - "description": "EntityGroup type", + "description": "Entity Group type", "required": true, "schema": { "type": "string", "enum": [ + "CUSTOMER", "ASSET", "DEVICE", "USER", "ENTITY_VIEW", - "DASHBOARD" + "DASHBOARD", + "EDGE" ] } }, + { + "name": "includeShared", + "in": "query", + "description": "Whether to include shared entity groups.", + "required": false, + "schema": { + "type": "boolean" + } + }, { "name": "pageSize", "in": "query", @@ -48952,169 +47789,17 @@ ] } }, - "/api/entityGroups/list": { - "get": { - "tags": [ - "entity-group-controller" - ], - "summary": "Get Entity Groups by Ids (getEntityGroupsByIds)", - "description": "Fetch the list of Entity Group Info objects based on the provided entity group ids list. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getEntityGroupsByIds", - "parameters": [ - { - "name": "entityGroupIds", - "in": "query", - "description": "A list of group 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/EntityGroupInfo" - } - } - } - } - }, - "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/entityGroups/{entityType}/{entityId}": { + "/api/entityGroups/{groupType}/all": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Entity Groups by Entity Id (getEntityGroupsForEntity)", - "description": "Returns a list of groups that contain the specified Entity Id. For example, all device groups that contain specific device. The list always contain at least one element - special group 'All'.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. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getEntityGroupsForEntity", + "summary": "Get Entity Groups by entity type (getAllEntityGroupsByType)", + "description": "Fetch the list of Entity Group Info objects based on the provided Entity Type. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getAllEntityGroupsByType", "parameters": [ { - "name": "entityType", + "name": "groupType", "in": "path", "description": "Entity Group type", "required": true, @@ -49132,12 +47817,12 @@ } }, { - "name": "entityId", - "in": "path", - "description": "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", - "required": true, + "name": "includeShared", + "in": "query", + "description": "Whether to include shared entity groups.", + "required": false, "schema": { - "type": "string" + "type": "boolean" } } ], @@ -49149,7 +47834,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/EntityGroupId" + "$ref": "#/components/schemas/EntityGroupInfo" } } } @@ -49271,14 +47956,14 @@ ] } }, - "/api/entityGroups/{groupType}": { + "/api/entityGroups/{groupType}/shared": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Entity Groups by entity type and page link (getEntityGroupsByTypeAndPageLink)", - "description": "Returns a page of Entity Group Info objects based on the provided Entity Type and Page Link. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.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. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getEntityGroupsByTypeAndPageLink", + "summary": "Get Shared Entity Groups by entity type and page link (getSharedEntityGroupsByTypeAndPageLink)", + "description": "Returns a page of Shared Entity Group Info objects based on the provided Entity Type and Page Link. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.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. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getSharedEntityGroupsByTypeAndPageLink", "parameters": [ { "name": "groupType", @@ -49298,15 +47983,6 @@ ] } }, - { - "name": "includeShared", - "in": "query", - "description": "Whether to include shared entity groups.", - "required": false, - "schema": { - "type": "boolean" - } - }, { "name": "pageSize", "in": "query", @@ -49486,14 +48162,14 @@ ] } }, - "/api/entityGroups/{groupType}/all": { + "/api/entityGroups/{groupType}/shared/all": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Entity Groups by entity type (getAllEntityGroupsByType)", - "description": "Fetch the list of Entity Group Info objects based on the provided Entity Type. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getAllEntityGroupsByType", + "summary": "Get Shared Entity Groups by entity type (getAllSharedEntityGroups)", + "description": "Fetch the list of Shared Entity Group Info objects based on the provided Entity Type. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getAllSharedEntityGroups", "parameters": [ { "name": "groupType", @@ -49512,15 +48188,6 @@ "EDGE" ] } - }, - { - "name": "includeShared", - "in": "query", - "description": "Whether to include shared entity groups.", - "required": false, - "schema": { - "type": "boolean" - } } ], "responses": { @@ -49653,15 +48320,38 @@ ] } }, - "/api/entityGroups/{groupType}/shared": { + "/api/entityGroups/{ownerType}/{ownerId}/{groupType}": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Shared Entity Groups by entity type and page link (getSharedEntityGroupsByTypeAndPageLink)", - "description": "Returns a page of Shared Entity Group Info objects based on the provided Entity Type and Page Link. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.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. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getSharedEntityGroupsByTypeAndPageLink", + "summary": "Get Entity Groups by owner and entity type and page link (getEntityGroupsByOwnerAndTypeAndPageLink)", + "description": "Returns a page of Entity Group objects based on the provided Owner Id and Entity Type and Page Link. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.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. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getEntityGroupsByOwnerAndTypeAndPageLink", "parameters": [ + { + "name": "ownerType", + "in": "path", + "description": "Tenant or Customer", + "required": true, + "schema": { + "type": "string", + "enum": [ + "TENANT", + "CUSTOMER" + ] + } + }, + { + "name": "ownerId", + "in": "path", + "description": "A string value representing the Tenant or Customer id", + "required": true, + "schema": { + "type": "string" + }, + "example": "784f394c-42b6-435a-983c-b7beff2784f9" + }, { "name": "groupType", "in": "path", @@ -49859,15 +48549,38 @@ ] } }, - "/api/entityGroups/{groupType}/shared/all": { + "/api/entityGroups/{ownerType}/{ownerId}/{groupType}/all": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Shared Entity Groups by entity type (getAllSharedEntityGroups)", - "description": "Fetch the list of Shared Entity Group Info objects based on the provided Entity Type. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getAllSharedEntityGroups", + "summary": "Get Entity Groups by owner and entity type (getAllEntityGroupsByOwnerAndType)", + "description": "Fetch the list of Entity Group Info objects based on the provided Owner Id and Entity Type. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getAllEntityGroupsByOwnerAndType", "parameters": [ + { + "name": "ownerType", + "in": "path", + "description": "Tenant or Customer", + "required": true, + "schema": { + "type": "string", + "enum": [ + "TENANT", + "CUSTOMER" + ] + } + }, + { + "name": "ownerId", + "in": "path", + "description": "A string value representing the Tenant or Customer id", + "required": true, + "schema": { + "type": "string" + }, + "example": "784f394c-42b6-435a-983c-b7beff2784f9" + }, { "name": "groupType", "in": "path", @@ -50017,14 +48730,14 @@ ] } }, - "/api/entityGroups/{ownerType}/{ownerId}/{groupType}": { + "/api/entityGroupsHierarchy/{ownerType}/{ownerId}/{groupType}": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Entity Groups by owner and entity type and page link (getEntityGroupsByOwnerAndTypeAndPageLink)", + "summary": "Get Entity Groups for all owners starting from specified than ending with owner of current user (getEntityGroupsHierarchyByOwnerAndTypeAndPageLink)", "description": "Returns a page of Entity Group objects based on the provided Owner Id and Entity Type and Page Link. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.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. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getEntityGroupsByOwnerAndTypeAndPageLink", + "operationId": "getEntityGroupsHierarchyByOwnerAndTypeAndPageLink", "parameters": [ { "name": "ownerType", @@ -50246,195 +48959,14 @@ ] } }, - "/api/entityGroups/{ownerType}/{ownerId}/{groupType}/all": { - "get": { - "tags": [ - "entity-group-controller" - ], - "summary": "Get Entity Groups by owner and entity type (getAllEntityGroupsByOwnerAndType)", - "description": "Fetch the list of Entity Group Info objects based on the provided Owner Id and Entity Type. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.Entity Group Info extends Entity Group object and adds 'ownerIds' - a list of owner ids.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getAllEntityGroupsByOwnerAndType", - "parameters": [ - { - "name": "ownerType", - "in": "path", - "description": "Tenant or Customer", - "required": true, - "schema": { - "type": "string", - "enum": [ - "TENANT", - "CUSTOMER" - ] - } - }, - { - "name": "ownerId", - "in": "path", - "description": "A string value representing the Tenant or Customer id", - "required": true, - "schema": { - "type": "string" - }, - "example": "784f394c-42b6-435a-983c-b7beff2784f9" - }, - { - "name": "groupType", - "in": "path", - "description": "Entity Group type", - "required": true, - "schema": { - "type": "string", - "enum": [ - "CUSTOMER", - "ASSET", - "DEVICE", - "USER", - "ENTITY_VIEW", - "DASHBOARD", - "EDGE" - ] - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityGroupInfo" - } - } - } - } - }, - "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/entityGroupsHierarchy/{ownerType}/{ownerId}/{groupType}": { + "/api/ownerInfo/{ownerType}/{ownerId}": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Entity Groups for all owners starting from specified than ending with owner of current user (getEntityGroupsHierarchyByOwnerAndTypeAndPageLink)", - "description": "Returns a page of Entity Group objects based on the provided Owner Id and Entity Type and Page Link. Entity group allows you to group multiple entities of the same entity type (Device, Asset, Customer, User, Dashboard, etc). Entity Group always have an owner - particular Tenant or Customer. Each entity may belong to multiple groups simultaneously.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. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getEntityGroupsHierarchyByOwnerAndTypeAndPageLink", + "summary": "Get Owner Info (getOwnerInfo)", + "description": "Fetch the owner info (tenant or customer) presented as Entity Info object based on the provided owner Id. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", + "operationId": "getOwnerInfo", "parameters": [ { "name": "ownerType", @@ -50458,75 +48990,6 @@ "type": "string" }, "example": "784f394c-42b6-435a-983c-b7beff2784f9" - }, - { - "name": "groupType", - "in": "path", - "description": "Entity Group type", - "required": true, - "schema": { - "type": "string", - "enum": [ - "CUSTOMER", - "ASSET", - "DEVICE", - "USER", - "ENTITY_VIEW", - "DASHBOARD", - "EDGE" - ] - } - }, - { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "string", - "minimum": 1 - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", - "required": true, - "schema": { - "type": "string", - "minimum": 0 - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'startsWith' filter based on the entity group 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", - "enum": [ - "ASC", - "DESC" - ] - } } ], "responses": { @@ -50535,7 +48998,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEntityGroupInfo" + "$ref": "#/components/schemas/EntityInfo" } } } @@ -50656,37 +49119,65 @@ ] } }, - "/api/ownerInfo/{ownerType}/{ownerId}": { + "/api/ownerInfos": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Owner Info (getOwnerInfo)", - "description": "Fetch the owner info (tenant or customer) presented as Entity Info object based on the provided owner Id. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for specified group.", - "operationId": "getOwnerInfo", + "summary": "Get Owner Infos (getOwnerInfos)", + "description": "Provides a rage view of Customers that the current user has READ access to. If the current user is Tenant administrator, the result set also contains the tenant. The call is designed for the UI auto-complete component to show tenant and all possible Customers that the user may select to change the owner of the particular entity or entity group.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", + "operationId": "getOwnerInfos", "parameters": [ { - "name": "ownerType", - "in": "path", - "description": "Tenant or Customer", + "name": "pageSize", + "in": "query", + "description": "Maximum amount of entities in a one page", "required": true, "schema": { "type": "string", - "enum": [ - "TENANT", - "CUSTOMER" - ] + "minimum": 1 } }, { - "name": "ownerId", - "in": "path", - "description": "A string value representing the Tenant or Customer id", + "name": "page", + "in": "query", + "description": "Sequence number of page starting from 0", "required": true, + "schema": { + "type": "string", + "minimum": 0 + } + }, + { + "name": "textSearch", + "in": "query", + "description": "The case insensitive 'startsWith' filter based on the entity group name.", + "required": false, "schema": { "type": "string" - }, - "example": "784f394c-42b6-435a-983c-b7beff2784f9" + } + }, + { + "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", + "enum": [ + "ASC", + "DESC" + ] + } } ], "responses": { @@ -50695,7 +49186,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EntityInfo" + "$ref": "#/components/schemas/PageDataEntityInfo" } } } @@ -50816,14 +49307,14 @@ ] } }, - "/api/ownerInfos": { + "/api/owners": { "get": { "tags": [ "entity-group-controller" ], - "summary": "Get Owner Infos (getOwnerInfos)", + "summary": "Get Owners (getOwners)", "description": "Provides a rage view of Customers that the current user has READ access to. If the current user is Tenant administrator, the result set also contains the tenant. The call is designed for the UI auto-complete component to show tenant and all possible Customers that the user may select to change the owner of the particular entity or entity group.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getOwnerInfos", + "operationId": "getOwners", "parameters": [ { "name": "pageSize", @@ -50883,7 +49374,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PageDataEntityInfo" + "$ref": "#/components/schemas/PageDataContactBasedObject" } } } @@ -51004,78 +49495,40 @@ ] } }, - "/api/owners": { - "get": { + "/api/v2/entityGroup/{entityGroupId}/share": { + "post": { "tags": [ "entity-group-controller" ], - "summary": "Get Owners (getOwners)", - "description": "Provides a rage view of Customers that the current user has READ access to. If the current user is Tenant administrator, the result set also contains the tenant. The call is designed for the UI auto-complete component to show tenant and all possible Customers that the user may select to change the owner of the particular entity or entity group.\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for the entity (entities).", - "operationId": "getOwners", + "summary": "Share the Entity Group with User group (shareEntityGroupToChildOwnerUserGroupV2)", + "description": "Share the entity group with specified user group using specified role. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for specified group.", + "operationId": "shareEntityGroupToChildOwnerUserGroupV2", "parameters": [ { - "name": "pageSize", - "in": "query", - "description": "Maximum amount of entities in a one page", - "required": true, - "schema": { - "type": "string", - "minimum": 1 - } - }, - { - "name": "page", - "in": "query", - "description": "Sequence number of page starting from 0", + "name": "entityGroupId", + "in": "path", + "description": "A uuid value representing the Entity Group Id that you would like to share. For example, '784f394c-42b6-435a-983c-b7beff2784f9'", "required": true, "schema": { "type": "string", - "minimum": 0 - } - }, - { - "name": "textSearch", - "in": "query", - "description": "The case insensitive 'startsWith' filter based on the entity group 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", - "enum": [ - "ASC", - "DESC" - ] + "format": "uuid" } } ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PageDataContactBasedObject" - } + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ShareGroupRequest" } } }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, "400": { "description": "Bad Request", "content": { @@ -51088,7 +49541,7 @@ "summary": "Bad Request", "value": { "status": 400, - "message": "Invalid UUID string: 123", + "message": "Invalid request body", "errorCode": 31, "timestamp": 1609459200000 } @@ -51344,7 +49797,7 @@ "entity-query-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```", + "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": { @@ -51760,7 +50213,7 @@ "entity-query-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## Group Entities Filter\n\nAllows to filter multiple entities of the same type using the entity group type and id. For example, this entity filter selects all devices that belong to the group 'e52b0020-2a7a-11ec-94eb-213c95f54092':\n\n```json\n{\n \"type\": \"entityGroup\",\n \"groupType\": \"DEVICE\",\n \"entityGroup\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\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## Group List Filter\n\nReturn multiple groups of the same type using specified ids. For example, this entity filter selects 2 device groups (if they are present in the system) with ids 'e52b0020-2a7a-11ec-94eb-213c95f54092' and 'e52b0020-2a7a-11ec-94eb-213c95f54093':\n\n```json\n{\n \"type\": \"entityGroupList\",\n \"groupType\": \"DEVICE\",\n \"entityGroupList\": [\"e52b0020-2a7a-11ec-94eb-213c95f54092\", \"e52b0020-2a7a-11ec-94eb-213c95f54093\"]\n}\n```\n\n## Group Name Filter\n\nAllows to filter entity groups based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all devices which name starts with 'CAT':\n\n```json\n{\n \"type\": \"entityGroupName\",\n \"groupType\": \"DEVICE\",\n \"entityGroupNameFilter\": \"CAT\"\n}\n```\n\n## Entities by Group Name Filter\n\nAllows to filter entities that belong to group based on the entity type and the group name. Optional parameter 'ownerId' allows you to specify the owner of the group (Tenant or Customer, current user owner by default).For example, this entity filter selects all devices which belong to group 'Water Meters':\n\n```json\n{\n \"type\": \"entitiesByGroupName\",\n \"groupType\": \"DEVICE\",\n \"entityGroupNameFilter\": \"Water Meters\"\n}\n```\n\n Other example, this entity filter selects all devices which belong to group 'Water Meters' which in turn belongs to (sub-)Customer with id 'e52b0020-2a7a-11ec-94eb-213c95f54093': \n\n```json\n{\n \"type\": \"entitiesByGroupName\",\n \"ownerId\": {\"entityType\": \"CUSTOMER\",\"id\":\"e52b0020-2a7a-11ec-94eb-213c95f54093\"},\n \"groupType\": \"DEVICE\",\n \"entityGroupNameFilter\": \"Water Meters\"\n}\n```\n\n## Entity owner Filter\n\nAllows to fetch owner (Tenant or Customer) of the specified entity. For example, this entity filter selects owner of the device with id 'e52b0020-2a7a-11ec-94eb-213c95f54093':\n\n```json\n{\n \"type\": \"stateEntityOwner\",\n \"singleEntity\": {\n \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n \"entityType\": \"DEVICE\"\n }\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.", + "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## Group Entities Filter\n\nAllows to filter multiple entities of the same type using the entity group type and id. For example, this entity filter selects all devices that belong to the group 'e52b0020-2a7a-11ec-94eb-213c95f54092':\n\n```json\n{\n \"type\": \"entityGroup\",\n \"groupType\": \"DEVICE\",\n \"entityGroup\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\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## Group List Filter\n\nReturn multiple groups of the same type using specified ids. For example, this entity filter selects 2 device groups (if they are present in the system) with ids 'e52b0020-2a7a-11ec-94eb-213c95f54092' and 'e52b0020-2a7a-11ec-94eb-213c95f54093':\n\n```json\n{\n \"type\": \"entityGroupList\",\n \"groupType\": \"DEVICE\",\n \"entityGroupList\": [\"e52b0020-2a7a-11ec-94eb-213c95f54092\", \"e52b0020-2a7a-11ec-94eb-213c95f54093\"]\n}\n```\n\n## Group Name Filter\n\nAllows to filter entity groups based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all devices which name starts with 'CAT':\n\n```json\n{\n \"type\": \"entityGroupName\",\n \"groupType\": \"DEVICE\",\n \"entityGroupNameFilter\": \"CAT\"\n}\n```\n\n## Entities by Group Name Filter\n\nAllows to filter entities that belong to group based on the entity type and the group name. Optional parameter 'ownerId' allows you to specify the owner of the group (Tenant or Customer, current user owner by default).For example, this entity filter selects all devices which belong to group 'Water Meters':\n\n```json\n{\n \"type\": \"entitiesByGroupName\",\n \"groupType\": \"DEVICE\",\n \"entityGroupNameFilter\": \"Water Meters\"\n}\n```\n\n Other example, this entity filter selects all devices which belong to group 'Water Meters' which in turn belongs to (sub-)Customer with id 'e52b0020-2a7a-11ec-94eb-213c95f54093': \n\n```json\n{\n \"type\": \"entitiesByGroupName\",\n \"ownerId\": {\"entityType\": \"CUSTOMER\",\"id\":\"e52b0020-2a7a-11ec-94eb-213c95f54093\"},\n \"groupType\": \"DEVICE\",\n \"entityGroupNameFilter\": \"Water Meters\"\n}\n```\n\n## Entity owner Filter\n\nAllows to fetch owner (Tenant or Customer) of the specified entity. For example, this entity filter selects owner of the device with id 'e52b0020-2a7a-11ec-94eb-213c95f54093':\n\n```json\n{\n \"type\": \"stateEntityOwner\",\n \"singleEntity\": {\n \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n \"entityType\": \"DEVICE\"\n }\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": { @@ -51906,7 +50359,7 @@ "entity-query-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## Group Entities Filter\n\nAllows to filter multiple entities of the same type using the entity group type and id. For example, this entity filter selects all devices that belong to the group 'e52b0020-2a7a-11ec-94eb-213c95f54092':\n\n```json\n{\n \"type\": \"entityGroup\",\n \"groupType\": \"DEVICE\",\n \"entityGroup\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\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## Group List Filter\n\nReturn multiple groups of the same type using specified ids. For example, this entity filter selects 2 device groups (if they are present in the system) with ids 'e52b0020-2a7a-11ec-94eb-213c95f54092' and 'e52b0020-2a7a-11ec-94eb-213c95f54093':\n\n```json\n{\n \"type\": \"entityGroupList\",\n \"groupType\": \"DEVICE\",\n \"entityGroupList\": [\"e52b0020-2a7a-11ec-94eb-213c95f54092\", \"e52b0020-2a7a-11ec-94eb-213c95f54093\"]\n}\n```\n\n## Group Name Filter\n\nAllows to filter entity groups based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all devices which name starts with 'CAT':\n\n```json\n{\n \"type\": \"entityGroupName\",\n \"groupType\": \"DEVICE\",\n \"entityGroupNameFilter\": \"CAT\"\n}\n```\n\n## Entities by Group Name Filter\n\nAllows to filter entities that belong to group based on the entity type and the group name. Optional parameter 'ownerId' allows you to specify the owner of the group (Tenant or Customer, current user owner by default).For example, this entity filter selects all devices which belong to group 'Water Meters':\n\n```json\n{\n \"type\": \"entitiesByGroupName\",\n \"groupType\": \"DEVICE\",\n \"entityGroupNameFilter\": \"Water Meters\"\n}\n```\n\n Other example, this entity filter selects all devices which belong to group 'Water Meters' which in turn belongs to (sub-)Customer with id 'e52b0020-2a7a-11ec-94eb-213c95f54093': \n\n```json\n{\n \"type\": \"entitiesByGroupName\",\n \"ownerId\": {\"entityType\": \"CUSTOMER\",\"id\":\"e52b0020-2a7a-11ec-94eb-213c95f54093\"},\n \"groupType\": \"DEVICE\",\n \"entityGroupNameFilter\": \"Water Meters\"\n}\n```\n\n## Entity owner Filter\n\nAllows to fetch owner (Tenant or Customer) of the specified entity. For example, this entity filter selects owner of the device with id 'e52b0020-2a7a-11ec-94eb-213c95f54093':\n\n```json\n{\n \"type\": \"stateEntityOwner\",\n \"singleEntity\": {\n \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n \"entityType\": \"DEVICE\"\n }\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.", + "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## Group Entities Filter\n\nAllows to filter multiple entities of the same type using the entity group type and id. For example, this entity filter selects all devices that belong to the group 'e52b0020-2a7a-11ec-94eb-213c95f54092':\n\n```json\n{\n \"type\": \"entityGroup\",\n \"groupType\": \"DEVICE\",\n \"entityGroup\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\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## Group List Filter\n\nReturn multiple groups of the same type using specified ids. For example, this entity filter selects 2 device groups (if they are present in the system) with ids 'e52b0020-2a7a-11ec-94eb-213c95f54092' and 'e52b0020-2a7a-11ec-94eb-213c95f54093':\n\n```json\n{\n \"type\": \"entityGroupList\",\n \"groupType\": \"DEVICE\",\n \"entityGroupList\": [\"e52b0020-2a7a-11ec-94eb-213c95f54092\", \"e52b0020-2a7a-11ec-94eb-213c95f54093\"]\n}\n```\n\n## Group Name Filter\n\nAllows to filter entity groups based on their type and the **'starts with'** expression over their name. For example, this entity filter selects all devices which name starts with 'CAT':\n\n```json\n{\n \"type\": \"entityGroupName\",\n \"groupType\": \"DEVICE\",\n \"entityGroupNameFilter\": \"CAT\"\n}\n```\n\n## Entities by Group Name Filter\n\nAllows to filter entities that belong to group based on the entity type and the group name. Optional parameter 'ownerId' allows you to specify the owner of the group (Tenant or Customer, current user owner by default).For example, this entity filter selects all devices which belong to group 'Water Meters':\n\n```json\n{\n \"type\": \"entitiesByGroupName\",\n \"groupType\": \"DEVICE\",\n \"entityGroupNameFilter\": \"Water Meters\"\n}\n```\n\n Other example, this entity filter selects all devices which belong to group 'Water Meters' which in turn belongs to (sub-)Customer with id 'e52b0020-2a7a-11ec-94eb-213c95f54093': \n\n```json\n{\n \"type\": \"entitiesByGroupName\",\n \"ownerId\": {\"entityType\": \"CUSTOMER\",\"id\":\"e52b0020-2a7a-11ec-94eb-213c95f54093\"},\n \"groupType\": \"DEVICE\",\n \"entityGroupNameFilter\": \"Water Meters\"\n}\n```\n\n## Entity owner Filter\n\nAllows to fetch owner (Tenant or Customer) of the specified entity. For example, this entity filter selects owner of the device with id 'e52b0020-2a7a-11ec-94eb-213c95f54093':\n\n```json\n{\n \"type\": \"stateEntityOwner\",\n \"singleEntity\": {\n \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n \"entityType\": \"DEVICE\"\n }\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": { @@ -64282,9 +62735,7 @@ "application/json": { "schema": { "properties": { - "refreshToken": { - - } + "refreshToken": {} } } } @@ -64485,9 +62936,7 @@ "application/json": { "schema": { "type": "object", - "additionalProperties": { - - } + "additionalProperties": {} } } }, @@ -117929,9 +116378,7 @@ "TS_ROLLING" ] }, - "ArrayNode": { - - }, + "ArrayNode": {}, "Asset": { "type": "object", "properties": { @@ -120166,9 +118613,7 @@ "ContactBasedObject": { "type": "object", "properties": { - "id": { - - }, + "id": {}, "createdTime": { "type": "integer", "format": "int64", @@ -126627,9 +125072,7 @@ "HasIdObject": { "type": "object", "properties": { - "id": { - - } + "id": {} } }, "HeaderFooter": { @@ -127445,9 +125888,7 @@ }, "JsonNode": { "description": "A value representing the any type (object or primitive)", - "example": { - - } + "example": {} }, "JsonTransportPayloadConfiguration": { "allOf": [ @@ -128483,9 +126924,7 @@ "firstName": { "type": "string" }, - "id": { - - }, + "id": {}, "lastName": { "type": "string" }, @@ -130781,7 +129220,7 @@ "version": { "type": "string", "description": "OTA Package version.", - "example": 1 + "example": 1.0 }, "tag": { "type": "string", @@ -130900,7 +129339,7 @@ "version": { "type": "string", "description": "OTA Package version.", - "example": 1 + "example": 1.0 }, "tag": { "type": "string", @@ -131043,9 +129482,7 @@ "type" ] }, - "OutputStrategy": { - - }, + "OutputStrategy": {}, "PSKLwM2MBootstrapServerCredential": { "allOf": [ { @@ -135013,15 +133450,15 @@ "legendValueColor": { "type": "string" }, + "xaxis": { + "$ref": "#/components/schemas/TimeSeriesChartXAxisSettings" + }, "yaxes": { "type": "object", "additionalProperties": { "$ref": "#/components/schemas/TimeSeriesChartYAxisSettings" } }, - "xaxis": { - "$ref": "#/components/schemas/TimeSeriesChartXAxisSettings" - }, "thresholds": { "type": "array", "items": { @@ -136080,7 +134517,7 @@ "version": { "type": "string", "description": "OTA Package version.", - "example": 1 + "example": 1.0 }, "tag": { "type": "string", @@ -137819,9 +136256,7 @@ } } }, - "SystemLevelUsersFilter": { - - }, + "SystemLevelUsersFilter": {}, "TableSortOrder": { "type": "object", "properties": { @@ -138913,7 +137348,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": { @@ -139700,39 +138151,27 @@ "properties": { "metricSummaryItems": { "type": "array", - "items": { - - } + "items": {} }, "anomalyModelSummaryItems": { "type": "array", - "items": { - - } + "items": {} }, "calculationFieldSummaryItems": { "type": "array", - "items": { - - } + "items": {} }, "predictionModelSummaryItems": { "type": "array", - "items": { - - } + "items": {} }, "viewSummaryItems": { "type": "array", - "items": { - - } + "items": {} }, "aiSummaryItems": { "type": "array", - "items": { - - } + "items": {} } } }, @@ -139815,9 +138254,7 @@ }, "runtimeFilters": { "type": "array", - "items": { - - } + "items": {} } } }, @@ -139857,9 +138294,7 @@ "type": "integer", "format": "int64" }, - "value": { - - }, + "value": {}, "key": { "type": "string" }, @@ -140657,9 +139092,7 @@ } } }, - "Version": { - - }, + "Version": {}, "VersionCreateConfig": { "type": "object", "properties": { @@ -141568,10 +140001,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/pe/src/main/java/org/thingsboard/client/api/ThingsboardApi.java b/pe/src/main/java/org/thingsboard/client/api/ThingsboardApi.java index 3fa7b079..fd17f6c2 100644 --- a/pe/src/main/java/org/thingsboard/client/api/ThingsboardApi.java +++ b/pe/src/main/java/org/thingsboard/client/api/ThingsboardApi.java @@ -34538,157 +34538,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. Available for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'READ' permission for the entity (entities). @@ -43046,169 +42895,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; - } - /** * getFirmwareById * @@ -58882,169 +58568,6 @@ private HttpRequest.Builder getSignUpSelfRegistrationParamsRequestBuilder(@javax 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 Solution template details (getSolutionTemplateDetails) * Get a solution template details based on the provided id Security check is performed to verify that the user has 'READ' permission for the entity (entities). @@ -75523,387 +75046,6 @@ private HttpRequest.Builder performTrendzHealthcheckRequestBuilder(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; - } - /** * Preview Login White Labeling configuration (saveWhiteLabelParams) * Merge the White Labeling configuration with the parent configuration and return the result. Security check is performed to verify that the user has 'WRITE' permission for the white labeling resource. @@ -76614,124 +75756,6 @@ private HttpRequest.Builder processSystemEdqsRequestRequestBuilder(@javax.annota return localVarRequestBuilder; } - /** - * 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 - * @throws ApiException if fails to make API call - */ - public String provisionDevice(@javax.annotation.Nonnull String body) throws ApiException { - return provisionDevice(body, 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) - * @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(); - } - - /** - * 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> - * @throws ApiException if fails to make API call - */ - public ApiResponse provisionDeviceWithHttpInfo(@javax.annotation.Nonnull String body) throws ApiException { - return provisionDeviceWithHttpInfo(body, 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) - * @param headers Optional headers to include in the request - * @return ApiResponse<String> - * @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); - 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("provisionDevice", 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 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"); - } - - HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - - String localVarPath = "/api/v1/provision"; - - 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; - } - /** * Public connect to Trendz (publicConnectToTrendz) * Initiates synchronization with Trendz if Trendz is not synced yet. Uses Trendz configuration from settings or falls back to environment variables. Generates API key, saves configuration, checks Trendz version, and performs initial sync. @@ -77515,142 +76539,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. @@ -80027,129 +78915,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 @@ -90089,170 +88854,51 @@ private HttpRequest.Builder shareEntityGroupToChildOwnerUserGroupRequestBuilder( } /** - * User Sign Up (signUp) - * Process user sign up request. Creates the Customer and corresponding User based on self Registration parameters for the domain. See [Self Registration Controller](/swagger-ui.html#/self-registration-controller) for more details. The result is either 'SUCCESS' or 'INACTIVE_USER_EXISTS'. If Success, the user will receive an email with instruction to activate the account. The content of the email is customizable via the mail templates. - * @param signUpRequest (required) - * @return SignUpResult - * @throws ApiException if fails to make API call - */ - public SignUpResult signUp(@javax.annotation.Nonnull SignUpRequest signUpRequest) throws ApiException { - return signUp(signUpRequest, null); - } - - /** - * User Sign Up (signUp) - * Process user sign up request. Creates the Customer and corresponding User based on self Registration parameters for the domain. See [Self Registration Controller](/swagger-ui.html#/self-registration-controller) for more details. The result is either 'SUCCESS' or 'INACTIVE_USER_EXISTS'. If Success, the user will receive an email with instruction to activate the account. The content of the email is customizable via the mail templates. - * @param signUpRequest (required) - * @param headers Optional headers to include in the request - * @return SignUpResult - * @throws ApiException if fails to make API call - */ - public SignUpResult signUp(@javax.annotation.Nonnull SignUpRequest signUpRequest, Map headers) throws ApiException { - ApiResponse localVarResponse = signUpWithHttpInfo(signUpRequest, headers); - return localVarResponse.getData(); - } - - /** - * User Sign Up (signUp) - * Process user sign up request. Creates the Customer and corresponding User based on self Registration parameters for the domain. See [Self Registration Controller](/swagger-ui.html#/self-registration-controller) for more details. The result is either 'SUCCESS' or 'INACTIVE_USER_EXISTS'. If Success, the user will receive an email with instruction to activate the account. The content of the email is customizable via the mail templates. - * @param signUpRequest (required) - * @return ApiResponse<SignUpResult> - * @throws ApiException if fails to make API call - */ - public ApiResponse signUpWithHttpInfo(@javax.annotation.Nonnull SignUpRequest signUpRequest) throws ApiException { - return signUpWithHttpInfo(signUpRequest, null); - } - - /** - * User Sign Up (signUp) - * Process user sign up request. Creates the Customer and corresponding User based on self Registration parameters for the domain. See [Self Registration Controller](/swagger-ui.html#/self-registration-controller) for more details. The result is either 'SUCCESS' or 'INACTIVE_USER_EXISTS'. If Success, the user will receive an email with instruction to activate the account. The content of the email is customizable via the mail templates. - * @param signUpRequest (required) - * @param headers Optional headers to include in the request - * @return ApiResponse<SignUpResult> - * @throws ApiException if fails to make API call - */ - public ApiResponse signUpWithHttpInfo(@javax.annotation.Nonnull SignUpRequest signUpRequest, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = signUpRequestBuilder(signUpRequest, 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("signUp", localVarResponse); - } - localVarResponseBody = ApiClient.getResponseBody(localVarResponse); - if (localVarResponseBody == null) { - return new ApiResponse( - localVarResponse.statusCode(), - localVarResponse.headers().map(), - null - ); - } - - - - String responseBody = new String(localVarResponseBody.readAllBytes()); - SignUpResult 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 signUpRequestBuilder(@javax.annotation.Nonnull SignUpRequest signUpRequest, Map headers) throws ApiException { - // verify the required parameter 'signUpRequest' is set - if (signUpRequest == null) { - throw new ApiException(400, "Missing the required parameter 'signUpRequest' when calling signUp"); - } - - HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - - String localVarPath = "/api/noauth/signup"; - - localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); - - localVarRequestBuilder.header("Content-Type", "application/json"); - localVarRequestBuilder.header("Accept", "application/json"); - - try { - byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(signUpRequest); - 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; - } - - /** - * Submit 2FA account config (submitTwoFaAccountConfig) - * Submit 2FA account config to prepare for a future verification. Basically, this method will send a verification code for a given account config, if this has sense for a chosen 2FA provider. This code is needed to then verify and save the account config. Example of EMAIL 2FA account config: ``` { \"providerType\": \"EMAIL\", \"useByDefault\": true, \"email\": \"separate-email-for-2fa@thingsboard.org\" } ``` Example of SMS 2FA account config: ``` { \"providerType\": \"SMS\", \"useByDefault\": false, \"phoneNumber\": \"+38012312321\" } ``` For TOTP this method does nothing. Will throw an error (Bad Request) if submitted account config is not valid, or if the provider is not configured for usage. Available for any authorized user. - * @param twoFaAccountConfig (required) + * Share the Entity Group with User group (shareEntityGroupToChildOwnerUserGroupV2) + * Share the entity group with specified user group using specified role. Available for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for specified group. + * @param entityGroupId A uuid value representing the Entity Group Id that you would like to share. For example, '784f394c-42b6-435a-983c-b7beff2784f9' (required) + * @param shareGroupRequest (required) * @throws ApiException if fails to make API call */ - public void submitTwoFaAccountConfig(@javax.annotation.Nonnull TwoFaAccountConfig twoFaAccountConfig) throws ApiException { - submitTwoFaAccountConfig(twoFaAccountConfig, null); + public void shareEntityGroupToChildOwnerUserGroupV2(@javax.annotation.Nonnull UUID entityGroupId, @javax.annotation.Nonnull ShareGroupRequest shareGroupRequest) throws ApiException { + shareEntityGroupToChildOwnerUserGroupV2(entityGroupId, shareGroupRequest, null); } /** - * Submit 2FA account config (submitTwoFaAccountConfig) - * Submit 2FA account config to prepare for a future verification. Basically, this method will send a verification code for a given account config, if this has sense for a chosen 2FA provider. This code is needed to then verify and save the account config. Example of EMAIL 2FA account config: ``` { \"providerType\": \"EMAIL\", \"useByDefault\": true, \"email\": \"separate-email-for-2fa@thingsboard.org\" } ``` Example of SMS 2FA account config: ``` { \"providerType\": \"SMS\", \"useByDefault\": false, \"phoneNumber\": \"+38012312321\" } ``` For TOTP this method does nothing. Will throw an error (Bad Request) if submitted account config is not valid, or if the provider is not configured for usage. Available for any authorized user. - * @param twoFaAccountConfig (required) + * Share the Entity Group with User group (shareEntityGroupToChildOwnerUserGroupV2) + * Share the entity group with specified user group using specified role. Available for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for specified group. + * @param entityGroupId A uuid value representing the Entity Group Id that you would like to share. For example, '784f394c-42b6-435a-983c-b7beff2784f9' (required) + * @param shareGroupRequest (required) * @param headers Optional headers to include in the request * @throws ApiException if fails to make API call */ - public void submitTwoFaAccountConfig(@javax.annotation.Nonnull TwoFaAccountConfig twoFaAccountConfig, Map headers) throws ApiException { - submitTwoFaAccountConfigWithHttpInfo(twoFaAccountConfig, headers); + public void shareEntityGroupToChildOwnerUserGroupV2(@javax.annotation.Nonnull UUID entityGroupId, @javax.annotation.Nonnull ShareGroupRequest shareGroupRequest, Map headers) throws ApiException { + shareEntityGroupToChildOwnerUserGroupV2WithHttpInfo(entityGroupId, shareGroupRequest, headers); } /** - * Submit 2FA account config (submitTwoFaAccountConfig) - * Submit 2FA account config to prepare for a future verification. Basically, this method will send a verification code for a given account config, if this has sense for a chosen 2FA provider. This code is needed to then verify and save the account config. Example of EMAIL 2FA account config: ``` { \"providerType\": \"EMAIL\", \"useByDefault\": true, \"email\": \"separate-email-for-2fa@thingsboard.org\" } ``` Example of SMS 2FA account config: ``` { \"providerType\": \"SMS\", \"useByDefault\": false, \"phoneNumber\": \"+38012312321\" } ``` For TOTP this method does nothing. Will throw an error (Bad Request) if submitted account config is not valid, or if the provider is not configured for usage. Available for any authorized user. - * @param twoFaAccountConfig (required) + * Share the Entity Group with User group (shareEntityGroupToChildOwnerUserGroupV2) + * Share the entity group with specified user group using specified role. Available for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for specified group. + * @param entityGroupId A uuid value representing the Entity Group Id that you would like to share. For example, '784f394c-42b6-435a-983c-b7beff2784f9' (required) + * @param shareGroupRequest (required) * @return ApiResponse<Void> * @throws ApiException if fails to make API call */ - public ApiResponse submitTwoFaAccountConfigWithHttpInfo(@javax.annotation.Nonnull TwoFaAccountConfig twoFaAccountConfig) throws ApiException { - return submitTwoFaAccountConfigWithHttpInfo(twoFaAccountConfig, null); + public ApiResponse shareEntityGroupToChildOwnerUserGroupV2WithHttpInfo(@javax.annotation.Nonnull UUID entityGroupId, @javax.annotation.Nonnull ShareGroupRequest shareGroupRequest) throws ApiException { + return shareEntityGroupToChildOwnerUserGroupV2WithHttpInfo(entityGroupId, shareGroupRequest, null); } /** - * Submit 2FA account config (submitTwoFaAccountConfig) - * Submit 2FA account config to prepare for a future verification. Basically, this method will send a verification code for a given account config, if this has sense for a chosen 2FA provider. This code is needed to then verify and save the account config. Example of EMAIL 2FA account config: ``` { \"providerType\": \"EMAIL\", \"useByDefault\": true, \"email\": \"separate-email-for-2fa@thingsboard.org\" } ``` Example of SMS 2FA account config: ``` { \"providerType\": \"SMS\", \"useByDefault\": false, \"phoneNumber\": \"+38012312321\" } ``` For TOTP this method does nothing. Will throw an error (Bad Request) if submitted account config is not valid, or if the provider is not configured for usage. Available for any authorized user. - * @param twoFaAccountConfig (required) + * Share the Entity Group with User group (shareEntityGroupToChildOwnerUserGroupV2) + * Share the entity group with specified user group using specified role. Available for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority. Security check is performed to verify that the user has 'WRITE' permission for specified group. + * @param entityGroupId A uuid value representing the Entity Group Id that you would like to share. For example, '784f394c-42b6-435a-983c-b7beff2784f9' (required) + * @param shareGroupRequest (required) * @param headers Optional headers to include in the request * @return ApiResponse<Void> * @throws ApiException if fails to make API call */ - public ApiResponse submitTwoFaAccountConfigWithHttpInfo(@javax.annotation.Nonnull TwoFaAccountConfig twoFaAccountConfig, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = submitTwoFaAccountConfigRequestBuilder(twoFaAccountConfig, headers); + public ApiResponse shareEntityGroupToChildOwnerUserGroupV2WithHttpInfo(@javax.annotation.Nonnull UUID entityGroupId, @javax.annotation.Nonnull ShareGroupRequest shareGroupRequest, Map headers) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = shareEntityGroupToChildOwnerUserGroupV2RequestBuilder(entityGroupId, shareGroupRequest, headers); try { HttpResponse localVarResponse = memberVarHttpClient.send( localVarRequestBuilder.build(), @@ -90263,7 +88909,7 @@ public ApiResponse submitTwoFaAccountConfigWithHttpInfo(@javax.annotation. InputStream localVarResponseBody = null; try { if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("submitTwoFaAccountConfig", localVarResponse); + throw getApiException("shareEntityGroupToChildOwnerUserGroupV2", localVarResponse); } localVarResponseBody = ApiClient.getResponseBody(localVarResponse); if (localVarResponseBody != null) { @@ -90288,15 +88934,20 @@ public ApiResponse submitTwoFaAccountConfigWithHttpInfo(@javax.annotation. } } - private HttpRequest.Builder submitTwoFaAccountConfigRequestBuilder(@javax.annotation.Nonnull TwoFaAccountConfig twoFaAccountConfig, Map headers) throws ApiException { - // verify the required parameter 'twoFaAccountConfig' is set - if (twoFaAccountConfig == null) { - throw new ApiException(400, "Missing the required parameter 'twoFaAccountConfig' when calling submitTwoFaAccountConfig"); + private HttpRequest.Builder shareEntityGroupToChildOwnerUserGroupV2RequestBuilder(@javax.annotation.Nonnull UUID entityGroupId, @javax.annotation.Nonnull ShareGroupRequest shareGroupRequest, Map headers) throws ApiException { + // verify the required parameter 'entityGroupId' is set + if (entityGroupId == null) { + throw new ApiException(400, "Missing the required parameter 'entityGroupId' when calling shareEntityGroupToChildOwnerUserGroupV2"); + } + // verify the required parameter 'shareGroupRequest' is set + if (shareGroupRequest == null) { + throw new ApiException(400, "Missing the required parameter 'shareGroupRequest' when calling shareEntityGroupToChildOwnerUserGroupV2"); } HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); - String localVarPath = "/api/2fa/account/config/submit"; + String localVarPath = "/api/v2/entityGroup/{entityGroupId}/share" + .replace("{entityGroupId}", ApiClient.urlEncode(entityGroupId.toString())); localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); @@ -90304,7 +88955,7 @@ private HttpRequest.Builder submitTwoFaAccountConfigRequestBuilder(@javax.annota localVarRequestBuilder.header("Accept", "application/json"); try { - byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(twoFaAccountConfig); + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(shareGroupRequest); localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); } catch (IOException e) { throw new ApiException(e); @@ -90321,54 +88972,50 @@ private HttpRequest.Builder submitTwoFaAccountConfigRequestBuilder(@javax.annota } /** - * 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 + * User Sign Up (signUp) + * Process user sign up request. Creates the Customer and corresponding User based on self Registration parameters for the domain. See [Self Registration Controller](/swagger-ui.html#/self-registration-controller) for more details. The result is either 'SUCCESS' or 'INACTIVE_USER_EXISTS'. If Success, the user will receive an email with instruction to activate the account. The content of the email is customizable via the mail templates. + * @param signUpRequest (required) + * @return SignUpResult * @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); + public SignUpResult signUp(@javax.annotation.Nonnull SignUpRequest signUpRequest) throws ApiException { + return signUp(signUpRequest, 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) + * User Sign Up (signUp) + * Process user sign up request. Creates the Customer and corresponding User based on self Registration parameters for the domain. See [Self Registration Controller](/swagger-ui.html#/self-registration-controller) for more details. The result is either 'SUCCESS' or 'INACTIVE_USER_EXISTS'. If Success, the user will receive an email with instruction to activate the account. The content of the email is customizable via the mail templates. + * @param signUpRequest (required) * @param headers Optional headers to include in the request - * @return String + * @return SignUpResult * @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); + public SignUpResult signUp(@javax.annotation.Nonnull SignUpRequest signUpRequest, Map headers) throws ApiException { + ApiResponse localVarResponse = signUpWithHttpInfo(signUpRequest, 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> + * User Sign Up (signUp) + * Process user sign up request. Creates the Customer and corresponding User based on self Registration parameters for the domain. See [Self Registration Controller](/swagger-ui.html#/self-registration-controller) for more details. The result is either 'SUCCESS' or 'INACTIVE_USER_EXISTS'. If Success, the user will receive an email with instruction to activate the account. The content of the email is customizable via the mail templates. + * @param signUpRequest (required) + * @return ApiResponse<SignUpResult> * @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); + public ApiResponse signUpWithHttpInfo(@javax.annotation.Nonnull SignUpRequest signUpRequest) throws ApiException { + return signUpWithHttpInfo(signUpRequest, 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) + * User Sign Up (signUp) + * Process user sign up request. Creates the Customer and corresponding User based on self Registration parameters for the domain. See [Self Registration Controller](/swagger-ui.html#/self-registration-controller) for more details. The result is either 'SUCCESS' or 'INACTIVE_USER_EXISTS'. If Success, the user will receive an email with instruction to activate the account. The content of the email is customizable via the mail templates. + * @param signUpRequest (required) * @param headers Optional headers to include in the request - * @return ApiResponse<String> + * @return ApiResponse<SignUpResult> * @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); + public ApiResponse signUpWithHttpInfo(@javax.annotation.Nonnull SignUpRequest signUpRequest, Map headers) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = signUpRequestBuilder(signUpRequest, headers); try { HttpResponse localVarResponse = memberVarHttpClient.send( localVarRequestBuilder.build(), @@ -90379,11 +89026,11 @@ public ApiResponse subscribeToAttributesWithHttpInfo(@javax.annotation.N InputStream localVarResponseBody = null; try { if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("subscribeToAttributes", localVarResponse); + throw getApiException("signUp", localVarResponse); } localVarResponseBody = ApiClient.getResponseBody(localVarResponse); if (localVarResponseBody == null) { - return new ApiResponse( + return new ApiResponse( localVarResponse.statusCode(), localVarResponse.headers().map(), null @@ -90393,10 +89040,10 @@ public ApiResponse subscribeToAttributesWithHttpInfo(@javax.annotation.N String responseBody = new String(localVarResponseBody.readAllBytes()); - String responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); + SignUpResult responseValue = responseBody.isBlank()? null: memberVarObjectMapper.readValue(responseBody, new TypeReference() {}); - return new ApiResponse( + return new ApiResponse( localVarResponse.statusCode(), localVarResponse.headers().map(), responseValue @@ -90415,37 +89062,27 @@ public ApiResponse subscribeToAttributesWithHttpInfo(@javax.annotation.N } } - 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"); + private HttpRequest.Builder signUpRequestBuilder(@javax.annotation.Nonnull SignUpRequest signUpRequest, Map headers) throws ApiException { + // verify the required parameter 'signUpRequest' is set + if (signUpRequest == null) { + throw new ApiException(400, "Missing the required parameter 'signUpRequest' when calling signUp"); } 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)); + String localVarPath = "/api/noauth/signup"; - 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.uri(URI.create(memberVarBaseUri + localVarPath)); + localVarRequestBuilder.header("Content-Type", "application/json"); localVarRequestBuilder.header("Accept", "application/json"); - localVarRequestBuilder.method("GET", HttpRequest.BodyPublishers.noBody()); + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(signUpRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } if (memberVarReadTimeout != null) { localVarRequestBuilder.timeout(memberVarReadTimeout); } @@ -90458,54 +89095,47 @@ private HttpRequest.Builder subscribeToAttributesRequestBuilder(@javax.annotatio } /** - * 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 + * Submit 2FA account config (submitTwoFaAccountConfig) + * Submit 2FA account config to prepare for a future verification. Basically, this method will send a verification code for a given account config, if this has sense for a chosen 2FA provider. This code is needed to then verify and save the account config. Example of EMAIL 2FA account config: ``` { \"providerType\": \"EMAIL\", \"useByDefault\": true, \"email\": \"separate-email-for-2fa@thingsboard.org\" } ``` Example of SMS 2FA account config: ``` { \"providerType\": \"SMS\", \"useByDefault\": false, \"phoneNumber\": \"+38012312321\" } ``` For TOTP this method does nothing. Will throw an error (Bad Request) if submitted account config is not valid, or if the provider is not configured for usage. Available for any authorized user. + * @param twoFaAccountConfig (required) * @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); + public void submitTwoFaAccountConfig(@javax.annotation.Nonnull TwoFaAccountConfig twoFaAccountConfig) throws ApiException { + submitTwoFaAccountConfig(twoFaAccountConfig, 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) + * Submit 2FA account config (submitTwoFaAccountConfig) + * Submit 2FA account config to prepare for a future verification. Basically, this method will send a verification code for a given account config, if this has sense for a chosen 2FA provider. This code is needed to then verify and save the account config. Example of EMAIL 2FA account config: ``` { \"providerType\": \"EMAIL\", \"useByDefault\": true, \"email\": \"separate-email-for-2fa@thingsboard.org\" } ``` Example of SMS 2FA account config: ``` { \"providerType\": \"SMS\", \"useByDefault\": false, \"phoneNumber\": \"+38012312321\" } ``` For TOTP this method does nothing. Will throw an error (Bad Request) if submitted account config is not valid, or if the provider is not configured for usage. Available for any authorized user. + * @param twoFaAccountConfig (required) * @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(); + public void submitTwoFaAccountConfig(@javax.annotation.Nonnull TwoFaAccountConfig twoFaAccountConfig, Map headers) throws ApiException { + submitTwoFaAccountConfigWithHttpInfo(twoFaAccountConfig, headers); } /** - * 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> + * Submit 2FA account config (submitTwoFaAccountConfig) + * Submit 2FA account config to prepare for a future verification. Basically, this method will send a verification code for a given account config, if this has sense for a chosen 2FA provider. This code is needed to then verify and save the account config. Example of EMAIL 2FA account config: ``` { \"providerType\": \"EMAIL\", \"useByDefault\": true, \"email\": \"separate-email-for-2fa@thingsboard.org\" } ``` Example of SMS 2FA account config: ``` { \"providerType\": \"SMS\", \"useByDefault\": false, \"phoneNumber\": \"+38012312321\" } ``` For TOTP this method does nothing. Will throw an error (Bad Request) if submitted account config is not valid, or if the provider is not configured for usage. Available for any authorized user. + * @param twoFaAccountConfig (required) + * @return ApiResponse<Void> * @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); + public ApiResponse submitTwoFaAccountConfigWithHttpInfo(@javax.annotation.Nonnull TwoFaAccountConfig twoFaAccountConfig) throws ApiException { + return submitTwoFaAccountConfigWithHttpInfo(twoFaAccountConfig, 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) + * Submit 2FA account config (submitTwoFaAccountConfig) + * Submit 2FA account config to prepare for a future verification. Basically, this method will send a verification code for a given account config, if this has sense for a chosen 2FA provider. This code is needed to then verify and save the account config. Example of EMAIL 2FA account config: ``` { \"providerType\": \"EMAIL\", \"useByDefault\": true, \"email\": \"separate-email-for-2fa@thingsboard.org\" } ``` Example of SMS 2FA account config: ``` { \"providerType\": \"SMS\", \"useByDefault\": false, \"phoneNumber\": \"+38012312321\" } ``` For TOTP this method does nothing. Will throw an error (Bad Request) if submitted account config is not valid, or if the provider is not configured for usage. Available for any authorized user. + * @param twoFaAccountConfig (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 subscribeToCommandsWithHttpInfo(@javax.annotation.Nonnull String deviceToken, @javax.annotation.Nullable Long timeout, Map headers) throws ApiException { - HttpRequest.Builder localVarRequestBuilder = subscribeToCommandsRequestBuilder(deviceToken, timeout, headers); + public ApiResponse submitTwoFaAccountConfigWithHttpInfo(@javax.annotation.Nonnull TwoFaAccountConfig twoFaAccountConfig, Map headers) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = submitTwoFaAccountConfigRequestBuilder(twoFaAccountConfig, headers); try { HttpResponse localVarResponse = memberVarHttpClient.send( localVarRequestBuilder.build(), @@ -90516,27 +89146,16 @@ public ApiResponse subscribeToCommandsWithHttpInfo(@javax.annotation.Non InputStream localVarResponseBody = null; try { if (localVarResponse.statusCode()/ 100 != 2) { - throw getApiException("subscribeToCommands", localVarResponse); + throw getApiException("submitTwoFaAccountConfig", 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) { @@ -90552,37 +89171,27 @@ public ApiResponse subscribeToCommandsWithHttpInfo(@javax.annotation.Non } } - 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"); + private HttpRequest.Builder submitTwoFaAccountConfigRequestBuilder(@javax.annotation.Nonnull TwoFaAccountConfig twoFaAccountConfig, Map headers) throws ApiException { + // verify the required parameter 'twoFaAccountConfig' is set + if (twoFaAccountConfig == null) { + throw new ApiException(400, "Missing the required parameter 'twoFaAccountConfig' when calling submitTwoFaAccountConfig"); } 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)); + String localVarPath = "/api/2fa/account/config/submit"; - 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.uri(URI.create(memberVarBaseUri + localVarPath)); + localVarRequestBuilder.header("Content-Type", "application/json"); localVarRequestBuilder.header("Accept", "application/json"); - localVarRequestBuilder.method("GET", HttpRequest.BodyPublishers.noBody()); + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(twoFaAccountConfig); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } if (memberVarReadTimeout != null) { localVarRequestBuilder.timeout(memberVarReadTimeout); } diff --git a/pe/src/main/java/org/thingsboard/client/model/ReportBarChartWithLabelsSettings.java b/pe/src/main/java/org/thingsboard/client/model/ReportBarChartWithLabelsSettings.java index 1b6bebc1..8c6f6170 100644 --- a/pe/src/main/java/org/thingsboard/client/model/ReportBarChartWithLabelsSettings.java +++ b/pe/src/main/java/org/thingsboard/client/model/ReportBarChartWithLabelsSettings.java @@ -507,14 +507,14 @@ public ReportBarChartWithLabelsSettings legendValueColor(@javax.annotation.Nulla } @Override - public ReportBarChartWithLabelsSettings yaxes(@javax.annotation.Nullable Map yaxes) { - this.setYaxes(yaxes); + public ReportBarChartWithLabelsSettings xaxis(@javax.annotation.Nullable TimeSeriesChartXAxisSettings xaxis) { + this.setXaxis(xaxis); return this; } @Override - public ReportBarChartWithLabelsSettings xaxis(@javax.annotation.Nullable TimeSeriesChartXAxisSettings xaxis) { - this.setXaxis(xaxis); + public ReportBarChartWithLabelsSettings yaxes(@javax.annotation.Nullable Map yaxes) { + this.setYaxes(yaxes); return this; } @@ -748,6 +748,11 @@ public String toUrlQueryString(String prefix) { joiner.add(String.format(java.util.Locale.ROOT, "%slegendValueColor%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getLegendValueColor())))); } + // add `xaxis` to the URL query string + if (getXaxis() != null) { + joiner.add(getXaxis().toUrlQueryString(prefix + "xaxis" + suffix)); + } + // add `yaxes` to the URL query string if (getYaxes() != null) { for (String _key : getYaxes().keySet()) { @@ -758,11 +763,6 @@ public String toUrlQueryString(String prefix) { } } - // add `xaxis` to the URL query string - if (getXaxis() != null) { - joiner.add(getXaxis().toUrlQueryString(prefix + "xaxis" + suffix)); - } - // add `thresholds` to the URL query string if (getThresholds() != null) { for (int i = 0; i < getThresholds().size(); i++) { diff --git a/pe/src/main/java/org/thingsboard/client/model/ReportRangeChartSettings.java b/pe/src/main/java/org/thingsboard/client/model/ReportRangeChartSettings.java index 62693622..f0a3cb85 100644 --- a/pe/src/main/java/org/thingsboard/client/model/ReportRangeChartSettings.java +++ b/pe/src/main/java/org/thingsboard/client/model/ReportRangeChartSettings.java @@ -429,14 +429,14 @@ public ReportRangeChartSettings legendValueColor(@javax.annotation.Nullable Stri } @Override - public ReportRangeChartSettings yaxes(@javax.annotation.Nullable Map yaxes) { - this.setYaxes(yaxes); + public ReportRangeChartSettings xaxis(@javax.annotation.Nullable TimeSeriesChartXAxisSettings xaxis) { + this.setXaxis(xaxis); return this; } @Override - public ReportRangeChartSettings xaxis(@javax.annotation.Nullable TimeSeriesChartXAxisSettings xaxis) { - this.setXaxis(xaxis); + public ReportRangeChartSettings yaxes(@javax.annotation.Nullable Map yaxes) { + this.setYaxes(yaxes); return this; } @@ -664,6 +664,11 @@ public String toUrlQueryString(String prefix) { joiner.add(String.format(java.util.Locale.ROOT, "%slegendValueColor%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getLegendValueColor())))); } + // add `xaxis` to the URL query string + if (getXaxis() != null) { + joiner.add(getXaxis().toUrlQueryString(prefix + "xaxis" + suffix)); + } + // add `yaxes` to the URL query string if (getYaxes() != null) { for (String _key : getYaxes().keySet()) { @@ -674,11 +679,6 @@ public String toUrlQueryString(String prefix) { } } - // add `xaxis` to the URL query string - if (getXaxis() != null) { - joiner.add(getXaxis().toUrlQueryString(prefix + "xaxis" + suffix)); - } - // add `thresholds` to the URL query string if (getThresholds() != null) { for (int i = 0; i < getThresholds().size(); i++) { diff --git a/pe/src/main/java/org/thingsboard/client/model/ReportTimeSeriesChartSettings.java b/pe/src/main/java/org/thingsboard/client/model/ReportTimeSeriesChartSettings.java index d6966038..f145248a 100644 --- a/pe/src/main/java/org/thingsboard/client/model/ReportTimeSeriesChartSettings.java +++ b/pe/src/main/java/org/thingsboard/client/model/ReportTimeSeriesChartSettings.java @@ -70,8 +70,8 @@ ReportTimeSeriesChartSettings.JSON_PROPERTY_LEGEND_LABEL_COLOR, ReportTimeSeriesChartSettings.JSON_PROPERTY_LEGEND_VALUE_FONT, ReportTimeSeriesChartSettings.JSON_PROPERTY_LEGEND_VALUE_COLOR, - ReportTimeSeriesChartSettings.JSON_PROPERTY_YAXES, ReportTimeSeriesChartSettings.JSON_PROPERTY_XAXIS, + ReportTimeSeriesChartSettings.JSON_PROPERTY_YAXES, ReportTimeSeriesChartSettings.JSON_PROPERTY_THRESHOLDS, ReportTimeSeriesChartSettings.JSON_PROPERTY_GRID, ReportTimeSeriesChartSettings.JSON_PROPERTY_Y_AXES, @@ -158,14 +158,14 @@ public class ReportTimeSeriesChartSettings { @javax.annotation.Nullable private String legendValueColor; - public static final String JSON_PROPERTY_YAXES = "yaxes"; - @javax.annotation.Nullable - private Map yaxes = new HashMap<>(); - public static final String JSON_PROPERTY_XAXIS = "xaxis"; @javax.annotation.Nullable private TimeSeriesChartXAxisSettings xaxis; + public static final String JSON_PROPERTY_YAXES = "yaxes"; + @javax.annotation.Nullable + private Map yaxes = new HashMap<>(); + public static final String JSON_PROPERTY_THRESHOLDS = "thresholds"; @javax.annotation.Nullable private List thresholds = new ArrayList<>(); @@ -589,6 +589,30 @@ public void setLegendValueColor(@javax.annotation.Nullable String legendValueCol } + public ReportTimeSeriesChartSettings xaxis(@javax.annotation.Nullable TimeSeriesChartXAxisSettings xaxis) { + this.xaxis = xaxis; + return this; + } + + /** + * Get xaxis + * @return xaxis + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_XAXIS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public TimeSeriesChartXAxisSettings getXaxis() { + return xaxis; + } + + + @JsonProperty(value = JSON_PROPERTY_XAXIS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setXaxis(@javax.annotation.Nullable TimeSeriesChartXAxisSettings xaxis) { + this.xaxis = xaxis; + } + + public ReportTimeSeriesChartSettings yaxes(@javax.annotation.Nullable Map yaxes) { this.yaxes = yaxes; return this; @@ -621,30 +645,6 @@ public void setYaxes(@javax.annotation.Nullable Map thresholds) { this.thresholds = thresholds; return this; @@ -913,8 +913,8 @@ public boolean equals(Object o) { Objects.equals(this.legendLabelColor, reportTimeSeriesChartSettings.legendLabelColor) && Objects.equals(this.legendValueFont, reportTimeSeriesChartSettings.legendValueFont) && Objects.equals(this.legendValueColor, reportTimeSeriesChartSettings.legendValueColor) && - Objects.equals(this.yaxes, reportTimeSeriesChartSettings.yaxes) && Objects.equals(this.xaxis, reportTimeSeriesChartSettings.xaxis) && + Objects.equals(this.yaxes, reportTimeSeriesChartSettings.yaxes) && Objects.equals(this.thresholds, reportTimeSeriesChartSettings.thresholds) && Objects.equals(this.grid, reportTimeSeriesChartSettings.grid) && Objects.equals(this.yAxes, reportTimeSeriesChartSettings.yAxes) && @@ -928,7 +928,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(showTitle, title, titleFont, titleColor, titleAlignment, stack, comparisonEnabled, timeForComparison, comparisonCustomIntervalValue, showLegend, legendColumnTitleFont, legendColumnTitleColor, legendLabelFont, legendLabelColor, legendValueFont, legendValueColor, yaxes, xaxis, thresholds, grid, yAxes, xAxis, barWidthSettings, noAggregationBarWidthSettings, states, comparisonXAxis, legendConfig); + return Objects.hash(showTitle, title, titleFont, titleColor, titleAlignment, stack, comparisonEnabled, timeForComparison, comparisonCustomIntervalValue, showLegend, legendColumnTitleFont, legendColumnTitleColor, legendLabelFont, legendLabelColor, legendValueFont, legendValueColor, xaxis, yaxes, thresholds, grid, yAxes, xAxis, barWidthSettings, noAggregationBarWidthSettings, states, comparisonXAxis, legendConfig); } @Override @@ -951,8 +951,8 @@ public String toString() { sb.append(" legendLabelColor: ").append(toIndentedString(legendLabelColor)).append("\n"); sb.append(" legendValueFont: ").append(toIndentedString(legendValueFont)).append("\n"); sb.append(" legendValueColor: ").append(toIndentedString(legendValueColor)).append("\n"); - sb.append(" yaxes: ").append(toIndentedString(yaxes)).append("\n"); sb.append(" xaxis: ").append(toIndentedString(xaxis)).append("\n"); + sb.append(" yaxes: ").append(toIndentedString(yaxes)).append("\n"); sb.append(" thresholds: ").append(toIndentedString(thresholds)).append("\n"); sb.append(" grid: ").append(toIndentedString(grid)).append("\n"); sb.append(" yAxes: ").append(toIndentedString(yAxes)).append("\n"); @@ -1089,6 +1089,11 @@ public String toUrlQueryString(String prefix) { joiner.add(String.format(java.util.Locale.ROOT, "%slegendValueColor%s=%s", prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getLegendValueColor())))); } + // add `xaxis` to the URL query string + if (getXaxis() != null) { + joiner.add(getXaxis().toUrlQueryString(prefix + "xaxis" + suffix)); + } + // add `yaxes` to the URL query string if (getYaxes() != null) { for (String _key : getYaxes().keySet()) { @@ -1099,11 +1104,6 @@ public String toUrlQueryString(String prefix) { } } - // add `xaxis` to the URL query string - if (getXaxis() != null) { - joiner.add(getXaxis().toUrlQueryString(prefix + "xaxis" + suffix)); - } - // add `thresholds` to the URL query string if (getThresholds() != null) { for (int i = 0; i < getThresholds().size(); i++) {