一、参考地址
Rest-api参考:
http://www.ithingsboard.com/docs/reference/rest-api/
所有API参考:
http://www.ithingsboard.com/docs/api/
二、关于三种属性
- 设备属性:只能是设备上报或者获取,平台无法修改,外部调用可以通过令牌来修改
- 共享属性:设备只能获取,平台可修改,外部调用可修改
- 平台属性:设备只能获取,平台可修改,外部调用可修改
三、相互通信方式
目前想到的,想要完成外部和设备互相通信,共有2种方式
- 通过设备属性方式,缺点是没法订阅属性更新(共享数据可以,设备属性不行),只能自己定期去查询
- 通过rpc方式,可以订阅属性更新,直接订阅 request/+ ,在命令触发时,就可以收到对应命令了
四、流程
1、MQTT设置和读取设备属性
参考链接:http://www.ithingsboard.com/docs/reference/mqtt-api/#rpc-api
-
设备通过MQTT登录,client_id是设备ID,username是访问令牌
esp_mqtt_client_config_t mqtt_cfg = { .uri = "mqtt://***.***.***.***:1883", .event_handle = mqtt_event_handler, // .cert_pem = (const char *)ca_cert, // .client_cert_pem = (const char *)cl_cert,//client_cert_pem_start, // .client_key_pem = (const char *)cl_key,//client_key_pem_start, //.port= 8884, .client_id = "312cd6d0-c99e-11eb-aaa5-2faca3423440", .username = "6U9OgdbWBNt5QCF7LJ8O", //用户名 // .password = "OdYdzRrTNeUKXJvIjAUbdA02I3h2P9df", //密码 //.task_stack = 10240, .keepalive = 60, };
-
发布属性
msg_id = esp_mqtt_client_publish(client, "v1/devices/me/attributes", "{\"key1\":\"value1\"}", 0, 1, 0); ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
- topic:v1/devices/me/attributes - pyload:{\"key1\":\"value1\"} ,json格式数据 注意一下这里程序上有转义
- 获取属性
- 发布 主题 为 v1/devices/me/attributes/request/序号
- 发布的pyload为 “{“clientKeys”:“dnakey,rootkey0,ble_mac”, “sharedKeys”:“t1”}”,可以拿到设备属性,和共享属性
int msg_id;
static uint8_t request_id = 0;
char request_topic[50];
char publish_data[100]="{“clientKeys”:“dnakey,rootkey0,ble_mac”, “sharedKeys”:“t1”}";
sprintf(request_topic,“v1/devices/me/attributes/request/%d”,request_id++);
msg_id = esp_mqtt_client_publish(client, request_topic, publish_data, 0, 1, 0);
ESP_LOGI(TAG, “sent publish successful, msg_id=%d”, msg_id);LOG: ```c [0;32mI (169389) RX_TASK: Read 7 bytes: 'request'[0m [0;32mI (169389) RX_TASK: 0x3fcb0200 72 65 71 75 65 73 74 |request|[0m [0;32mI (169389) MQTT_EXAMPLE: sent publish successful, msg_id=22462[0m [0;32mI (169439) MQTT_EXAMPLE: MQTT_EVENT_PUBLISHED, msg_id=22462[0m [0;32mI (169529) MQTT_EXAMPLE: MQTT_EVENT_DATA[0m TOPIC=v1/devices/me/attributes/response/0 DATA={"client":{"dnakey":"3951536c30537a59554a35426e496374","rootkey0":"03c53f32","ble_mac":"84c2e43f"},"shared":{"t1":"121212"}}
- 获取属性
2、RPC控制设备
参考链接:
http://www.ithingsboard.com/docs/user-guide/rpc/
-
.需要订阅的topic
- v1/devices/me/rpc/request/+ 用于 收取rpc命令
msg_id = esp_mqtt_client_subscribe(client, "v1/devices/me/rpc/request/+", 0); ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
-
通过 swagger-ui.html#/rpc-controller 下发 rpc命令=oneway模式,不需要回复
需要填入2个信息- device id
- request body,注意一下是json格式 必须有method 和 params 字段
{ "method": "setGpio", "params": { "pin": "23", "value": 1 } }
-
点击 try it out ,设备收到数据
Log:
[0;32mI (1196589) MQTT_EXAMPLE: MQTT_EVENT_DATA[0m TOPIC=v1/devices/me/rpc/request/112 DATA={"method":"setGpio","params":{"pin":"23","value":1}} request_id = 112 topic = v1/devices/me/rpc/response/112 [0;32mI (1196609) MQTT_EXAMPLE: MQTT_EVENT_PUBLISHED, msg_id=23360[0m
-
TwoWay模式,需要回复
其实我们可以看到对应的curl命令
这里收到了数据后,发布了回复,回复数据如下:
{ "button1": 0 }
注意这里的回复并不是设置设备属性。。。。我这里只是随便写一个
if(strstr((const char *)event->topic,"request")) { //v1/devices/me/rpc/response/$request_id char *ptr = strstr((const char *)event->topic,"request"); uint16_t request_id = atoi(ptr+8); printf("request_id = %d \r\n",request_id); char topic[50]; sprintf(topic,"v1/devices/me/rpc/response/%d",request_id); printf("topic = %s\r\n",topic); esp_mqtt_client_publish(client, topic,"{\"button1\":0}", 0, 1, 0); }
五、关于REST API 认证
参考链接:
http://www.ithingsboard.com/docs/reference/rest-api/
- 使用POSTMAN
- POST方式 ,地址为 :http://localhost:8080/api/auth/login
- headers 增加 content-type 为 application /json
- Body 写raw 数据
{"username":"tenant@thingsboard.org", "password":"tenant"}
- 发送后,或者Token
- 打开 http://localhost:8080/swagger-ui.html,点击Authorize
输入 Bearer+空格+Token
验证成功后:
六、相关API操作
-
获取设备所有属性,包括服务器属性,设备属性,共享属性
这里可以看到设备的状态(是否在线)
telemetry-controller : Telemetry Controller
GET /api/plugins/telemetry/{entityType}/{entityId}/values/attributes{?keys}
entityType 为 DEVICE
entityID为设备ID
Keys 如果 不填,则全部获取,可以填入Key,拿自己需要的
对应的curl命令为curl -X GET --header 'Accept: application/json' --header 'X-Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZW5hbnRAdGhpbmdzYm9hcmQub3JnIiwic2NvcGVzIjpbIlRFTkFOVF9BRE1JTiJdLCJ1c2VySWQiOiI0NjM3MGZiMC1iZThhLTExZWItODQxOS1iZjYxZDMwOTA0ZmMiLCJlbmFibGVkIjp0cnVlLCJpc1B1YmxpYyI6ZmFsc2UsInRlbmFudElkIjoiNDViZWFiNjAtYmU4YS0xMWViLTg0MTktYmY2MWQzMDkwNGZjIiwiY3VzdG9tZXJJZCI6IjEzODE0MDAwLTFkZDItMTFiMi04MDgwLTgwODA4MDgwODA4MCIsImlzcyI6InRoaW5nc2JvYXJkLmlvIiwiaWF0IjoxNjIzNzI0NTE3LCJleHAiOjE2MjM3MzM1MTd9.q8hSOO09J7u3wlndnrSaLTZfBJDOY0swtnzlBd7PDNDOF7QSBMk7nYFIcUtUhKXNy8eB4oszTtREs8gr45muQQ' 'http://localhost:8080/api/plugins/telemetry/DEVICE/312cd6d0-c99e-11eb-aaa5-2faca3423440/values/attributes'
获取到的数据 ,这里可以看到 active 为 true 意思就是在线了
Response Body [ { "lastUpdateTs": 1623606896305, "key": "t1", "value": "tt1" }, { "lastUpdateTs": 1623317129221, "key": "button1", "value": 0 }, { "lastUpdateTs": 1623723459779, "key": "key1", "value": "value1" }, { "lastUpdateTs": 1623723459870, "key": "dnakey", "value": "3951536c30537a59554a35426e496374" }, { "lastUpdateTs": 1623392208381, "key": "t2", "value": 5 }, { "lastUpdateTs": 1623723459870, "key": "rootkey0", "value": "03c53f32" }, { "lastUpdateTs": 1623723459870, "key": "ble_mac", "value": "84c2e43f" }, { "lastUpdateTs": 1623377404660, "key": "t1", "value": "121212" }, { "lastUpdateTs": 1623724863931, "key": "lastActivityTime", "value": 1623724846444 }, { "lastUpdateTs": 1623609453940, "key": "lastDisconnectTime", "value": 1623609453940 }, { "lastUpdateTs": 1623609741443, "key": "inactivityAlarmTime", "value": 1623609741442 }, { "lastUpdateTs": 1623723454932, "key": "active", "value": true }, { "lastUpdateTs": 1623723459722, "key": "lastConnectTime", "value": 1623723459722 } ] Response Code 200 Response Headers { "cache-control": "no-cache, no-store, max-age=0, must-revalidate", "connection": "keep-alive", "content-type": "application/json", "date": "Tue, 15 Jun 2021 02:41:31 GMT", "expires": "0", "keep-alive": "timeout=4", "pragma": "no-cache", "proxy-connection": "keep-alive", "transfer-encoding": "chunked", "vary": "Origin, Access-Control-Request-Method, Access-Control-Request-Headers", "x-content-type-options": "nosniff", "x-xss-protection": "1; mode=block" }
-
下发RPC数据
rpc-controller : Rpc Controller
2种定义具体参考上面 RPC控制设备