...
|
...
|
@@ -17,6 +17,8 @@ package org.thingsboard.server.transport.http; |
17
|
17
|
|
18
|
18
|
import com.google.gson.JsonObject;
|
19
|
19
|
import com.google.gson.JsonParser;
|
|
20
|
+import io.swagger.annotations.ApiOperation;
|
|
21
|
+import io.swagger.annotations.ApiParam;
|
20
|
22
|
import lombok.RequiredArgsConstructor;
|
21
|
23
|
import lombok.extern.slf4j.Slf4j;
|
22
|
24
|
import org.springframework.beans.factory.annotation.Autowired;
|
...
|
...
|
@@ -68,6 +70,7 @@ import java.util.List; |
68
|
70
|
import java.util.UUID;
|
69
|
71
|
import java.util.function.Consumer;
|
70
|
72
|
|
|
73
|
+
|
71
|
74
|
/**
|
72
|
75
|
* @author Andrew Shvayka
|
73
|
76
|
*/
|
...
|
...
|
@@ -77,14 +80,70 @@ import java.util.function.Consumer; |
77
|
80
|
@Slf4j
|
78
|
81
|
public class DeviceApiController implements TbTransportService {
|
79
|
82
|
|
|
83
|
+ private static final String MARKDOWN_CODE_BLOCK_START = "\n\n```json\n";
|
|
84
|
+ private static final String MARKDOWN_CODE_BLOCK_END = "\n```\n\n";
|
|
85
|
+
|
|
86
|
+ private static final String REQUIRE_ACCESS_TOKEN = "The API call is designed to be used by device firmware and requires device access token ('deviceToken'). " +
|
|
87
|
+ "It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead).\n";
|
|
88
|
+
|
|
89
|
+ private static final String ATTRIBUTE_PAYLOAD_EXAMPLE = "{\n" +
|
|
90
|
+ " \"stringKey\":\"value1\", \n" +
|
|
91
|
+ " \"booleanKey\":true, \n" +
|
|
92
|
+ " \"doubleKey\":42.0, \n" +
|
|
93
|
+ " \"longKey\":73, \n" +
|
|
94
|
+ " \"jsonKey\": {\n" +
|
|
95
|
+ " \"someNumber\": 42,\n" +
|
|
96
|
+ " \"someArray\": [1,2,3],\n" +
|
|
97
|
+ " \"someNestedObject\": {\"key\": \"value\"}\n" +
|
|
98
|
+ " }\n" +
|
|
99
|
+ "}";
|
|
100
|
+
|
|
101
|
+ protected static final String TS_PAYLOAD = "The request payload is a JSON document with three possible formats:\n\n" +
|
|
102
|
+ "Simple format without timestamp. In such a case, current server time will be used: \n\n" +
|
|
103
|
+ MARKDOWN_CODE_BLOCK_START +
|
|
104
|
+ "{\n" +
|
|
105
|
+ " \"stringKey\":\"value1\", \n" +
|
|
106
|
+ " \"booleanKey\":true, \n" +
|
|
107
|
+ " \"doubleKey\":42.0, \n" +
|
|
108
|
+ " \"longKey\":73, \n" +
|
|
109
|
+ " \"jsonKey\": {\n" +
|
|
110
|
+ " \"someNumber\": 42,\n" +
|
|
111
|
+ " \"someArray\": [1,2,3],\n" +
|
|
112
|
+ " \"someNestedObject\": {\"key\": \"value\"}\n" +
|
|
113
|
+ " }\n" +
|
|
114
|
+ "}" +
|
|
115
|
+ MARKDOWN_CODE_BLOCK_END +
|
|
116
|
+ "\n\n Single JSON object with timestamp: \n\n" +
|
|
117
|
+ MARKDOWN_CODE_BLOCK_START +
|
|
118
|
+ "{\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}}" +
|
|
119
|
+ MARKDOWN_CODE_BLOCK_END +
|
|
120
|
+ "\n\n JSON array with timestamps: \n\n" +
|
|
121
|
+ MARKDOWN_CODE_BLOCK_START +
|
|
122
|
+ "[\n{\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}}, \n{\"ts\":1634712588000,\"values\":{\"temperature\":25, \"humidity\":88}}\n]" +
|
|
123
|
+ MARKDOWN_CODE_BLOCK_END;
|
|
124
|
+
|
|
125
|
+ private static final String ACCESS_TOKEN_PARAM_DESCRIPTION = "Your device access token.";
|
|
126
|
+
|
80
|
127
|
@Autowired
|
81
|
128
|
private HttpTransportContext transportContext;
|
82
|
129
|
|
|
130
|
+ @ApiOperation(value = "Get attributes (getDeviceAttributes)",
|
|
131
|
+ notes = "Returns all attributes that belong to device. "
|
|
132
|
+ + "Use optional 'clientKeys' and/or 'sharedKeys' parameter to return specific attributes. "
|
|
133
|
+ + "\n Example of the result: "
|
|
134
|
+ + MARKDOWN_CODE_BLOCK_START
|
|
135
|
+ + ATTRIBUTE_PAYLOAD_EXAMPLE
|
|
136
|
+ + MARKDOWN_CODE_BLOCK_END
|
|
137
|
+ + REQUIRE_ACCESS_TOKEN,
|
|
138
|
+ produces = MediaType.APPLICATION_JSON_VALUE)
|
83
|
139
|
@RequestMapping(value = "/{deviceToken}/attributes", method = RequestMethod.GET, produces = "application/json")
|
84
|
|
- public DeferredResult<ResponseEntity> getDeviceAttributes(@PathVariable("deviceToken") String deviceToken,
|
85
|
|
- @RequestParam(value = "clientKeys", required = false, defaultValue = "") String clientKeys,
|
86
|
|
- @RequestParam(value = "sharedKeys", required = false, defaultValue = "") String sharedKeys,
|
87
|
|
- HttpServletRequest httpRequest) {
|
|
140
|
+ public DeferredResult<ResponseEntity> getDeviceAttributes(
|
|
141
|
+ @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
|
|
142
|
+ @PathVariable("deviceToken") String deviceToken,
|
|
143
|
+ @ApiParam(value = "Comma separated key names for attribute with client scope", required = true, defaultValue = "state")
|
|
144
|
+ @RequestParam(value = "clientKeys", required = false, defaultValue = "") String clientKeys,
|
|
145
|
+ @ApiParam(value = "Comma separated key names for attribute with shared scope", required = true, defaultValue = "configuration")
|
|
146
|
+ @RequestParam(value = "sharedKeys", required = false, defaultValue = "") String sharedKeys) {
|
88
|
147
|
DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>();
|
89
|
148
|
transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
|
90
|
149
|
new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
|
...
|
...
|
@@ -106,9 +165,20 @@ public class DeviceApiController implements TbTransportService { |
106
|
165
|
return responseWriter;
|
107
|
166
|
}
|
108
|
167
|
|
|
168
|
+ @ApiOperation(value = "Post attributes (postDeviceAttributes)",
|
|
169
|
+ notes = "Post client attribute updates on behalf of device. "
|
|
170
|
+ + "\n Example of the request: "
|
|
171
|
+ + MARKDOWN_CODE_BLOCK_START
|
|
172
|
+ + ATTRIBUTE_PAYLOAD_EXAMPLE
|
|
173
|
+ + MARKDOWN_CODE_BLOCK_END
|
|
174
|
+ + REQUIRE_ACCESS_TOKEN,
|
|
175
|
+ produces = MediaType.APPLICATION_JSON_VALUE)
|
109
|
176
|
@RequestMapping(value = "/{deviceToken}/attributes", method = RequestMethod.POST)
|
110
|
|
- public DeferredResult<ResponseEntity> postDeviceAttributes(@PathVariable("deviceToken") String deviceToken,
|
111
|
|
- @RequestBody String json, HttpServletRequest request) {
|
|
177
|
+ public DeferredResult<ResponseEntity> postDeviceAttributes(
|
|
178
|
+ @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
|
|
179
|
+ @PathVariable("deviceToken") String deviceToken,
|
|
180
|
+ @ApiParam(value = "JSON with attribute key-value pairs. See API call description for example.")
|
|
181
|
+ @RequestBody String json) {
|
112
|
182
|
DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>();
|
113
|
183
|
transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
|
114
|
184
|
new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
|
...
|
...
|
@@ -119,9 +189,17 @@ public class DeviceApiController implements TbTransportService { |
119
|
189
|
return responseWriter;
|
120
|
190
|
}
|
121
|
191
|
|
|
192
|
+ @ApiOperation(value = "Post time-series data (postTelemetry)",
|
|
193
|
+ notes = "Post time-series data on behalf of device. "
|
|
194
|
+ + "\n Example of the request: "
|
|
195
|
+ + TS_PAYLOAD
|
|
196
|
+ + REQUIRE_ACCESS_TOKEN,
|
|
197
|
+ produces = MediaType.APPLICATION_JSON_VALUE)
|
122
|
198
|
@RequestMapping(value = "/{deviceToken}/telemetry", method = RequestMethod.POST)
|
123
|
|
- public DeferredResult<ResponseEntity> postTelemetry(@PathVariable("deviceToken") String deviceToken,
|
124
|
|
- @RequestBody String json, HttpServletRequest request) {
|
|
199
|
+ public DeferredResult<ResponseEntity> postTelemetry(
|
|
200
|
+ @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
|
|
201
|
+ @PathVariable("deviceToken") String deviceToken,
|
|
202
|
+ @RequestBody String json, HttpServletRequest request) {
|
125
|
203
|
DeferredResult<ResponseEntity> responseWriter = new DeferredResult<ResponseEntity>();
|
126
|
204
|
transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
|
127
|
205
|
new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
|
...
|
...
|
@@ -132,9 +210,22 @@ public class DeviceApiController implements TbTransportService { |
132
|
210
|
return responseWriter;
|
133
|
211
|
}
|
134
|
212
|
|
|
213
|
+ @ApiOperation(value = "Save claiming information (claimDevice)",
|
|
214
|
+ notes = "Saves the information required for user to claim the device. " +
|
|
215
|
+ "See more info about claiming in the corresponding 'Claiming devices' platform documentation."
|
|
216
|
+ + "\n Example of the request payload: "
|
|
217
|
+ + MARKDOWN_CODE_BLOCK_START
|
|
218
|
+ + "{\"secretKey\":\"value\", \"durationMs\":60000}"
|
|
219
|
+ + MARKDOWN_CODE_BLOCK_END
|
|
220
|
+ + "Note: both 'secretKey' and 'durationMs' is optional parameters. " +
|
|
221
|
+ "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\n"
|
|
222
|
+ + REQUIRE_ACCESS_TOKEN,
|
|
223
|
+ produces = MediaType.APPLICATION_JSON_VALUE)
|
135
|
224
|
@RequestMapping(value = "/{deviceToken}/claim", method = RequestMethod.POST)
|
136
|
|
- public DeferredResult<ResponseEntity> claimDevice(@PathVariable("deviceToken") String deviceToken,
|
137
|
|
- @RequestBody(required = false) String json, HttpServletRequest request) {
|
|
225
|
+ public DeferredResult<ResponseEntity> claimDevice(
|
|
226
|
+ @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
|
|
227
|
+ @PathVariable("deviceToken") String deviceToken,
|
|
228
|
+ @RequestBody(required = false) String json) {
|
138
|
229
|
DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>();
|
139
|
230
|
transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
|
140
|
231
|
new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
|
...
|
...
|
@@ -146,10 +237,18 @@ public class DeviceApiController implements TbTransportService { |
146
|
237
|
return responseWriter;
|
147
|
238
|
}
|
148
|
239
|
|
|
240
|
+ @ApiOperation(value = "Subscribe to RPC commands (subscribeToCommands) (Deprecated)",
|
|
241
|
+ notes = "Subscribes to RPC commands using http long polling. " +
|
|
242
|
+ "Deprecated, since long polling is resource and network consuming. " +
|
|
243
|
+ "Consider using MQTT or CoAP protocol for light-weight real-time updates. \n\n" +
|
|
244
|
+ REQUIRE_ACCESS_TOKEN,
|
|
245
|
+ produces = MediaType.APPLICATION_JSON_VALUE)
|
149
|
246
|
@RequestMapping(value = "/{deviceToken}/rpc", method = RequestMethod.GET, produces = "application/json")
|
150
|
|
- public DeferredResult<ResponseEntity> subscribeToCommands(@PathVariable("deviceToken") String deviceToken,
|
151
|
|
- @RequestParam(value = "timeout", required = false, defaultValue = "0") long timeout,
|
152
|
|
- HttpServletRequest httpRequest) {
|
|
247
|
+ public DeferredResult<ResponseEntity> subscribeToCommands(
|
|
248
|
+ @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
|
|
249
|
+ @PathVariable("deviceToken") String deviceToken,
|
|
250
|
+ @ApiParam(value = "Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side.")
|
|
251
|
+ @RequestParam(value = "timeout", required = false, defaultValue = "0") long timeout) {
|
153
|
252
|
DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>();
|
154
|
253
|
transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
|
155
|
254
|
new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
|
...
|
...
|
@@ -164,10 +263,18 @@ public class DeviceApiController implements TbTransportService { |
164
|
263
|
return responseWriter;
|
165
|
264
|
}
|
166
|
265
|
|
|
266
|
+ @ApiOperation(value = "Reply to RPC commands (replyToCommand)",
|
|
267
|
+ notes = "Replies to server originated RPC command identified by 'requestId' parameter. The response is arbitrary JSON.\n\n" +
|
|
268
|
+ REQUIRE_ACCESS_TOKEN,
|
|
269
|
+ produces = MediaType.APPLICATION_JSON_VALUE)
|
167
|
270
|
@RequestMapping(value = "/{deviceToken}/rpc/{requestId}", method = RequestMethod.POST)
|
168
|
|
- public DeferredResult<ResponseEntity> replyToCommand(@PathVariable("deviceToken") String deviceToken,
|
169
|
|
- @PathVariable("requestId") Integer requestId,
|
170
|
|
- @RequestBody String json, HttpServletRequest request) {
|
|
271
|
+ public DeferredResult<ResponseEntity> replyToCommand(
|
|
272
|
+ @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
|
|
273
|
+ @PathVariable("deviceToken") String deviceToken,
|
|
274
|
+ @ApiParam(value = "RPC request id from the incoming RPC request", required = true, defaultValue = "123")
|
|
275
|
+ @PathVariable("requestId") Integer requestId,
|
|
276
|
+ @ApiParam(value = "Reply to the RPC request, JSON. For example: {\"status\":\"success\"}", required = true)
|
|
277
|
+ @RequestBody String json) {
|
171
|
278
|
DeferredResult<ResponseEntity> responseWriter = new DeferredResult<ResponseEntity>();
|
172
|
279
|
transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
|
173
|
280
|
new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
|
...
|
...
|
@@ -177,9 +284,23 @@ public class DeviceApiController implements TbTransportService { |
177
|
284
|
return responseWriter;
|
178
|
285
|
}
|
179
|
286
|
|
|
287
|
+ @ApiOperation(value = "Send the RPC command (postRpcRequest)",
|
|
288
|
+ notes = "Send the RPC request to server. The request payload is a JSON document that contains 'method' and 'params'. For example:" +
|
|
289
|
+ MARKDOWN_CODE_BLOCK_START +
|
|
290
|
+ "{\"method\": \"sumOnServer\", \"params\":{\"a\":2, \"b\":2}}" +
|
|
291
|
+ MARKDOWN_CODE_BLOCK_END +
|
|
292
|
+ "The response contains arbitrary JSON with the RPC reply. For example: " +
|
|
293
|
+ MARKDOWN_CODE_BLOCK_START +
|
|
294
|
+ "{\"result\": 4}" +
|
|
295
|
+ MARKDOWN_CODE_BLOCK_END +
|
|
296
|
+ REQUIRE_ACCESS_TOKEN,
|
|
297
|
+ produces = MediaType.APPLICATION_JSON_VALUE)
|
180
|
298
|
@RequestMapping(value = "/{deviceToken}/rpc", method = RequestMethod.POST)
|
181
|
|
- public DeferredResult<ResponseEntity> postRpcRequest(@PathVariable("deviceToken") String deviceToken,
|
182
|
|
- @RequestBody String json, HttpServletRequest httpRequest) {
|
|
299
|
+ public DeferredResult<ResponseEntity> postRpcRequest(
|
|
300
|
+ @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
|
|
301
|
+ @PathVariable("deviceToken") String deviceToken,
|
|
302
|
+ @ApiParam(value = "The RPC request JSON", required = true)
|
|
303
|
+ @RequestBody String json) {
|
183
|
304
|
DeferredResult<ResponseEntity> responseWriter = new DeferredResult<ResponseEntity>();
|
184
|
305
|
transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
|
185
|
306
|
new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
|
...
|
...
|
@@ -196,10 +317,18 @@ public class DeviceApiController implements TbTransportService { |
196
|
317
|
return responseWriter;
|
197
|
318
|
}
|
198
|
319
|
|
|
320
|
+ @ApiOperation(value = "Subscribe to attribute updates (subscribeToAttributes) (Deprecated)",
|
|
321
|
+ notes = "Subscribes to client and shared scope attribute updates using http long polling. " +
|
|
322
|
+ "Deprecated, since long polling is resource and network consuming. " +
|
|
323
|
+ "Consider using MQTT or CoAP protocol for light-weight real-time updates. \n\n" +
|
|
324
|
+ REQUIRE_ACCESS_TOKEN,
|
|
325
|
+ produces = MediaType.APPLICATION_JSON_VALUE)
|
199
|
326
|
@RequestMapping(value = "/{deviceToken}/attributes/updates", method = RequestMethod.GET, produces = "application/json")
|
200
|
|
- public DeferredResult<ResponseEntity> subscribeToAttributes(@PathVariable("deviceToken") String deviceToken,
|
201
|
|
- @RequestParam(value = "timeout", required = false, defaultValue = "0") long timeout,
|
202
|
|
- HttpServletRequest httpRequest) {
|
|
327
|
+ public DeferredResult<ResponseEntity> subscribeToAttributes(
|
|
328
|
+ @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
|
|
329
|
+ @PathVariable("deviceToken") String deviceToken,
|
|
330
|
+ @ApiParam(value = "Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side.")
|
|
331
|
+ @RequestParam(value = "timeout", required = false, defaultValue = "0") long timeout) {
|
203
|
332
|
DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>();
|
204
|
333
|
transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
|
205
|
334
|
new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
|
...
|
...
|
@@ -214,26 +343,85 @@ public class DeviceApiController implements TbTransportService { |
214
|
343
|
return responseWriter;
|
215
|
344
|
}
|
216
|
345
|
|
|
346
|
+ @ApiOperation(value = "Get Device Firmware (getFirmware)",
|
|
347
|
+ notes = "Downloads the current firmware package." +
|
|
348
|
+ "When the platform initiates firmware update, " +
|
|
349
|
+ "it informs the device by updating the 'fw_title', 'fw_version', 'fw_checksum' and 'fw_checksum_algorithm' shared attributes." +
|
|
350
|
+ "The 'fw_title' and 'fw_version' parameters must be supplied in this request to double-check " +
|
|
351
|
+ "that the firmware that device is downloading matches the firmware it expects to download. " +
|
|
352
|
+ "This is important, since the administrator may change the firmware assignment while device is downloading the firmware. \n\n" +
|
|
353
|
+ "Optional 'chunk' and 'size' parameters may be used to download the firmware in chunks. " +
|
|
354
|
+ "For example, device may request first 16 KB of firmware using 'chunk'=0 and 'size'=16384. " +
|
|
355
|
+ "Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. \n\n" +
|
|
356
|
+ REQUIRE_ACCESS_TOKEN,
|
|
357
|
+ produces = MediaType.APPLICATION_JSON_VALUE)
|
217
|
358
|
@RequestMapping(value = "/{deviceToken}/firmware", method = RequestMethod.GET)
|
218
|
|
- public DeferredResult<ResponseEntity> getFirmware(@PathVariable("deviceToken") String deviceToken,
|
219
|
|
- @RequestParam(value = "title") String title,
|
220
|
|
- @RequestParam(value = "version") String version,
|
221
|
|
- @RequestParam(value = "size", required = false, defaultValue = "0") int size,
|
222
|
|
- @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) {
|
|
359
|
+ public DeferredResult<ResponseEntity> getFirmware(
|
|
360
|
+ @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
|
|
361
|
+ @PathVariable("deviceToken") String deviceToken,
|
|
362
|
+ @ApiParam(value = "Title of the firmware, corresponds to the value of 'fw_title' attribute.", required = true)
|
|
363
|
+ @RequestParam(value = "title") String title,
|
|
364
|
+ @ApiParam(value = "Version of the firmware, corresponds to the value of 'fw_version' attribute.", required = true)
|
|
365
|
+ @RequestParam(value = "version") String version,
|
|
366
|
+ @ApiParam(value = "Size of the chunk. Optional. Omit to download the entire file without chunks.")
|
|
367
|
+ @RequestParam(value = "size", required = false, defaultValue = "0") int size,
|
|
368
|
+ @ApiParam(value = "Index of the chunk. Optional. Omit to download the entire file without chunks.")
|
|
369
|
+ @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) {
|
223
|
370
|
return getOtaPackageCallback(deviceToken, title, version, size, chunk, OtaPackageType.FIRMWARE);
|
224
|
371
|
}
|
225
|
372
|
|
|
373
|
+ @ApiOperation(value = "Get Device Software (getSoftware)",
|
|
374
|
+ notes = "Downloads the current software package." +
|
|
375
|
+ "When the platform initiates software update, " +
|
|
376
|
+ "it informs the device by updating the 'sw_title', 'sw_version', 'sw_checksum' and 'sw_checksum_algorithm' shared attributes." +
|
|
377
|
+ "The 'sw_title' and 'sw_version' parameters must be supplied in this request to double-check " +
|
|
378
|
+ "that the software that device is downloading matches the software it expects to download. " +
|
|
379
|
+ "This is important, since the administrator may change the software assignment while device is downloading the software. \n\n" +
|
|
380
|
+ "Optional 'chunk' and 'size' parameters may be used to download the software in chunks. " +
|
|
381
|
+ "For example, device may request first 16 KB of software using 'chunk'=0 and 'size'=16384. " +
|
|
382
|
+ "Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. \n\n" +
|
|
383
|
+ REQUIRE_ACCESS_TOKEN,
|
|
384
|
+ produces = MediaType.APPLICATION_JSON_VALUE)
|
226
|
385
|
@RequestMapping(value = "/{deviceToken}/software", method = RequestMethod.GET)
|
227
|
|
- public DeferredResult<ResponseEntity> getSoftware(@PathVariable("deviceToken") String deviceToken,
|
228
|
|
- @RequestParam(value = "title") String title,
|
229
|
|
- @RequestParam(value = "version") String version,
|
230
|
|
- @RequestParam(value = "size", required = false, defaultValue = "0") int size,
|
231
|
|
- @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) {
|
|
386
|
+ public DeferredResult<ResponseEntity> getSoftware(
|
|
387
|
+ @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
|
|
388
|
+ @PathVariable("deviceToken") String deviceToken,
|
|
389
|
+ @ApiParam(value = "Title of the software, corresponds to the value of 'sw_title' attribute.", required = true)
|
|
390
|
+ @RequestParam(value = "title") String title,
|
|
391
|
+ @ApiParam(value = "Version of the software, corresponds to the value of 'sw_version' attribute.", required = true)
|
|
392
|
+ @RequestParam(value = "version") String version,
|
|
393
|
+ @ApiParam(value = "Size of the chunk. Optional. Omit to download the entire file without using chunks.")
|
|
394
|
+ @RequestParam(value = "size", required = false, defaultValue = "0") int size,
|
|
395
|
+ @ApiParam(value = "Index of the chunk. Optional. Omit to download the entire file without using chunks.")
|
|
396
|
+ @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) {
|
232
|
397
|
return getOtaPackageCallback(deviceToken, title, version, size, chunk, OtaPackageType.SOFTWARE);
|
233
|
398
|
}
|
234
|
399
|
|
|
400
|
+ @ApiOperation(value = "Provision new device (provisionDevice)",
|
|
401
|
+ notes = "Exchange the provision request to the device credentials. " +
|
|
402
|
+ "See more info about provisioning in the corresponding 'Device provisioning' platform documentation." +
|
|
403
|
+ "Requires valid JSON request with the following format: " +
|
|
404
|
+ MARKDOWN_CODE_BLOCK_START +
|
|
405
|
+ "{\n" +
|
|
406
|
+ " \"deviceName\": \"NEW_DEVICE_NAME\",\n" +
|
|
407
|
+ " \"provisionDeviceKey\": \"u7piawkboq8v32dmcmpp\",\n" +
|
|
408
|
+ " \"provisionDeviceSecret\": \"jpmwdn8ptlswmf4m29bw\"\n" +
|
|
409
|
+ "}" +
|
|
410
|
+ MARKDOWN_CODE_BLOCK_END +
|
|
411
|
+ "Where 'deviceName' is the name of enw or existing device which depends on the provisioning strategy. " +
|
|
412
|
+ "The 'provisionDeviceKey' and 'provisionDeviceSecret' matches info configured in one of the existing device profiles. " +
|
|
413
|
+ "The result of the successful call is the JSON object that contains new credentials:" +
|
|
414
|
+ MARKDOWN_CODE_BLOCK_START + "{\n" +
|
|
415
|
+ " \"credentialsType\":\"ACCESS_TOKEN\",\n" +
|
|
416
|
+ " \"credentialsValue\":\"DEVICE_ACCESS_TOKEN\",\n" +
|
|
417
|
+ " \"status\":\"SUCCESS\"\n" +
|
|
418
|
+ "}" + MARKDOWN_CODE_BLOCK_END
|
|
419
|
+ ,
|
|
420
|
+ produces = MediaType.APPLICATION_JSON_VALUE)
|
235
|
421
|
@RequestMapping(value = "/provision", method = RequestMethod.POST)
|
236
|
|
- public DeferredResult<ResponseEntity> provisionDevice(@RequestBody String json, HttpServletRequest httpRequest) {
|
|
422
|
+ public DeferredResult<ResponseEntity> provisionDevice(
|
|
423
|
+ @ApiParam(value = "JSON with provision request. See API call description for example.")
|
|
424
|
+ @RequestBody String json) {
|
237
|
425
|
DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>();
|
238
|
426
|
transportContext.getTransportService().process(JsonConverter.convertToProvisionRequestMsg(json),
|
239
|
427
|
new DeviceProvisionCallback(responseWriter));
|
...
|
...
|
|