Commit 45424dedeb45da882792f61ef657311c2c05ddeb
Merge branch 'feature/swagger-device-profile-data' of https://github.com/dmytro-…
…landiak/thingsboard into feature/swagger
Showing
14 changed files
with
668 additions
and
76 deletions
... | ... | @@ -155,6 +155,8 @@ public abstract class BaseController { |
155 | 155 | |
156 | 156 | /*Swagger UI description*/ |
157 | 157 | |
158 | + protected static final String NEW_LINE = "\n\n"; | |
159 | + | |
158 | 160 | public static final String CUSTOMER_ID = "customerId"; |
159 | 161 | public static final String TENANT_ID = "tenantId"; |
160 | 162 | public static final String DEVICE_ID = "deviceId"; |
... | ... | @@ -263,7 +265,7 @@ public abstract class BaseController { |
263 | 265 | protected static final String EVENT_END_TIME_DESCRIPTION = "Timestamp. Events with creation time after it won't be queried."; |
264 | 266 | |
265 | 267 | protected static final String EDGE_UNASSIGN_ASYNC_FIRST_STEP_DESCRIPTION = "Unassignment works in async way - first, 'unassign' notification event pushed to edge queue on platform. "; |
266 | - protected static final String EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION = "(Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform)" ; | |
268 | + protected static final String EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION = "(Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform)"; | |
267 | 269 | protected static final String EDGE_ASSIGN_ASYNC_FIRST_STEP_DESCRIPTION = "Assignment works in async way - first, notification event pushed to edge service queue on platform. "; |
268 | 270 | protected static final String EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION = "(Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform)"; |
269 | 271 | |
... | ... | @@ -281,6 +283,114 @@ public abstract class BaseController { |
281 | 283 | protected static final String EVENT_DEBUG_RULE_NODE_FILTER_OBJ = MARKDOWN_CODE_BLOCK_START + "{ \"eventType\": \"DEBUG_RULE_NODE\"," + DEBUG_FILTER_OBJ + MARKDOWN_CODE_BLOCK_END; |
282 | 284 | protected static final String EVENT_DEBUG_RULE_CHAIN_FILTER_OBJ = MARKDOWN_CODE_BLOCK_START + "{ \"eventType\": \"DEBUG_RULE_CHAIN\"," + DEBUG_FILTER_OBJ + MARKDOWN_CODE_BLOCK_END; |
283 | 285 | |
286 | + protected static final String FILTER_VALUE_TYPE = NEW_LINE + "## Value Type and Operations" + NEW_LINE + | |
287 | + "Provides a hint about the data type of the entity field that is defined in the filter key. " + | |
288 | + "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." + | |
289 | + "The following filter value types and corresponding predicate operations are supported: " + NEW_LINE + | |
290 | + " * 'STRING' - used to filter any 'String' or 'JSON' values. Operations: EQUAL, NOT_EQUAL, STARTS_WITH, ENDS_WITH, CONTAINS, NOT_CONTAINS; \n" + | |
291 | + " * 'NUMERIC' - used for 'Long' and 'Double' values. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n" + | |
292 | + " * 'BOOLEAN' - used for boolean values. Operations: EQUAL, NOT_EQUAL;\n" + | |
293 | + " * 'DATE_TIME' - similar to numeric, transforms value to milliseconds since epoch. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n"; | |
294 | + | |
295 | + protected static final String DEVICE_PROFILE_ALARM_SCHEDULE_SPECIFIC_TIME_EXAMPLE = MARKDOWN_CODE_BLOCK_START + | |
296 | + "{\n" + | |
297 | + " \"schedule\":{\n" + | |
298 | + " \"type\":\"SPECIFIC_TIME\",\n" + | |
299 | + " \"endsOn\":64800000,\n" + | |
300 | + " \"startsOn\":43200000,\n" + | |
301 | + " \"timezone\":\"Europe/Kiev\",\n" + | |
302 | + " \"daysOfWeek\":[\n" + | |
303 | + " 1,\n" + | |
304 | + " 3,\n" + | |
305 | + " 5\n" + | |
306 | + " ]\n" + | |
307 | + " }\n" + | |
308 | + "}" + | |
309 | + MARKDOWN_CODE_BLOCK_END; | |
310 | + protected static final String DEVICE_PROFILE_ALARM_SCHEDULE_CUSTOM_EXAMPLE = MARKDOWN_CODE_BLOCK_START + | |
311 | + "{\n" + | |
312 | + " \"schedule\":{\n" + | |
313 | + " \"type\":\"CUSTOM\",\n" + | |
314 | + " \"items\":[\n" + | |
315 | + " {\n" + | |
316 | + " \"endsOn\":0,\n" + | |
317 | + " \"enabled\":false,\n" + | |
318 | + " \"startsOn\":0,\n" + | |
319 | + " \"dayOfWeek\":1\n" + | |
320 | + " },\n" + | |
321 | + " {\n" + | |
322 | + " \"endsOn\":64800000,\n" + | |
323 | + " \"enabled\":true,\n" + | |
324 | + " \"startsOn\":43200000,\n" + | |
325 | + " \"dayOfWeek\":2\n" + | |
326 | + " },\n" + | |
327 | + " {\n" + | |
328 | + " \"endsOn\":0,\n" + | |
329 | + " \"enabled\":false,\n" + | |
330 | + " \"startsOn\":0,\n" + | |
331 | + " \"dayOfWeek\":3\n" + | |
332 | + " },\n" + | |
333 | + " {\n" + | |
334 | + " \"endsOn\":57600000,\n" + | |
335 | + " \"enabled\":true,\n" + | |
336 | + " \"startsOn\":36000000,\n" + | |
337 | + " \"dayOfWeek\":4\n" + | |
338 | + " },\n" + | |
339 | + " {\n" + | |
340 | + " \"endsOn\":0,\n" + | |
341 | + " \"enabled\":false,\n" + | |
342 | + " \"startsOn\":0,\n" + | |
343 | + " \"dayOfWeek\":5\n" + | |
344 | + " },\n" + | |
345 | + " {\n" + | |
346 | + " \"endsOn\":0,\n" + | |
347 | + " \"enabled\":false,\n" + | |
348 | + " \"startsOn\":0,\n" + | |
349 | + " \"dayOfWeek\":6\n" + | |
350 | + " },\n" + | |
351 | + " {\n" + | |
352 | + " \"endsOn\":0,\n" + | |
353 | + " \"enabled\":false,\n" + | |
354 | + " \"startsOn\":0,\n" + | |
355 | + " \"dayOfWeek\":7\n" + | |
356 | + " }\n" + | |
357 | + " ],\n" + | |
358 | + " \"timezone\":\"Europe/Kiev\"\n" + | |
359 | + " }\n" + | |
360 | + "}" + | |
361 | + MARKDOWN_CODE_BLOCK_END; | |
362 | + protected static final String DEVICE_PROFILE_ALARM_SCHEDULE_ALWAYS_EXAMPLE = MARKDOWN_CODE_BLOCK_START + "\"schedule\": null" + MARKDOWN_CODE_BLOCK_END; | |
363 | + | |
364 | + protected static final String DEVICE_PROFILE_ALARM_CONDITION_REPEATING_EXAMPLE = MARKDOWN_CODE_BLOCK_START + | |
365 | + "{\n" + | |
366 | + " \"spec\":{\n" + | |
367 | + " \"type\":\"REPEATING\",\n" + | |
368 | + " \"predicate\":{\n" + | |
369 | + " \"userValue\":null,\n" + | |
370 | + " \"defaultValue\":5,\n" + | |
371 | + " \"dynamicValue\":{\n" + | |
372 | + " \"inherit\":true,\n" + | |
373 | + " \"sourceType\":\"CURRENT_DEVICE\",\n" + | |
374 | + " \"sourceAttribute\":\"tempAttr\"\n" + | |
375 | + " }\n" + | |
376 | + " }\n" + | |
377 | + " }\n" + | |
378 | + "}" + | |
379 | + MARKDOWN_CODE_BLOCK_END; | |
380 | + protected static final String DEVICE_PROFILE_ALARM_CONDITION_DURATION_EXAMPLE = MARKDOWN_CODE_BLOCK_START + | |
381 | + "{\n" + | |
382 | + " \"spec\":{\n" + | |
383 | + " \"type\":\"DURATION\",\n" + | |
384 | + " \"unit\":\"MINUTES\",\n" + | |
385 | + " \"predicate\":{\n" + | |
386 | + " \"userValue\":null,\n" + | |
387 | + " \"defaultValue\":30,\n" + | |
388 | + " \"dynamicValue\":null\n" + | |
389 | + " }\n" + | |
390 | + " }\n" + | |
391 | + "}" + | |
392 | + MARKDOWN_CODE_BLOCK_END; | |
393 | + | |
284 | 394 | protected static final String RELATION_TYPE_PARAM_DESCRIPTION = "A string value representing relation type between entities. For example, 'Contains', 'Manages'. It can be any string value."; |
285 | 395 | protected static final String RELATION_TYPE_GROUP_PARAM_DESCRIPTION = "A string value representing relation type group. For example, 'COMMON'"; |
286 | 396 | ... | ... |
... | ... | @@ -55,6 +55,453 @@ import java.util.UUID; |
55 | 55 | @Slf4j |
56 | 56 | public class DeviceProfileController extends BaseController { |
57 | 57 | |
58 | + private static final String COAP_TRANSPORT_CONFIGURATION_EXAMPLE = MARKDOWN_CODE_BLOCK_START + | |
59 | + "{\n" + | |
60 | + " \"type\":\"COAP\",\n" + | |
61 | + " \"clientSettings\":{\n" + | |
62 | + " \"edrxCycle\":null,\n" + | |
63 | + " \"powerMode\":\"DRX\",\n" + | |
64 | + " \"psmActivityTimer\":null,\n" + | |
65 | + " \"pagingTransmissionWindow\":null\n" + | |
66 | + " },\n" + | |
67 | + " \"coapDeviceTypeConfiguration\":{\n" + | |
68 | + " \"coapDeviceType\":\"DEFAULT\",\n" + | |
69 | + " \"transportPayloadTypeConfiguration\":{\n" + | |
70 | + " \"transportPayloadType\":\"JSON\"\n" + | |
71 | + " }\n" + | |
72 | + " }\n" + | |
73 | + "}" | |
74 | + + MARKDOWN_CODE_BLOCK_END; | |
75 | + | |
76 | + private static final String TRANSPORT_CONFIGURATION = "# Transport Configuration" + NEW_LINE + | |
77 | + "5 transport configuration types are available:\n" + | |
78 | + " * 'DEFAULT';\n" + | |
79 | + " * 'MQTT';\n" + | |
80 | + " * 'LWM2M';\n" + | |
81 | + " * 'COAP';\n" + | |
82 | + " * 'SNMP'." + NEW_LINE + "Default type supports basic MQTT, HTTP, CoAP and LwM2M transports. " + | |
83 | + "Please refer to the [docs](https://thingsboard.io/docs/user-guide/device-profiles/#transport-configuration) for more details about other types.\n" + | |
84 | + "\nSee another example of COAP transport configuration below:" + NEW_LINE + COAP_TRANSPORT_CONFIGURATION_EXAMPLE; | |
85 | + | |
86 | + private static final String ALARM_FILTER_KEY = "## Alarm Filter Key" + NEW_LINE + | |
87 | + "Filter 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" + | |
88 | + " * 'ATTRIBUTE' - used for attributes values;\n" + | |
89 | + " * 'TIME_SERIES' - used for time-series values;\n" + | |
90 | + " * 'ENTITY_FIELD' - used for accessing entity fields like 'name', 'label', etc. The list of available fields depends on the entity type;\n" + | |
91 | + " * 'CONSTANT' - constant value specified." + NEW_LINE + "Let's review the example:" + NEW_LINE + | |
92 | + MARKDOWN_CODE_BLOCK_START + | |
93 | + "{\n" + | |
94 | + " \"type\": \"TIME_SERIES\",\n" + | |
95 | + " \"key\": \"temperature\"\n" + | |
96 | + "}" + | |
97 | + MARKDOWN_CODE_BLOCK_END; | |
98 | + | |
99 | + private static final String FILTER_PREDICATE = NEW_LINE + "## Filter Predicate" + NEW_LINE + | |
100 | + "Filter Predicate defines the logical expression to evaluate. The list of available operations depends on the filter value type, see above. " + | |
101 | + "Platform supports 4 predicate types: 'STRING', 'NUMERIC', 'BOOLEAN' and 'COMPLEX'. The last one allows to combine multiple operations over one filter key." + NEW_LINE + | |
102 | + "Simple predicate example to check 'value < 100': " + NEW_LINE + | |
103 | + MARKDOWN_CODE_BLOCK_START + | |
104 | + "{\n" + | |
105 | + " \"operation\": \"LESS\",\n" + | |
106 | + " \"value\": {\n" + | |
107 | + " \"userValue\": null,\n" + | |
108 | + " \"defaultValue\": 100,\n" + | |
109 | + " \"dynamicValue\": null\n" + | |
110 | + " },\n" + | |
111 | + " \"type\": \"NUMERIC\"\n" + | |
112 | + "}" + | |
113 | + MARKDOWN_CODE_BLOCK_END + NEW_LINE + | |
114 | + "Complex predicate example, to check 'value < 10 or value > 20': " + NEW_LINE + | |
115 | + MARKDOWN_CODE_BLOCK_START + | |
116 | + "{\n" + | |
117 | + " \"type\": \"COMPLEX\",\n" + | |
118 | + " \"operation\": \"OR\",\n" + | |
119 | + " \"predicates\": [\n" + | |
120 | + " {\n" + | |
121 | + " \"operation\": \"LESS\",\n" + | |
122 | + " \"value\": {\n" + | |
123 | + " \"userValue\": null,\n" + | |
124 | + " \"defaultValue\": 10,\n" + | |
125 | + " \"dynamicValue\": null\n" + | |
126 | + " },\n" + | |
127 | + " \"type\": \"NUMERIC\"\n" + | |
128 | + " },\n" + | |
129 | + " {\n" + | |
130 | + " \"operation\": \"GREATER\",\n" + | |
131 | + " \"value\": {\n" + | |
132 | + " \"userValue\": null,\n" + | |
133 | + " \"defaultValue\": 20,\n" + | |
134 | + " \"dynamicValue\": null\n" + | |
135 | + " },\n" + | |
136 | + " \"type\": \"NUMERIC\"\n" + | |
137 | + " }\n" + | |
138 | + " ]\n" + | |
139 | + "}" + | |
140 | + MARKDOWN_CODE_BLOCK_END + NEW_LINE + | |
141 | + "More complex predicate example, to check 'value < 10 or (value > 50 && value < 60)': " + NEW_LINE + | |
142 | + MARKDOWN_CODE_BLOCK_START + | |
143 | + "{\n" + | |
144 | + " \"type\": \"COMPLEX\",\n" + | |
145 | + " \"operation\": \"OR\",\n" + | |
146 | + " \"predicates\": [\n" + | |
147 | + " {\n" + | |
148 | + " \"operation\": \"LESS\",\n" + | |
149 | + " \"value\": {\n" + | |
150 | + " \"userValue\": null,\n" + | |
151 | + " \"defaultValue\": 10,\n" + | |
152 | + " \"dynamicValue\": null\n" + | |
153 | + " },\n" + | |
154 | + " \"type\": \"NUMERIC\"\n" + | |
155 | + " },\n" + | |
156 | + " {\n" + | |
157 | + " \"type\": \"COMPLEX\",\n" + | |
158 | + " \"operation\": \"AND\",\n" + | |
159 | + " \"predicates\": [\n" + | |
160 | + " {\n" + | |
161 | + " \"operation\": \"GREATER\",\n" + | |
162 | + " \"value\": {\n" + | |
163 | + " \"userValue\": null,\n" + | |
164 | + " \"defaultValue\": 50,\n" + | |
165 | + " \"dynamicValue\": null\n" + | |
166 | + " },\n" + | |
167 | + " \"type\": \"NUMERIC\"\n" + | |
168 | + " },\n" + | |
169 | + " {\n" + | |
170 | + " \"operation\": \"LESS\",\n" + | |
171 | + " \"value\": {\n" + | |
172 | + " \"userValue\": null,\n" + | |
173 | + " \"defaultValue\": 60,\n" + | |
174 | + " \"dynamicValue\": null\n" + | |
175 | + " },\n" + | |
176 | + " \"type\": \"NUMERIC\"\n" + | |
177 | + " }\n" + | |
178 | + " ]\n" + | |
179 | + " }\n" + | |
180 | + " ]\n" + | |
181 | + "}" + | |
182 | + MARKDOWN_CODE_BLOCK_END + NEW_LINE + | |
183 | + "You may also want to replace hardcoded values (for example, temperature > 20) with the more dynamic " + | |
184 | + "expression (for example, temperature > value of the tenant attribute with key 'temperatureThreshold'). " + | |
185 | + "It is possible to use 'dynamicValue' to define attribute of the tenant, customer or device. " + | |
186 | + "See example below:" + NEW_LINE + | |
187 | + MARKDOWN_CODE_BLOCK_START + | |
188 | + "{\n" + | |
189 | + " \"operation\": \"GREATER\",\n" + | |
190 | + " \"value\": {\n" + | |
191 | + " \"userValue\": null,\n" + | |
192 | + " \"defaultValue\": 0,\n" + | |
193 | + " \"dynamicValue\": {\n" + | |
194 | + " \"inherit\": false,\n" + | |
195 | + " \"sourceType\": \"CURRENT_TENANT\",\n" + | |
196 | + " \"sourceAttribute\": \"temperatureThreshold\"\n" + | |
197 | + " }\n" + | |
198 | + " },\n" + | |
199 | + " \"type\": \"NUMERIC\"\n" + | |
200 | + "}" + | |
201 | + MARKDOWN_CODE_BLOCK_END + NEW_LINE + | |
202 | + "Note 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. " + | |
203 | + "The 'sourceAttribute' can be inherited from the owner of the specified 'sourceType' if 'inherit' is set to true."; | |
204 | + | |
205 | + private static final String KEY_FILTERS_DESCRIPTION = "# Key Filters" + NEW_LINE + | |
206 | + "Key filter objects are created under the **'condition'** array. They allow you to define complex logical expressions over entity field, " + | |
207 | + "attribute, latest time-series value or constant. The filter is defined using 'key', 'valueType', " + | |
208 | + "'value' (refers to the value of the 'CONSTANT' alarm filter key type) and 'predicate' objects. Let's review each object:" + NEW_LINE + | |
209 | + ALARM_FILTER_KEY + FILTER_VALUE_TYPE + NEW_LINE + FILTER_PREDICATE + NEW_LINE; | |
210 | + | |
211 | + private static final String DEFAULT_DEVICE_PROFILE_DATA_EXAMPLE = MARKDOWN_CODE_BLOCK_START + "{\n" + | |
212 | + " \"alarms\":[\n" + | |
213 | + " ],\n" + | |
214 | + " \"configuration\":{\n" + | |
215 | + " \"type\":\"DEFAULT\"\n" + | |
216 | + " },\n" + | |
217 | + " \"provisionConfiguration\":{\n" + | |
218 | + " \"type\":\"DISABLED\",\n" + | |
219 | + " \"provisionDeviceSecret\":null\n" + | |
220 | + " },\n" + | |
221 | + " \"transportConfiguration\":{\n" + | |
222 | + " \"type\":\"DEFAULT\"\n" + | |
223 | + " }\n" + | |
224 | + "}" + MARKDOWN_CODE_BLOCK_END; | |
225 | + | |
226 | + private static final String CUSTOM_DEVICE_PROFILE_DATA_EXAMPLE = MARKDOWN_CODE_BLOCK_START + "{\n" + | |
227 | + " \"alarms\":[\n" + | |
228 | + " {\n" + | |
229 | + " \"id\":\"2492b935-1226-59e9-8615-17d8978a4f93\",\n" + | |
230 | + " \"alarmType\":\"Temperature Alarm\",\n" + | |
231 | + " \"clearRule\":{\n" + | |
232 | + " \"schedule\":null,\n" + | |
233 | + " \"condition\":{\n" + | |
234 | + " \"spec\":{\n" + | |
235 | + " \"type\":\"SIMPLE\"\n" + | |
236 | + " },\n" + | |
237 | + " \"condition\":[\n" + | |
238 | + " {\n" + | |
239 | + " \"key\":{\n" + | |
240 | + " \"key\":\"temperature\",\n" + | |
241 | + " \"type\":\"TIME_SERIES\"\n" + | |
242 | + " },\n" + | |
243 | + " \"value\":null,\n" + | |
244 | + " \"predicate\":{\n" + | |
245 | + " \"type\":\"NUMERIC\",\n" + | |
246 | + " \"value\":{\n" + | |
247 | + " \"userValue\":null,\n" + | |
248 | + " \"defaultValue\":30.0,\n" + | |
249 | + " \"dynamicValue\":null\n" + | |
250 | + " },\n" + | |
251 | + " \"operation\":\"LESS\"\n" + | |
252 | + " },\n" + | |
253 | + " \"valueType\":\"NUMERIC\"\n" + | |
254 | + " }\n" + | |
255 | + " ]\n" + | |
256 | + " },\n" + | |
257 | + " \"dashboardId\":null,\n" + | |
258 | + " \"alarmDetails\":null\n" + | |
259 | + " },\n" + | |
260 | + " \"propagate\":false,\n" + | |
261 | + " \"createRules\":{\n" + | |
262 | + " \"MAJOR\":{\n" + | |
263 | + " \"schedule\":{\n" + | |
264 | + " \"type\":\"SPECIFIC_TIME\",\n" + | |
265 | + " \"endsOn\":64800000,\n" + | |
266 | + " \"startsOn\":43200000,\n" + | |
267 | + " \"timezone\":\"Europe/Kiev\",\n" + | |
268 | + " \"daysOfWeek\":[\n" + | |
269 | + " 1,\n" + | |
270 | + " 3,\n" + | |
271 | + " 5\n" + | |
272 | + " ]\n" + | |
273 | + " },\n" + | |
274 | + " \"condition\":{\n" + | |
275 | + " \"spec\":{\n" + | |
276 | + " \"type\":\"DURATION\",\n" + | |
277 | + " \"unit\":\"MINUTES\",\n" + | |
278 | + " \"predicate\":{\n" + | |
279 | + " \"userValue\":null,\n" + | |
280 | + " \"defaultValue\":30,\n" + | |
281 | + " \"dynamicValue\":null\n" + | |
282 | + " }\n" + | |
283 | + " },\n" + | |
284 | + " \"condition\":[\n" + | |
285 | + " {\n" + | |
286 | + " \"key\":{\n" + | |
287 | + " \"key\":\"temperature\",\n" + | |
288 | + " \"type\":\"TIME_SERIES\"\n" + | |
289 | + " },\n" + | |
290 | + " \"value\":null,\n" + | |
291 | + " \"predicate\":{\n" + | |
292 | + " \"type\":\"COMPLEX\",\n" + | |
293 | + " \"operation\":\"OR\",\n" + | |
294 | + " \"predicates\":[\n" + | |
295 | + " {\n" + | |
296 | + " \"type\":\"NUMERIC\",\n" + | |
297 | + " \"value\":{\n" + | |
298 | + " \"userValue\":null,\n" + | |
299 | + " \"defaultValue\":50.0,\n" + | |
300 | + " \"dynamicValue\":null\n" + | |
301 | + " },\n" + | |
302 | + " \"operation\":\"LESS_OR_EQUAL\"\n" + | |
303 | + " },\n" + | |
304 | + " {\n" + | |
305 | + " \"type\":\"NUMERIC\",\n" + | |
306 | + " \"value\":{\n" + | |
307 | + " \"userValue\":null,\n" + | |
308 | + " \"defaultValue\":30.0,\n" + | |
309 | + " \"dynamicValue\":null\n" + | |
310 | + " },\n" + | |
311 | + " \"operation\":\"GREATER\"\n" + | |
312 | + " }\n" + | |
313 | + " ]\n" + | |
314 | + " },\n" + | |
315 | + " \"valueType\":\"NUMERIC\"\n" + | |
316 | + " }\n" + | |
317 | + " ]\n" + | |
318 | + " },\n" + | |
319 | + " \"dashboardId\":null,\n" + | |
320 | + " \"alarmDetails\":null\n" + | |
321 | + " },\n" + | |
322 | + " \"WARNING\":{\n" + | |
323 | + " \"schedule\":{\n" + | |
324 | + " \"type\":\"CUSTOM\",\n" + | |
325 | + " \"items\":[\n" + | |
326 | + " {\n" + | |
327 | + " \"endsOn\":0,\n" + | |
328 | + " \"enabled\":false,\n" + | |
329 | + " \"startsOn\":0,\n" + | |
330 | + " \"dayOfWeek\":1\n" + | |
331 | + " },\n" + | |
332 | + " {\n" + | |
333 | + " \"endsOn\":64800000,\n" + | |
334 | + " \"enabled\":true,\n" + | |
335 | + " \"startsOn\":43200000,\n" + | |
336 | + " \"dayOfWeek\":2\n" + | |
337 | + " },\n" + | |
338 | + " {\n" + | |
339 | + " \"endsOn\":0,\n" + | |
340 | + " \"enabled\":false,\n" + | |
341 | + " \"startsOn\":0,\n" + | |
342 | + " \"dayOfWeek\":3\n" + | |
343 | + " },\n" + | |
344 | + " {\n" + | |
345 | + " \"endsOn\":57600000,\n" + | |
346 | + " \"enabled\":true,\n" + | |
347 | + " \"startsOn\":36000000,\n" + | |
348 | + " \"dayOfWeek\":4\n" + | |
349 | + " },\n" + | |
350 | + " {\n" + | |
351 | + " \"endsOn\":0,\n" + | |
352 | + " \"enabled\":false,\n" + | |
353 | + " \"startsOn\":0,\n" + | |
354 | + " \"dayOfWeek\":5\n" + | |
355 | + " },\n" + | |
356 | + " {\n" + | |
357 | + " \"endsOn\":0,\n" + | |
358 | + " \"enabled\":false,\n" + | |
359 | + " \"startsOn\":0,\n" + | |
360 | + " \"dayOfWeek\":6\n" + | |
361 | + " },\n" + | |
362 | + " {\n" + | |
363 | + " \"endsOn\":0,\n" + | |
364 | + " \"enabled\":false,\n" + | |
365 | + " \"startsOn\":0,\n" + | |
366 | + " \"dayOfWeek\":7\n" + | |
367 | + " }\n" + | |
368 | + " ],\n" + | |
369 | + " \"timezone\":\"Europe/Kiev\"\n" + | |
370 | + " },\n" + | |
371 | + " \"condition\":{\n" + | |
372 | + " \"spec\":{\n" + | |
373 | + " \"type\":\"REPEATING\",\n" + | |
374 | + " \"predicate\":{\n" + | |
375 | + " \"userValue\":null,\n" + | |
376 | + " \"defaultValue\":5,\n" + | |
377 | + " \"dynamicValue\":null\n" + | |
378 | + " }\n" + | |
379 | + " },\n" + | |
380 | + " \"condition\":[\n" + | |
381 | + " {\n" + | |
382 | + " \"key\":{\n" + | |
383 | + " \"key\":\"tempConstant\",\n" + | |
384 | + " \"type\":\"CONSTANT\"\n" + | |
385 | + " },\n" + | |
386 | + " \"value\":30,\n" + | |
387 | + " \"predicate\":{\n" + | |
388 | + " \"type\":\"NUMERIC\",\n" + | |
389 | + " \"value\":{\n" + | |
390 | + " \"userValue\":null,\n" + | |
391 | + " \"defaultValue\":0.0,\n" + | |
392 | + " \"dynamicValue\":{\n" + | |
393 | + " \"inherit\":false,\n" + | |
394 | + " \"sourceType\":\"CURRENT_DEVICE\",\n" + | |
395 | + " \"sourceAttribute\":\"tempThreshold\"\n" + | |
396 | + " }\n" + | |
397 | + " },\n" + | |
398 | + " \"operation\":\"EQUAL\"\n" + | |
399 | + " },\n" + | |
400 | + " \"valueType\":\"NUMERIC\"\n" + | |
401 | + " }\n" + | |
402 | + " ]\n" + | |
403 | + " },\n" + | |
404 | + " \"dashboardId\":null,\n" + | |
405 | + " \"alarmDetails\":null\n" + | |
406 | + " },\n" + | |
407 | + " \"CRITICAL\":{\n" + | |
408 | + " \"schedule\":null,\n" + | |
409 | + " \"condition\":{\n" + | |
410 | + " \"spec\":{\n" + | |
411 | + " \"type\":\"SIMPLE\"\n" + | |
412 | + " },\n" + | |
413 | + " \"condition\":[\n" + | |
414 | + " {\n" + | |
415 | + " \"key\":{\n" + | |
416 | + " \"key\":\"temperature\",\n" + | |
417 | + " \"type\":\"TIME_SERIES\"\n" + | |
418 | + " },\n" + | |
419 | + " \"value\":null,\n" + | |
420 | + " \"predicate\":{\n" + | |
421 | + " \"type\":\"NUMERIC\",\n" + | |
422 | + " \"value\":{\n" + | |
423 | + " \"userValue\":null,\n" + | |
424 | + " \"defaultValue\":50.0,\n" + | |
425 | + " \"dynamicValue\":null\n" + | |
426 | + " },\n" + | |
427 | + " \"operation\":\"GREATER\"\n" + | |
428 | + " },\n" + | |
429 | + " \"valueType\":\"NUMERIC\"\n" + | |
430 | + " }\n" + | |
431 | + " ]\n" + | |
432 | + " },\n" + | |
433 | + " \"dashboardId\":null,\n" + | |
434 | + " \"alarmDetails\":null\n" + | |
435 | + " }\n" + | |
436 | + " },\n" + | |
437 | + " \"propagateRelationTypes\":null\n" + | |
438 | + " }\n" + | |
439 | + " ],\n" + | |
440 | + " \"configuration\":{\n" + | |
441 | + " \"type\":\"DEFAULT\"\n" + | |
442 | + " },\n" + | |
443 | + " \"provisionConfiguration\":{\n" + | |
444 | + " \"type\":\"ALLOW_CREATE_NEW_DEVICES\",\n" + | |
445 | + " \"provisionDeviceSecret\":\"vaxb9hzqdbz3oqukvomg\"\n" + | |
446 | + " },\n" + | |
447 | + " \"transportConfiguration\":{\n" + | |
448 | + " \"type\":\"MQTT\",\n" + | |
449 | + " \"deviceTelemetryTopic\":\"v1/devices/me/telemetry\",\n" + | |
450 | + " \"deviceAttributesTopic\":\"v1/devices/me/attributes\",\n" + | |
451 | + " \"transportPayloadTypeConfiguration\":{\n" + | |
452 | + " \"transportPayloadType\":\"PROTOBUF\",\n" + | |
453 | + " \"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" + | |
454 | + " \"deviceAttributesProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage attributes;\\n\\nmessage SensorConfiguration {\\n optional string firmwareVersion = 1;\\n optional string serialNumber = 2;\\n}\",\n" + | |
455 | + " \"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" + | |
456 | + " \"deviceRpcResponseProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage rpc;\\n\\nmessage RpcResponseMsg {\\n optional string payload = 1;\\n}\"\n" + | |
457 | + " }\n" + | |
458 | + " }\n" + | |
459 | + "}" + MARKDOWN_CODE_BLOCK_END; | |
460 | + private static final String DEVICE_PROFILE_DATA_DEFINITION = NEW_LINE + "# Device profile data definition" + NEW_LINE + | |
461 | + "Device profile data object contains alarm rules configuration, device provision strategy and transport type configuration for device connectivity. Let's review some examples. " + | |
462 | + "First one is the default device profile data configuration and second one - the custom one. " + | |
463 | + NEW_LINE + DEFAULT_DEVICE_PROFILE_DATA_EXAMPLE + NEW_LINE + CUSTOM_DEVICE_PROFILE_DATA_EXAMPLE + | |
464 | + NEW_LINE + "Let's review some specific objects examples related to the device profile configuration:"; | |
465 | + | |
466 | + private static final String ALARM_SCHEDULE = NEW_LINE + "# Alarm Schedule" + NEW_LINE + | |
467 | + "Alarm Schedule JSON object represents the time interval during which the alarm rule is active. Note, " + | |
468 | + NEW_LINE + DEVICE_PROFILE_ALARM_SCHEDULE_ALWAYS_EXAMPLE + NEW_LINE + "means alarm rule is active all the time. " + | |
469 | + "**'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). " + | |
470 | + "**'enabled'** flag specifies if item in a custom rule is active for specific day of the week:" + NEW_LINE + | |
471 | + "## Specific Time Schedule" + NEW_LINE + | |
472 | + DEVICE_PROFILE_ALARM_SCHEDULE_SPECIFIC_TIME_EXAMPLE + NEW_LINE + | |
473 | + "## Custom Schedule" + | |
474 | + NEW_LINE + DEVICE_PROFILE_ALARM_SCHEDULE_CUSTOM_EXAMPLE + NEW_LINE; | |
475 | + | |
476 | + private static final String ALARM_CONDITION_TYPE = "# Alarm condition type (**'spec'**)" + NEW_LINE + | |
477 | + "Alarm condition type can be either simple, duration, or repeating. For example, 5 times in a row or during 5 minutes." + NEW_LINE + | |
478 | + "Note, **'userValue'** field is not used and reserved for future usage, **'dynamicValue'** is used for condition appliance by using the value of the **'sourceAttribute'** " + | |
479 | + "or else **'defaultValue'** is used (if **'sourceAttribute'** is absent).\n" + | |
480 | + "\n**'sourceType'** of the **'sourceAttribute'** can be: \n" + | |
481 | + " * 'CURRENT_DEVICE';\n" + | |
482 | + " * 'CURRENT_CUSTOMER';\n" + | |
483 | + " * 'CURRENT_TENANT'." + NEW_LINE + | |
484 | + "**'sourceAttribute'** can be inherited from the owner if **'inherit'** is set to true (for CURRENT_DEVICE and CURRENT_CUSTOMER)." + NEW_LINE + | |
485 | + "## Repeating alarm condition" + NEW_LINE + | |
486 | + DEVICE_PROFILE_ALARM_CONDITION_REPEATING_EXAMPLE + NEW_LINE + | |
487 | + "## Duration alarm condition" + NEW_LINE + | |
488 | + DEVICE_PROFILE_ALARM_CONDITION_DURATION_EXAMPLE + NEW_LINE + | |
489 | + "**'unit'** can be: \n" + | |
490 | + " * 'SECONDS';\n" + | |
491 | + " * 'MINUTES';\n" + | |
492 | + " * 'HOURS';\n" + | |
493 | + " * 'DAYS'." + NEW_LINE; | |
494 | + | |
495 | + private static final String PROVISION_CONFIGURATION = "# Provision Configuration" + NEW_LINE + | |
496 | + "There are 3 types of device provision configuration for the device profile: \n" + | |
497 | + " * 'DISABLED';\n" + | |
498 | + " * 'ALLOW_CREATE_NEW_DEVICES';\n" + | |
499 | + " * 'CHECK_PRE_PROVISIONED_DEVICES'." + NEW_LINE + | |
500 | + "Please refer to the [docs](https://thingsboard.io/docs/user-guide/device-provisioning/) for more details." + NEW_LINE; | |
501 | + | |
502 | + private static final String DEVICE_PROFILE_DATA = DEVICE_PROFILE_DATA_DEFINITION + ALARM_SCHEDULE + ALARM_CONDITION_TYPE + | |
503 | + KEY_FILTERS_DESCRIPTION + PROVISION_CONFIGURATION + TRANSPORT_CONFIGURATION; | |
504 | + | |
58 | 505 | private static final String DEVICE_PROFILE_ID = "deviceProfileId"; |
59 | 506 | |
60 | 507 | @Autowired |
... | ... | @@ -169,12 +616,13 @@ public class DeviceProfileController extends BaseController { |
169 | 616 | } |
170 | 617 | } |
171 | 618 | |
172 | - @ApiOperation(value = "Create Or Update Device Profile (saveDevice)", | |
619 | + @ApiOperation(value = "Create Or Update Device Profile (saveDeviceProfile)", | |
173 | 620 | notes = "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). " + |
174 | 621 | "The newly created device profile id will be present in the response. " + |
175 | 622 | "Specify existing device profile id to update the device profile. " + |
176 | - "Referencing non-existing device profile Id will cause 'Not Found' error. " + | |
177 | - "\n\nDevice profile name is unique in the scope of tenant. Only one 'default' device profile may exist in scope of tenant." + TENANT_AUTHORITY_PARAGRAPH, | |
623 | + "Referencing non-existing device profile Id will cause 'Not Found' error. " + NEW_LINE + | |
624 | + "Device profile name is unique in the scope of tenant. Only one 'default' device profile may exist in scope of tenant." + DEVICE_PROFILE_DATA + | |
625 | + TENANT_AUTHORITY_PARAGRAPH, | |
178 | 626 | produces = "application/json", |
179 | 627 | consumes = "application/json") |
180 | 628 | @PreAuthorize("hasAuthority('TENANT_ADMIN')") | ... | ... |
... | ... | @@ -45,7 +45,7 @@ import org.thingsboard.server.service.query.EntityQueryService; |
45 | 45 | public class EntityQueryController extends BaseController { |
46 | 46 | |
47 | 47 | private static final String SINGLE_ENTITY = "\n\n## Single Entity\n\n" + |
48 | - "Allows to filter only one entity based on the id. For example, this entity filter selects certain device:\n\n"+ | |
48 | + "Allows to filter only one entity based on the id. For example, this entity filter selects certain device:\n\n" + | |
49 | 49 | MARKDOWN_CODE_BLOCK_START + |
50 | 50 | "{\n" + |
51 | 51 | " \"type\": \"singleEntity\",\n" + |
... | ... | @@ -53,12 +53,12 @@ public class EntityQueryController extends BaseController { |
53 | 53 | " \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n" + |
54 | 54 | " \"entityType\": \"DEVICE\"\n" + |
55 | 55 | " }\n" + |
56 | - "}"+ | |
56 | + "}" + | |
57 | 57 | MARKDOWN_CODE_BLOCK_END + |
58 | 58 | ""; |
59 | 59 | |
60 | 60 | private static final String ENTITY_LIST = "\n\n## Entity List Filter\n\n" + |
61 | - "Allows to filter entities of the same type using their ids. For example, this entity filter selects two devices:\n\n"+ | |
61 | + "Allows to filter entities of the same type using their ids. For example, this entity filter selects two devices:\n\n" + | |
62 | 62 | MARKDOWN_CODE_BLOCK_START + |
63 | 63 | "{\n" + |
64 | 64 | " \"type\": \"entityList\",\n" + |
... | ... | @@ -67,84 +67,84 @@ public class EntityQueryController extends BaseController { |
67 | 67 | " \"e6501f30-2a7a-11ec-94eb-213c95f54092\",\n" + |
68 | 68 | " \"e6657bf0-2a7a-11ec-94eb-213c95f54092\"\n" + |
69 | 69 | " ]\n" + |
70 | - "}"+ | |
70 | + "}" + | |
71 | 71 | MARKDOWN_CODE_BLOCK_END + |
72 | 72 | ""; |
73 | 73 | |
74 | 74 | private static final String ENTITY_NAME = "\n\n## Entity Name Filter\n\n" + |
75 | 75 | "Allows to filter entities of the same type using the **'starts with'** expression over entity name. " + |
76 | - "For example, this entity filter selects all devices which name starts with 'Air Quality':\n\n"+ | |
76 | + "For example, this entity filter selects all devices which name starts with 'Air Quality':\n\n" + | |
77 | 77 | MARKDOWN_CODE_BLOCK_START + |
78 | 78 | "{\n" + |
79 | 79 | " \"type\": \"entityName\",\n" + |
80 | 80 | " \"entityType\": \"DEVICE\",\n" + |
81 | 81 | " \"entityNameFilter\": \"Air Quality\"\n" + |
82 | - "}"+ | |
82 | + "}" + | |
83 | 83 | MARKDOWN_CODE_BLOCK_END + |
84 | 84 | ""; |
85 | 85 | |
86 | 86 | private static final String ENTITY_TYPE = "\n\n## Entity Type Filter\n\n" + |
87 | 87 | "Allows to filter entities based on their type (CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, etc)" + |
88 | - "For example, this entity filter selects all tenant customers:\n\n"+ | |
88 | + "For example, this entity filter selects all tenant customers:\n\n" + | |
89 | 89 | MARKDOWN_CODE_BLOCK_START + |
90 | 90 | "{\n" + |
91 | 91 | " \"type\": \"entityType\",\n" + |
92 | 92 | " \"entityType\": \"CUSTOMER\"\n" + |
93 | - "}"+ | |
93 | + "}" + | |
94 | 94 | MARKDOWN_CODE_BLOCK_END + |
95 | 95 | ""; |
96 | 96 | |
97 | 97 | private static final String ASSET_TYPE = "\n\n## Asset Type Filter\n\n" + |
98 | 98 | "Allows to filter assets based on their type and the **'starts with'** expression over their name. " + |
99 | - "For example, this entity filter selects all 'charging station' assets which name starts with 'Tesla':\n\n"+ | |
99 | + "For example, this entity filter selects all 'charging station' assets which name starts with 'Tesla':\n\n" + | |
100 | 100 | MARKDOWN_CODE_BLOCK_START + |
101 | 101 | "{\n" + |
102 | 102 | " \"type\": \"assetType\",\n" + |
103 | 103 | " \"assetType\": \"charging station\",\n" + |
104 | 104 | " \"assetNameFilter\": \"Tesla\"\n" + |
105 | - "}"+ | |
105 | + "}" + | |
106 | 106 | MARKDOWN_CODE_BLOCK_END + |
107 | 107 | ""; |
108 | 108 | |
109 | 109 | private static final String DEVICE_TYPE = "\n\n## Device Type Filter\n\n" + |
110 | 110 | "Allows to filter devices based on their type and the **'starts with'** expression over their name. " + |
111 | - "For example, this entity filter selects all 'Temperature Sensor' devices which name starts with 'ABC':\n\n"+ | |
111 | + "For example, this entity filter selects all 'Temperature Sensor' devices which name starts with 'ABC':\n\n" + | |
112 | 112 | MARKDOWN_CODE_BLOCK_START + |
113 | 113 | "{\n" + |
114 | 114 | " \"type\": \"deviceType\",\n" + |
115 | 115 | " \"deviceType\": \"Temperature Sensor\",\n" + |
116 | 116 | " \"deviceNameFilter\": \"ABC\"\n" + |
117 | - "}"+ | |
117 | + "}" + | |
118 | 118 | MARKDOWN_CODE_BLOCK_END + |
119 | 119 | ""; |
120 | 120 | |
121 | 121 | private static final String EDGE_TYPE = "\n\n## Edge Type Filter\n\n" + |
122 | 122 | "Allows to filter edge instances based on their type and the **'starts with'** expression over their name. " + |
123 | - "For example, this entity filter selects all 'Factory' edge instances which name starts with 'Nevada':\n\n"+ | |
123 | + "For example, this entity filter selects all 'Factory' edge instances which name starts with 'Nevada':\n\n" + | |
124 | 124 | MARKDOWN_CODE_BLOCK_START + |
125 | 125 | "{\n" + |
126 | 126 | " \"type\": \"edgeType\",\n" + |
127 | 127 | " \"edgeType\": \"Factory\",\n" + |
128 | 128 | " \"edgeNameFilter\": \"Nevada\"\n" + |
129 | - "}"+ | |
129 | + "}" + | |
130 | 130 | MARKDOWN_CODE_BLOCK_END + |
131 | 131 | ""; |
132 | 132 | |
133 | 133 | private static final String ENTITY_VIEW_TYPE = "\n\n## Entity View Filter\n\n" + |
134 | 134 | "Allows to filter entity views based on their type and the **'starts with'** expression over their name. " + |
135 | - "For example, this entity filter selects all 'Concrete Mixer' entity views which name starts with 'CAT':\n\n"+ | |
135 | + "For example, this entity filter selects all 'Concrete Mixer' entity views which name starts with 'CAT':\n\n" + | |
136 | 136 | MARKDOWN_CODE_BLOCK_START + |
137 | 137 | "{\n" + |
138 | 138 | " \"type\": \"entityViewType\",\n" + |
139 | 139 | " \"entityViewType\": \"Concrete Mixer\",\n" + |
140 | 140 | " \"entityViewNameFilter\": \"CAT\"\n" + |
141 | - "}"+ | |
141 | + "}" + | |
142 | 142 | MARKDOWN_CODE_BLOCK_END + |
143 | 143 | ""; |
144 | 144 | |
145 | 145 | private static final String API_USAGE = "\n\n## Api Usage Filter\n\n" + |
146 | 146 | "Allows to query for Api Usage based on optional customer id. If the customer id is not set, returns current tenant API usage." + |
147 | - "For example, this entity filter selects the 'Api Usage' entity for customer with id 'e6501f30-2a7a-11ec-94eb-213c95f54092':\n\n"+ | |
147 | + "For example, this entity filter selects the 'Api Usage' entity for customer with id 'e6501f30-2a7a-11ec-94eb-213c95f54092':\n\n" + | |
148 | 148 | MARKDOWN_CODE_BLOCK_START + |
149 | 149 | "{\n" + |
150 | 150 | " \"type\": \"apiUsageState\",\n" + |
... | ... | @@ -152,7 +152,7 @@ public class EntityQueryController extends BaseController { |
152 | 152 | " \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n" + |
153 | 153 | " \"entityType\": \"CUSTOMER\"\n" + |
154 | 154 | " }\n" + |
155 | - "}"+ | |
155 | + "}" + | |
156 | 156 | MARKDOWN_CODE_BLOCK_END + |
157 | 157 | ""; |
158 | 158 | |
... | ... | @@ -165,7 +165,7 @@ public class EntityQueryController extends BaseController { |
165 | 165 | FETCH_LAST_LEVEL_ONLY_DESCRIPTION + |
166 | 166 | "The 'filter' object allows you to define the relation type and set of acceptable entity types to search for. " + |
167 | 167 | "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\n" + |
168 | - "For example, this entity filter selects all devices and assets which are related to the asset with id 'e51de0c0-2a7a-11ec-94eb-213c95f54092':\n\n"+ | |
168 | + "For example, this entity filter selects all devices and assets which are related to the asset with id 'e51de0c0-2a7a-11ec-94eb-213c95f54092':\n\n" + | |
169 | 169 | MARKDOWN_CODE_BLOCK_START + |
170 | 170 | "{\n" + |
171 | 171 | " \"type\": \"relationsQuery\",\n" + |
... | ... | @@ -185,7 +185,7 @@ public class EntityQueryController extends BaseController { |
185 | 185 | " ]\n" + |
186 | 186 | " }\n" + |
187 | 187 | " ]\n" + |
188 | - "}"+ | |
188 | + "}" + | |
189 | 189 | MARKDOWN_CODE_BLOCK_END + |
190 | 190 | ""; |
191 | 191 | |
... | ... | @@ -197,7 +197,7 @@ public class EntityQueryController extends BaseController { |
197 | 197 | "The 'relationType' defines the type of the relation to search for. " + |
198 | 198 | "The 'assetTypes' defines the type of the asset to search for. " + |
199 | 199 | "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\n" + |
200 | - "For 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"+ | |
200 | + "For 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" + | |
201 | 201 | MARKDOWN_CODE_BLOCK_START + |
202 | 202 | "{\n" + |
203 | 203 | " \"type\": \"assetSearchQuery\",\n" + |
... | ... | @@ -212,7 +212,7 @@ public class EntityQueryController extends BaseController { |
212 | 212 | " \"assetTypes\": [\n" + |
213 | 213 | " \"charging station\"\n" + |
214 | 214 | " ]\n" + |
215 | - "}"+ | |
215 | + "}" + | |
216 | 216 | MARKDOWN_CODE_BLOCK_END + |
217 | 217 | ""; |
218 | 218 | |
... | ... | @@ -223,7 +223,7 @@ public class EntityQueryController extends BaseController { |
223 | 223 | "The 'relationType' defines the type of the relation to search for. " + |
224 | 224 | "The 'deviceTypes' defines the type of the device to search for. " + |
225 | 225 | "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\n" + |
226 | - "For 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"+ | |
226 | + "For 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" + | |
227 | 227 | MARKDOWN_CODE_BLOCK_START + |
228 | 228 | "{\n" + |
229 | 229 | " \"type\": \"deviceSearchQuery\",\n" + |
... | ... | @@ -239,7 +239,7 @@ public class EntityQueryController extends BaseController { |
239 | 239 | " \"Air Quality Sensor\",\n" + |
240 | 240 | " \"Charging port\"\n" + |
241 | 241 | " ]\n" + |
242 | - "}"+ | |
242 | + "}" + | |
243 | 243 | MARKDOWN_CODE_BLOCK_END + |
244 | 244 | ""; |
245 | 245 | |
... | ... | @@ -250,7 +250,7 @@ public class EntityQueryController extends BaseController { |
250 | 250 | "The 'relationType' defines the type of the relation to search for. " + |
251 | 251 | "The 'entityViewTypes' defines the type of the entity view to search for. " + |
252 | 252 | "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\n" + |
253 | - "For 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"+ | |
253 | + "For 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" + | |
254 | 254 | MARKDOWN_CODE_BLOCK_START + |
255 | 255 | "{\n" + |
256 | 256 | " \"type\": \"entityViewSearchQuery\",\n" + |
... | ... | @@ -265,7 +265,7 @@ public class EntityQueryController extends BaseController { |
265 | 265 | " \"entityViewTypes\": [\n" + |
266 | 266 | " \"Concrete mixer\"\n" + |
267 | 267 | " ]\n" + |
268 | - "}"+ | |
268 | + "}" + | |
269 | 269 | MARKDOWN_CODE_BLOCK_END + |
270 | 270 | ""; |
271 | 271 | |
... | ... | @@ -276,7 +276,7 @@ public class EntityQueryController extends BaseController { |
276 | 276 | "The 'relationType' defines the type of the relation to search for. " + |
277 | 277 | "The 'deviceTypes' defines the type of the device to search for. " + |
278 | 278 | "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\n" + |
279 | - "For 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"+ | |
279 | + "For 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" + | |
280 | 280 | MARKDOWN_CODE_BLOCK_START + |
281 | 281 | "{\n" + |
282 | 282 | " \"type\": \"deviceSearchQuery\",\n" + |
... | ... | @@ -291,27 +291,27 @@ public class EntityQueryController extends BaseController { |
291 | 291 | " \"edgeTypes\": [\n" + |
292 | 292 | " \"Factory\"\n" + |
293 | 293 | " ]\n" + |
294 | - "}"+ | |
294 | + "}" + | |
295 | 295 | MARKDOWN_CODE_BLOCK_END + |
296 | 296 | ""; |
297 | 297 | |
298 | 298 | private static final String EMPTY = "\n\n## Entity Type Filter\n\n" + |
299 | 299 | "Allows to filter multiple entities of the same type using the **'starts with'** expression over entity name. " + |
300 | - "For example, this entity filter selects all devices which name starts with 'Air Quality':\n\n"+ | |
300 | + "For example, this entity filter selects all devices which name starts with 'Air Quality':\n\n" + | |
301 | 301 | MARKDOWN_CODE_BLOCK_START + |
302 | - ""+ | |
302 | + "" + | |
303 | 303 | MARKDOWN_CODE_BLOCK_END + |
304 | 304 | ""; |
305 | 305 | |
306 | 306 | private static final String ENTITY_FILTERS = |
307 | 307 | "\n\n # Entity Filters" + |
308 | - "\nEntity Filter body depends on the 'type' parameter. Let's review available entity filter types. In fact, they do correspond to available dashboard aliases." + | |
309 | - SINGLE_ENTITY + ENTITY_LIST + ENTITY_NAME + ENTITY_TYPE + ASSET_TYPE + DEVICE_TYPE + EDGE_TYPE + ENTITY_VIEW_TYPE + API_USAGE + RELATIONS_QUERY_FILTER | |
310 | - + ASSET_QUERY_FILTER + DEVICE_QUERY_FILTER + EV_QUERY_FILTER + EDGE_QUERY_FILTER; | |
308 | + "\nEntity Filter body depends on the 'type' parameter. Let's review available entity filter types. In fact, they do correspond to available dashboard aliases." + | |
309 | + SINGLE_ENTITY + ENTITY_LIST + ENTITY_NAME + ENTITY_TYPE + ASSET_TYPE + DEVICE_TYPE + EDGE_TYPE + ENTITY_VIEW_TYPE + API_USAGE + RELATIONS_QUERY_FILTER | |
310 | + + ASSET_QUERY_FILTER + DEVICE_QUERY_FILTER + EV_QUERY_FILTER + EDGE_QUERY_FILTER; | |
311 | 311 | |
312 | 312 | private static final String FILTER_KEY = "\n\n## Filter Key\n\n" + |
313 | 313 | "Filter Key defines either entity field, attribute or telemetry. It is a JSON object that consists the key name and type. " + |
314 | - "The following filter key types are supported: \n\n"+ | |
314 | + "The following filter key types are supported: \n\n" + | |
315 | 315 | " * 'CLIENT_ATTRIBUTE' - used for client attributes; \n" + |
316 | 316 | " * 'SHARED_ATTRIBUTE' - used for shared attributes; \n" + |
317 | 317 | " * 'SERVER_ATTRIBUTE' - used for server attributes; \n" + |
... | ... | @@ -328,19 +328,10 @@ public class EntityQueryController extends BaseController { |
328 | 328 | MARKDOWN_CODE_BLOCK_END + |
329 | 329 | ""; |
330 | 330 | |
331 | - private static final String FILTER_VALUE_TYPE = "\n\n## Value Type and Operations\n\n" + | |
332 | - "Provides a hint about the data type of the entity field that is defined in the filter key. " + | |
333 | - "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." + | |
334 | - "The following filter value types and corresponding predicate operations are supported: \n\n"+ | |
335 | - " * 'STRING' - used to filter any 'String' or 'JSON' values. Operations: EQUAL, NOT_EQUAL, STARTS_WITH, ENDS_WITH, CONTAINS, NOT_CONTAINS; \n" + | |
336 | - " * 'NUMERIC' - used for 'Long' and 'Double' values. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n" + | |
337 | - " * 'BOOLEAN' - used for boolean values; Operations: EQUAL, NOT_EQUAL \n" + | |
338 | - " * 'DATE_TIME' - similar to numeric, transforms value to milliseconds since epoch. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n"; | |
339 | - | |
340 | 331 | private static final String FILTER_PREDICATE = "\n\n## Filter Predicate\n\n" + |
341 | 332 | "Filter Predicate defines the logical expression to evaluate. The list of available operations depends on the filter value type, see above. " + |
342 | 333 | "Platform supports 4 predicate types: 'STRING', 'NUMERIC', 'BOOLEAN' and 'COMPLEX'. The last one allows to combine multiple operations over one filter key." + |
343 | - "\n\nSimple predicate example to check 'value < 100': \n\n"+ | |
334 | + "\n\nSimple predicate example to check 'value < 100': \n\n" + | |
344 | 335 | MARKDOWN_CODE_BLOCK_START + |
345 | 336 | "{\n" + |
346 | 337 | " \"operation\": \"LESS\",\n" + |
... | ... | @@ -351,7 +342,7 @@ public class EntityQueryController extends BaseController { |
351 | 342 | " \"type\": \"NUMERIC\"\n" + |
352 | 343 | "}" + |
353 | 344 | MARKDOWN_CODE_BLOCK_END + |
354 | - "\n\nComplex predicate example, to check 'value < 10 or value > 20': \n\n"+ | |
345 | + "\n\nComplex predicate example, to check 'value < 10 or value > 20': \n\n" + | |
355 | 346 | MARKDOWN_CODE_BLOCK_START + |
356 | 347 | "{\n" + |
357 | 348 | " \"type\": \"COMPLEX\",\n" + |
... | ... | @@ -376,7 +367,7 @@ public class EntityQueryController extends BaseController { |
376 | 367 | " ]\n" + |
377 | 368 | "}" + |
378 | 369 | MARKDOWN_CODE_BLOCK_END + |
379 | - "\n\nMore complex predicate example, to check 'value < 10 or (value > 50 && value < 60)': \n\n"+ | |
370 | + "\n\nMore complex predicate example, to check 'value < 10 or (value > 50 && value < 60)': \n\n" + | |
380 | 371 | MARKDOWN_CODE_BLOCK_START + |
381 | 372 | "{\n" + |
382 | 373 | " \"type\": \"COMPLEX\",\n" + |
... | ... | @@ -461,16 +452,16 @@ public class EntityQueryController extends BaseController { |
461 | 452 | |
462 | 453 | private static final String ENTITY_COUNT_QUERY_DESCRIPTION = |
463 | 454 | "Allows to run complex queries to search the count of platform entities (devices, assets, customers, etc) " + |
464 | - "based on the combination of main entity filter and multiple key filters. Returns the number of entities that match the query definition.\n\n" + | |
465 | - "# Query Definition\n\n" + | |
466 | - "\n\nMain **entity filter** is mandatory and defines generic search criteria. " + | |
455 | + "based on the combination of main entity filter and multiple key filters. Returns the number of entities that match the query definition.\n\n" + | |
456 | + "# Query Definition\n\n" + | |
457 | + "\n\nMain **entity filter** is mandatory and defines generic search criteria. " + | |
467 | 458 | "For example, \"find all devices with profile 'Moisture Sensor'\" or \"Find all devices related to asset 'Building A'\"" + |
468 | - "\n\nOptional **key filters** allow to filter results of the entity filter by complex criteria against " + | |
469 | - "main entity fields (name, label, type, etc), attributes and telemetry. " + | |
470 | - "For example, \"temperature > 20 or temperature< 10\" or \"name starts with 'T', and attribute 'model' is 'T1000', and timeseries field 'batteryLevel' > 40\"."+ | |
471 | - "\n\nLet's review the example:" + | |
472 | - "\n\n" + MARKDOWN_CODE_BLOCK_START + | |
473 | - "{\n" + | |
459 | + "\n\nOptional **key filters** allow to filter results of the entity filter by complex criteria against " + | |
460 | + "main entity fields (name, label, type, etc), attributes and telemetry. " + | |
461 | + "For example, \"temperature > 20 or temperature< 10\" or \"name starts with 'T', and attribute 'model' is 'T1000', and timeseries field 'batteryLevel' > 40\"." + | |
462 | + "\n\nLet's review the example:" + | |
463 | + "\n\n" + MARKDOWN_CODE_BLOCK_START + | |
464 | + "{\n" + | |
474 | 465 | " \"entityFilter\": {\n" + |
475 | 466 | " \"type\": \"entityType\",\n" + |
476 | 467 | " \"entityType\": \"DEVICE\"\n" + |
... | ... | @@ -492,12 +483,12 @@ public class EntityQueryController extends BaseController { |
492 | 483 | " }\n" + |
493 | 484 | " }\n" + |
494 | 485 | " ]\n" + |
495 | - "}"+ | |
496 | - MARKDOWN_CODE_BLOCK_END + | |
497 | - "\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:" + | |
498 | - ENTITY_FILTERS + | |
499 | - KEY_FILTERS + | |
500 | - TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;; | |
486 | + "}" + | |
487 | + MARKDOWN_CODE_BLOCK_END + | |
488 | + "\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:" + | |
489 | + ENTITY_FILTERS + | |
490 | + KEY_FILTERS + | |
491 | + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH; | |
501 | 492 | |
502 | 493 | private static final String ENTITY_DATA_QUERY_DESCRIPTION = |
503 | 494 | "Allows to run complex queries over platform entities (devices, assets, customers, etc) " + |
... | ... | @@ -508,7 +499,7 @@ public class EntityQueryController extends BaseController { |
508 | 499 | "For example, \"find all devices with profile 'Moisture Sensor'\" or \"Find all devices related to asset 'Building A'\"" + |
509 | 500 | "\n\nOptional **key filters** allow to filter results of the **entity filter** by complex criteria against " + |
510 | 501 | "main entity fields (name, label, type, etc), attributes and telemetry. " + |
511 | - "For example, \"temperature > 20 or temperature< 10\" or \"name starts with 'T', and attribute 'model' is 'T1000', and timeseries field 'batteryLevel' > 40\"."+ | |
502 | + "For example, \"temperature > 20 or temperature< 10\" or \"name starts with 'T', and attribute 'model' is 'T1000', and timeseries field 'batteryLevel' > 40\"." + | |
512 | 503 | "\n\nThe **entity fields** and **latest values** contains list of entity fields and latest attribute/telemetry fields to fetch for each entity." + |
513 | 504 | "\n\nThe **page link** contains information about the page to fetch and the sort ordering." + |
514 | 505 | "\n\nLet's review the example:" + |
... | ... | @@ -575,7 +566,7 @@ public class EntityQueryController extends BaseController { |
575 | 566 | " \"direction\": \"ASC\"\n" + |
576 | 567 | " }\n" + |
577 | 568 | " }\n" + |
578 | - "}"+ | |
569 | + "}" + | |
579 | 570 | MARKDOWN_CODE_BLOCK_END + |
580 | 571 | "\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:" + |
581 | 572 | ENTITY_FILTERS + |
... | ... | @@ -672,7 +663,7 @@ public class EntityQueryController extends BaseController { |
672 | 663 | " \"key\": \"temperature\"\n" + |
673 | 664 | " }\n" + |
674 | 665 | " ]\n" + |
675 | - "}"+ | |
666 | + "}" + | |
676 | 667 | MARKDOWN_CODE_BLOCK_END + |
677 | 668 | ""; |
678 | 669 | ... | ... |
... | ... | @@ -45,8 +45,6 @@ import org.thingsboard.server.service.security.permission.Operation; |
45 | 45 | @RequestMapping("/api") |
46 | 46 | public class EventController extends BaseController { |
47 | 47 | |
48 | - private static final String NEW_LINE = "\n\n"; | |
49 | - | |
50 | 48 | @Autowired |
51 | 49 | private EventService eventService; |
52 | 50 | ... | ... |
... | ... | @@ -69,8 +69,8 @@ public class Alarm extends BaseData<AlarmId> implements HasName, HasTenantId, Ha |
69 | 69 | @ApiModelProperty(position = 15, value = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") |
70 | 70 | private boolean propagate; |
71 | 71 | @ApiModelProperty(position = 16, value = "JSON array of relation types that should be used for propagation. " + |
72 | - "By default, 'propagateRelationTypes' array is empty which means that the alarm will propagate based on any relation type to parent entities. " + | |
73 | - "This parameter should be used only in case when 'propagate' parameter is set to true, otherwise, 'propagateRelationTypes' array will ignoned.") | |
72 | + "By default, 'propagateRelationTypes' array is empty which means that the alarm will be propagated based on any relation type to parent entities. " + | |
73 | + "This parameter should be used only in case when 'propagate' parameter is set to true, otherwise, 'propagateRelationTypes' array will be ignored.") | |
74 | 74 | private List<String> propagateRelationTypes; |
75 | 75 | |
76 | 76 | public Alarm() { | ... | ... |
... | ... | @@ -16,13 +16,16 @@ |
16 | 16 | package org.thingsboard.server.common.data.device.data; |
17 | 17 | |
18 | 18 | import io.swagger.annotations.ApiModel; |
19 | +import io.swagger.annotations.ApiModelProperty; | |
19 | 20 | import lombok.Data; |
20 | 21 | |
21 | 22 | @ApiModel |
22 | 23 | @Data |
23 | 24 | public class DeviceData { |
24 | 25 | |
26 | + @ApiModelProperty(position = 1, value = "Device configuration for device profile type. DEFAULT is only supported value for now") | |
25 | 27 | private DeviceConfiguration configuration; |
28 | + @ApiModelProperty(position = 2, value = "Device transport configuration used to connect the device") | |
26 | 29 | private DeviceTransportConfiguration transportConfiguration; |
27 | 30 | |
28 | 31 | } | ... | ... |
... | ... | @@ -16,18 +16,23 @@ |
16 | 16 | package org.thingsboard.server.common.data.device.profile; |
17 | 17 | |
18 | 18 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
19 | +import io.swagger.annotations.ApiModel; | |
20 | +import io.swagger.annotations.ApiModelProperty; | |
19 | 21 | import lombok.Data; |
20 | 22 | |
21 | 23 | import java.io.Serializable; |
22 | 24 | import javax.validation.Valid; |
23 | 25 | import java.util.List; |
24 | 26 | |
27 | +@ApiModel | |
25 | 28 | @Data |
26 | 29 | @JsonIgnoreProperties(ignoreUnknown = true) |
27 | 30 | public class AlarmCondition implements Serializable { |
28 | 31 | |
29 | 32 | @Valid |
33 | + @ApiModelProperty(position = 1, value = "JSON array of alarm condition filters") | |
30 | 34 | private List<AlarmConditionFilter> condition; |
35 | + @ApiModelProperty(position = 2, value = "JSON object representing alarm condition type") | |
31 | 36 | private AlarmConditionSpec spec; |
32 | 37 | |
33 | 38 | } | ... | ... |
... | ... | @@ -15,6 +15,8 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.device.profile; |
17 | 17 | |
18 | +import io.swagger.annotations.ApiModel; | |
19 | +import io.swagger.annotations.ApiModelProperty; | |
18 | 20 | import lombok.Data; |
19 | 21 | import org.thingsboard.server.common.data.query.EntityKeyValueType; |
20 | 22 | import org.thingsboard.server.common.data.query.KeyFilterPredicate; |
... | ... | @@ -24,15 +26,20 @@ import javax.validation.Valid; |
24 | 26 | |
25 | 27 | import java.io.Serializable; |
26 | 28 | |
29 | +@ApiModel | |
27 | 30 | @Data |
28 | 31 | public class AlarmConditionFilter implements Serializable { |
29 | 32 | |
30 | 33 | @Valid |
34 | + @ApiModelProperty(position = 1, value = "JSON object for specifying alarm condition by specific key") | |
31 | 35 | private AlarmConditionFilterKey key; |
36 | + @ApiModelProperty(position = 2, value = "String representation of the type of the value", example = "NUMERIC") | |
32 | 37 | private EntityKeyValueType valueType; |
33 | 38 | @NoXss |
39 | + @ApiModelProperty(position = 3, value = "Value used in Constant comparison. For other types, such as TIME_SERIES or ATTRIBUTE, the predicate condition is used") | |
34 | 40 | private Object value; |
35 | 41 | @Valid |
42 | + @ApiModelProperty(position = 4, value = "JSON object representing filter condition") | |
36 | 43 | private KeyFilterPredicate predicate; |
37 | 44 | |
38 | 45 | } | ... | ... |
... | ... | @@ -15,16 +15,21 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.device.profile; |
17 | 17 | |
18 | +import io.swagger.annotations.ApiModel; | |
19 | +import io.swagger.annotations.ApiModelProperty; | |
18 | 20 | import lombok.Data; |
19 | 21 | import org.thingsboard.server.common.data.validation.NoXss; |
20 | 22 | |
21 | 23 | import java.io.Serializable; |
22 | 24 | |
25 | +@ApiModel | |
23 | 26 | @Data |
24 | 27 | public class AlarmConditionFilterKey implements Serializable { |
25 | 28 | |
29 | + @ApiModelProperty(position = 1, value = "The key type", example = "TIME_SERIES") | |
26 | 30 | private final AlarmConditionKeyType type; |
27 | 31 | @NoXss |
32 | + @ApiModelProperty(position = 2, value = "String value representing the key", example = "temp") | |
28 | 33 | private final String key; |
29 | 34 | |
30 | 35 | } | ... | ... |
... | ... | @@ -15,6 +15,8 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.device.profile; |
17 | 17 | |
18 | +import io.swagger.annotations.ApiModel; | |
19 | +import io.swagger.annotations.ApiModelProperty; | |
18 | 20 | import lombok.Data; |
19 | 21 | import org.thingsboard.server.common.data.id.DashboardId; |
20 | 22 | import org.thingsboard.server.common.data.validation.NoXss; |
... | ... | @@ -23,15 +25,20 @@ import javax.validation.Valid; |
23 | 25 | |
24 | 26 | import java.io.Serializable; |
25 | 27 | |
28 | +@ApiModel | |
26 | 29 | @Data |
27 | 30 | public class AlarmRule implements Serializable { |
28 | 31 | |
29 | 32 | @Valid |
33 | + @ApiModelProperty(position = 1, value = "JSON object representing the alarm rule condition") | |
30 | 34 | private AlarmCondition condition; |
35 | + @ApiModelProperty(position = 2, value = "JSON object representing time interval during which the rule is active") | |
31 | 36 | private AlarmSchedule schedule; |
32 | 37 | // Advanced |
33 | 38 | @NoXss |
39 | + @ApiModelProperty(position = 3, value = "String value representing the additional details for an alarm rule") | |
34 | 40 | private String alarmDetails; |
41 | + @ApiModelProperty(position = 4, value = "JSON object with the dashboard Id representing the reference to alarm details dashboard used by mobile application") | |
35 | 42 | private DashboardId dashboardId; |
36 | 43 | |
37 | 44 | } | ... | ... |
... | ... | @@ -15,28 +15,40 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.device.profile; |
17 | 17 | |
18 | +import io.swagger.annotations.ApiModel; | |
19 | +import io.swagger.annotations.ApiModelProperty; | |
18 | 20 | import lombok.Data; |
19 | 21 | import org.thingsboard.server.common.data.alarm.AlarmSeverity; |
20 | 22 | import org.thingsboard.server.common.data.validation.NoXss; |
21 | 23 | |
22 | -import java.io.Serializable; | |
23 | 24 | import javax.validation.Valid; |
25 | +import java.io.Serializable; | |
24 | 26 | import java.util.List; |
25 | 27 | import java.util.TreeMap; |
26 | 28 | |
29 | +@ApiModel | |
27 | 30 | @Data |
28 | 31 | public class DeviceProfileAlarm implements Serializable { |
29 | 32 | |
33 | + @ApiModelProperty(position = 1, value = "String value representing the alarm rule id", example = "highTemperatureAlarmID") | |
30 | 34 | private String id; |
31 | 35 | @NoXss |
36 | + @ApiModelProperty(position = 2, value = "String value representing type of the alarm", example = "High Temperature Alarm") | |
32 | 37 | private String alarmType; |
33 | 38 | |
34 | 39 | @Valid |
40 | + @ApiModelProperty(position = 3, value = "Complex JSON object representing create alarm rules. The unique create alarm rule can be created for each alarm severity type. " + | |
41 | + "There can be 5 create alarm rules configured per a single alarm type. See method implementation notes and AlarmRule model for more details") | |
35 | 42 | private TreeMap<AlarmSeverity, AlarmRule> createRules; |
36 | 43 | @Valid |
44 | + @ApiModelProperty(position = 4, value = "JSON object representing clear alarm rule") | |
37 | 45 | private AlarmRule clearRule; |
38 | 46 | |
39 | 47 | // Hidden in advanced settings |
48 | + @ApiModelProperty(position = 5, value = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") | |
40 | 49 | private boolean propagate; |
50 | + @ApiModelProperty(position = 6, value = "JSON array of relation types that should be used for propagation. " + | |
51 | + "By default, 'propagateRelationTypes' array is empty which means that the alarm will be propagated based on any relation type to parent entities. " + | |
52 | + "This parameter should be used only in case when 'propagate' parameter is set to true, otherwise, 'propagateRelationTypes' array will be ignored.") | |
41 | 53 | private List<String> propagateRelationTypes; |
42 | 54 | } | ... | ... |
... | ... | @@ -29,7 +29,7 @@ import java.io.Serializable; |
29 | 29 | include = JsonTypeInfo.As.PROPERTY, |
30 | 30 | property = "type") |
31 | 31 | @JsonSubTypes({ |
32 | - @JsonSubTypes.Type(value = DefaultDeviceProfileConfiguration.class, name = "DEFAULT")}) | |
32 | + @JsonSubTypes.Type(value = DefaultDeviceProfileConfiguration.class, name = "DEFAULT")}) | |
33 | 33 | public interface DeviceProfileConfiguration extends Serializable { |
34 | 34 | |
35 | 35 | @JsonIgnore | ... | ... |
... | ... | @@ -15,20 +15,27 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.device.profile; |
17 | 17 | |
18 | +import io.swagger.annotations.ApiModel; | |
19 | +import io.swagger.annotations.ApiModelProperty; | |
18 | 20 | import lombok.Data; |
19 | 21 | |
20 | -import java.io.Serializable; | |
21 | 22 | import javax.validation.Valid; |
23 | +import java.io.Serializable; | |
22 | 24 | import java.util.List; |
23 | 25 | |
26 | +@ApiModel | |
24 | 27 | @Data |
25 | 28 | public class DeviceProfileData implements Serializable { |
26 | 29 | |
30 | + @ApiModelProperty(position = 1, value = "JSON object of device profile configuration") | |
27 | 31 | private DeviceProfileConfiguration configuration; |
28 | 32 | @Valid |
33 | + @ApiModelProperty(position = 2, value = "JSON object of device profile transport configuration") | |
29 | 34 | private DeviceProfileTransportConfiguration transportConfiguration; |
35 | + @ApiModelProperty(position = 3, value = "JSON object of provisioning strategy type per device profile") | |
30 | 36 | private DeviceProfileProvisionConfiguration provisionConfiguration; |
31 | 37 | @Valid |
38 | + @ApiModelProperty(position = 4, value = "JSON array of alarm rules configuration per device profile") | |
32 | 39 | private List<DeviceProfileAlarm> alarms; |
33 | 40 | |
34 | 41 | } | ... | ... |