# ThingsBoard ThingsBoard Devices API
# Source: https://demo.thingsboard.io/v3/api-docs (Apache 2.0)
openapi: 3.1.0
info:
title: ThingsBoard Devices API
description: "ThingsBoard Devices API \u2014 subset of the ThingsBoard REST API (open-source IoT platform). Covers: Device, Device Profile, Device Connectivity, Ota Package."
version: 4.3.0.3DEMO
contact:
name: ThingsBoard team
url: https://thingsboard.io
email: [email protected]
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0
servers:
- url: https://demo.thingsboard.io
description: ThingsBoard Live Demo
- url: http://localhost:8080
description: Local ThingsBoard server
tags:
- name: device-controller
description: Device
- name: device-profile-controller
description: Device Profile
- name: device-connectivity-controller
description: Device Connectivity
- name: ota-package-controller
description: Ota Package
paths:
/api/tenant/{tenantId}/device/{deviceId}:
post:
tags:
- device-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.
Available for users with ''TENANT_ADMIN'' authority.'
operationId: assignDeviceToTenant
parameters:
- name: tenantId
in: path
description: A string value representing the tenant id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
required: true
schema:
type: string
- name: deviceId
in: path
description: A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Device'
/api/otaPackage:
post:
tags:
- ota-package-controller
summary: Create or Update OTA Package Info (saveOtaPackageInfo)
description: "Create or update the OTA Package Info. When creating OTA Package Info, platform generates OTA Package id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)).\
\ The newly created OTA Package id will be present in the response. Specify existing OTA Package id to update the OTA Package Info. Referencing non-existing OTA Package Id will cause 'Not Found'\
\ error. \n\nOTA Package combination of the title with the version is unique in the scope of tenant. \n\nAvailable for users with 'TENANT_ADMIN' authority."
operationId: saveOtaPackageInfo
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SaveOtaPackageInfoRequest'
required: true
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/OtaPackageInfo'
/api/otaPackage/{otaPackageId}:
get:
tags:
- ota-package-controller
summary: Get OTA Package (getOtaPackageById)
description: "Fetch the OTA Package object based on the provided OTA Package Id. The server checks that the OTA Package is owned by the same tenant. OTA Package is a heavyweight object that includes\
\ main information about the OTA Package and also data. \n\nAvailable for users with 'TENANT_ADMIN' authority."
operationId: getOtaPackageById
parameters:
- name: otaPackageId
in: path
description: A string value representing the ota package id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/OtaPackage'
post:
tags:
- ota-package-controller
summary: Save OTA Package Data (saveOtaPackageData)
description: 'Update the OTA Package. Adds the date to the existing OTA Package Info
Available for users with ''TENANT_ADMIN'' authority.'
operationId: saveOtaPackageData
parameters:
- name: otaPackageId
in: path
description: A string value representing the ota package id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
required: true
schema:
type: string
- name: checksum
in: query
description: OTA Package checksum. For example, '0xd87f7e0c'
required: false
schema:
type: string
- name: checksumAlgorithm
in: query
description: OTA Package checksum algorithm.
required: true
schema:
type: string
enum:
- MD5
- SHA256
- SHA384
- SHA512
- CRC32
- MURMUR3_32
- MURMUR3_128
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
description: OTA Package data.
required:
- file
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/OtaPackageInfo'
delete:
tags:
- ota-package-controller
summary: Delete OTA Package (deleteOtaPackage)
description: 'Deletes the OTA Package. Referencing non-existing OTA Package Id will cause an error. Can''t delete the OTA Package if it is referenced by existing devices or device profile.
Available for users with ''TENANT_ADMIN'' authority.'
operationId: deleteOtaPackage
parameters:
- name: otaPackageId
in: path
description: A string value representing the ota package id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
required: true
schema:
type: string
responses:
'200':
description: OK
/api/edge/{edgeId}/device/{deviceId}:
post:
tags:
- device-controller
summary: Assign Device to Edge (assignDeviceToEdge)
description: 'Creates assignment of an existing device to an instance of The Edge. Assignment works in async way - first, notification event pushed to edge service queue on platform. Second, remote
edge service will receive a copy of assignment device (Edge will receive this instantly, if it''s currently connected, or once it''s going to be connected to platform). Third, once device will be
delivered to edge service, it''s going to be available for usage on remote edge instance.
Available for users with ''TENANT_ADMIN'' authority.'
operationId: assignDeviceToEdge
parameters:
- name: edgeId
in: path
description: A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
required: true
schema:
type: string
- name: deviceId
in: path
description: A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Device'
delete:
tags:
- device-controller
summary: Unassign Device from Edge (unassignDeviceFromEdge)
description: 'Clears assignment of the device to the edge. Unassignment works in async way - first, ''unassign'' notification event pushed to edge queue on platform. Second, remote edge service will
receive an ''unassign'' command to remove device (Edge will receive this instantly, if it''s currently connected, or once it''s going to be connected to platform). Third, once ''unassign'' command
will be delivered to edge service, it''s going to remove device locally.
Available for users with ''TENANT_ADMIN'' authority.'
operationId: unassignDeviceFromEdge
parameters:
- name: edgeId
in: path
description: A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
required: true
schema:
type: string
- name: deviceId
in: path
description: A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Device'
/api/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."
operationId: getDevicesByIds
parameters:
- name: deviceIds
in: query
description: A list of devices 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/Device'
post:
tags:
- device-controller
summary: Find Related Devices (findByQuery)
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.
Available for users with ''TENANT_ADMIN'' or ''CUSTOMER_USER'' authority.'
operationId: findByQuery_3
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/DeviceSearchQuery'
required: true
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Device'
/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."
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: nameConflictPolicy
in: query
description: 'Optional value of name conflict policy. Possible values: FAIL or UNIQUIFY. If omitted, FAIL policy is applied. FAIL policy implies exception will be thrown if an entity with the same
name already exists. UNIQUIFY policy appends a suffix to the entity name, if a name conflict occurs.'
required: false
schema:
type: string
default: FAIL
enum:
- FAIL
- UNIQUIFY
- 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:
type: string
default: RANDOM
enum:
- RANDOM
- INCREMENTAL
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'
/api/deviceProfile:
post:
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 <\
\ 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
# --- truncated at 32 KB (179 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/thingsboard/refs/heads/main/openapi/thingsboard-devices-openapi.yml