一. 體驗新版更新內容
onenet5.0是一個大改版, 連用了多年的LOGO都換掉了, 現(xiàn)在的logo更簡約美觀了
1. OneNET Studio
更新后推出了一個OneNET Studio 的概念, 所有接入服務放在了這里面
進入 OneNET Studio 發(fā)現(xiàn)其整合相當一部分的業(yè)務, 而且分的非常明晰
2. 設備接入
現(xiàn)在, 我們關心的主要內容是設備接入
3. 產品管理和創(chuàng)建產品
產品管理界面簡介美觀
添加產品很容易
這里有了第一個概念 OneJson
4. OneJson概念
OneJson 就是OneNet能自動解析的JSON, 如果你按照這個格式上傳json數(shù)據(jù), 會省略上傳數(shù)據(jù)解析過程.
5. 創(chuàng)建物模型
創(chuàng)建完產品后, 要開始創(chuàng)建物模型
- 更新后的onenet MQTT和阿里云IOT一樣擁有了物模型的概念
關于物模型, 請參考以下文檔:
https://open.iot.10086.cn/doc/iot_platform/book/device-connect&manager/thing-model/introduce.html
創(chuàng)建物模型分為 系統(tǒng)功能點 和 自定義功能點組
5.1 系統(tǒng)功能點(如果不需要定位服務,可以忽略此節(jié))
目前只有兩個
這個功能點已經完全定死, 我們只能提交符合它的格式的數(shù)據(jù),
根據(jù)官方的SDK, 其結構如下:
5.2 自定義功能點組
自定義功能點分為3類
很容易明白這三類的意思, 本次試驗我們只用屬性類
創(chuàng)建功能點很簡單:
和阿里云IOT一樣, 創(chuàng)建完保存才能更新
6. 添加設備
添加設備還是那么的無腦 ??我喜歡
添加完設備后, 我們就得到了設備的關鍵信息了!!!
7. 計算token
和之前一樣, 參考文章: http://www.reibang.com/p/1c8dccc35b61
或者看文檔: https://open.iot.10086.cn/doc/iot_platform/book/device-connect&manager/device-auth.html
通過 產品ID 設備名 和token 我們就可以接入新版OneNet了
8. 接入地址
和之前不一樣了
參考文檔: https://open.iot.10086.cn/doc/iot_platform/book/device-connect&manager/MQTT/mqtt-device-development.html
現(xiàn)在我們要接入的是: 218.201.45.7 : 1883 了!!
9. 通訊主題
原先OneNet可以說只有兩個主題 , 現(xiàn)在終于把主題的概念發(fā)展開了, 越看越像阿里IOT了
參考文檔 : https://open.iot.10086.cn/doc/iot_platform/book/device-connect&manager/MQTT/topic.html
10. 新版MQTT通訊限制
文檔把通訊限制寫的非常明確, 這很好!
https://open.iot.10086.cn/doc/iot_platform/book/device-connect&manager/MQTT/mqtt-limit.html
二. 上傳溫濕度至新版ONENET示例
#include <Arduino.h>
#include "WiFi.h"
#include "PubSubClient.h"
#include "Ticker.h"
#include "uFire_SHT20.h"
uFire_SHT20 sht20;
const char *ssid = "anleng"; //wifi名
const char *password = "al77776666"; //wifi密碼
const char *mqtt_server = "218.201.45.7"; //onenet 的 IP地址
const int port = 1883; //端口號
#define mqtt_pubid "IaiJ9078ZN" //產品ID
#define mqtt_devid "esp_mqtts_001" //設備名稱
//鑒權信息
#define mqtt_password "version=2018-10-31&res=products%2FIaiJ9078ZN%2Fdevices%2Fesp_mqtts_001&et=4092599349&method=md5&sign=nvhmyIawpRbUyAojvL8CRA%3D%3D" //鑒權信息
WiFiClient espClient; //創(chuàng)建一個WIFI連接客戶端
PubSubClient client(espClient); // 創(chuàng)建一個PubSub客戶端, 傳入創(chuàng)建的WIFI客戶端
Ticker tim1; //定時器,用來循環(huán)上傳數(shù)據(jù)
//設備下發(fā)命令的set主題
#define ONENET_TOPIC_PROP_SET "$sys/" mqtt_pubid "/" mqtt_devid "/thing/property/set"
//設備上傳數(shù)據(jù)的post主題
#define ONENET_TOPIC_PROP_POST "$sys/" mqtt_pubid "/" mqtt_devid "/thing/property/post"
//這是post上傳數(shù)據(jù)使用的模板
#define ONENET_POST_BODY_FORMAT "{\"id\":\"%u\",\"params\":%s}"
int postMsgId = 0; //記錄已經post了多少條
//連接WIFI相關函數(shù)
void setupWifi()
{
delay(10);
Serial.println("connect WIFI");
WiFi.begin(ssid, password);
while (!WiFi.isConnected())
{
Serial.print(".");
delay(500);
}
Serial.println("OK");
Serial.println("Wifi connected!");
}
//向主題發(fā)送模擬的溫濕度數(shù)據(jù)
void sendTempAndHumi()
{
if (client.connected())
{
//先拼接出json字符串
char param[82];
char jsonBuf[178];
sprintf(param, "{\"temp\":{\"value\":%.2f},\"humi\":{\"value\":%.2f}}", sht20.temperature(), sht20.humidity()); //我們把要上傳的數(shù)據(jù)寫在param里
postMsgId += 1;
sprintf(jsonBuf, ONENET_POST_BODY_FORMAT, postMsgId, param);
//再從mqtt客戶端中發(fā)布post消息
if (client.publish(ONENET_TOPIC_PROP_POST, jsonBuf))
{
Serial.print("Post message to cloud: ");
Serial.println(jsonBuf);
}
else
{
Serial.println("Publish message to cloud failed!");
}
}
}
//重連函數(shù), 如果客戶端斷線,可以通過此函數(shù)重連
void clientReconnect()
{
while (!client.connected()) //再重連客戶端
{
Serial.println("reconnect MQTT...");
if (client.connect(mqtt_devid, mqtt_pubid, mqtt_password))
{
Serial.println("connected");
}
else
{
Serial.println("failed");
Serial.println(client.state());
Serial.println("try again in 5 sec");
delay(5000);
}
}
}
void setup()
{
Serial.begin(115200); //初始化串口
Wire.begin();
sht20.begin();
delay(3000); //這個延時是為了讓我打開串口助手
setupWifi(); //調用函數(shù)連接WIFI
client.setServer(mqtt_server, port); //設置客戶端連接的服務器,連接Onenet服務器, 使用6002端口
client.connect(mqtt_devid, mqtt_pubid, mqtt_password); //客戶端連接到指定的產品的指定設備.同時輸入鑒權信息
if (client.connected())
{
Serial.println("OneNet is connected!"); //判斷以下是不是連好了.
}
tim1.attach(10, sendTempAndHumi); //定時每10秒調用一次發(fā)送數(shù)據(jù)函數(shù)sendTempAndHumi
}
void loop()
{
if (!WiFi.isConnected()) //先看WIFI是否還在連接
{
setupWifi();
}
if (!client.connected()) //如果客戶端沒連接ONENET, 重新連接
{
clientReconnect();
delay(100);
}
client.loop(); //客戶端循環(huán)檢測
}
三. 下面的版本更全面,配合onenet5.0 API調用的章節(jié)
參考文章:
http://www.reibang.com/p/902a73b4a758
http://www.reibang.com/p/cdf03171346e
http://www.reibang.com/p/c5bb7a63b4cb
#include <Arduino.h>
#include "WiFi.h"
#include "PubSubClient.h"
#include "Ticker.h"
#include "uFire_SHT20.h"
#include "ArduinoJson.h"
uFire_SHT20 sht20;
const char *ssid = "anleng"; //wifi名
const char *password = "al77776666"; //wifi密碼
const char *mqtt_server = "218.201.45.7"; //onenet 的 IP地址
const int port = 1883; //端口號
#define mqtt_pubid "IaiJ9078ZN" //產品ID
#define mqtt_devid "esp_mqtts_001" //設備名稱
//鑒權信息
#define mqtt_password "version=2018-10-31&res=products%2FIaiJ9078ZN%2Fdevices%2Fesp_mqtts_001&et=4092599349&method=md5&sign=nvhmyIawpRbUyAojvL8CRA%3D%3D" //鑒權信息
WiFiClient espClient; //創(chuàng)建一個WIFI連接客戶端
PubSubClient client(espClient); // 創(chuàng)建一個PubSub客戶端, 傳入創(chuàng)建的WIFI客戶端
Ticker tim1; //定時器,用來循環(huán)上傳數(shù)據(jù)
float temp;
float humi;
//設備上傳數(shù)據(jù)的post主題
#define ONENET_TOPIC_PROP_POST "$sys/" mqtt_pubid "/" mqtt_devid "/thing/property/post"
//接收下發(fā)屬性設置主題
#define ONENET_TOPIC_PROP_SET "$sys/" mqtt_pubid "/" mqtt_devid "/thing/property/set"
//接收下發(fā)屬性設置成功的回復主題
#define ONENET_TOPIC_PROP_SET_REPLY "$sys/" mqtt_pubid "/" mqtt_devid "/thing/property/set_reply"
//接收設備屬性獲取命令主題
#define ONENET_TOPIC_PROP_GET "$sys/" mqtt_pubid "/" mqtt_devid "/thing/property/get"
//接收設備屬性獲取命令成功的回復主題
#define ONENET_TOPIC_PROP_GET_REPLY "$sys/" mqtt_pubid "/" mqtt_devid "/thing/property/get_reply"
//這是post上傳數(shù)據(jù)使用的模板
#define ONENET_POST_BODY_FORMAT "{\"id\":\"%u\",\"params\":%s}"
int postMsgId = 0; //記錄已經post了多少條
//連接WIFI相關函數(shù)
void setupWifi()
{
delay(10);
Serial.println("connect WIFI");
WiFi.begin(ssid, password);
while (!WiFi.isConnected())
{
Serial.print(".");
delay(500);
}
Serial.println("OK");
Serial.println("Wifi connected!");
}
//向主題發(fā)送模擬的溫濕度數(shù)據(jù)
void sendTempAndHumi()
{
if (client.connected())
{
//先拼接出json字符串
char param[82];
char jsonBuf[178];
sprintf(param, "{\"temp\":{\"value\":%.2f},\"humi\":{\"value\":%.2f}}", temp, humi); //我們把要上傳的數(shù)據(jù)寫在param里
postMsgId += 1;
sprintf(jsonBuf, ONENET_POST_BODY_FORMAT, postMsgId, param);
//再從mqtt客戶端中發(fā)布post消息
if (client.publish(ONENET_TOPIC_PROP_POST, jsonBuf))
{
Serial.print("Post message to cloud: ");
Serial.println(jsonBuf);
}
else
{
Serial.println("Publish message to cloud failed!");
}
}
}
//重連函數(shù), 如果客戶端斷線,可以通過此函數(shù)重連
void clientReconnect()
{
while (!client.connected()) //再重連客戶端
{
Serial.println("reconnect MQTT...");
if (client.connect(mqtt_devid, mqtt_pubid, mqtt_password))
{
Serial.println("connected");
}
else
{
Serial.println("failed");
Serial.println(client.state());
Serial.println("try again in 5 sec");
delay(5000);
}
}
}
void callback(char *topic, byte *payload, unsigned int length)
{
Serial.println("message rev:");
Serial.println(topic);
for (size_t i = 0; i < length; i++)
{
Serial.print((char)payload[i]);
}
Serial.println();
if (strstr(topic, ONENET_TOPIC_PROP_SET))
{
DynamicJsonDocument doc(100);
DeserializationError error = deserializeJson(doc, payload);
if (error)
{
Serial.println("parse json failed");
return;
}
JsonObject setAlinkMsgObj = doc.as<JsonObject>();
serializeJsonPretty(setAlinkMsgObj, Serial);
String str = setAlinkMsgObj["id"];
Serial.println(str);
char sendbuf[100];
sprintf(sendbuf, "{\"id\": \"%s\",\"code\":200,\"msg\":\"success\"}", str.c_str());
Serial.println(sendbuf);
client.publish(ONENET_TOPIC_PROP_SET_REPLY, sendbuf);
}
if (strstr(topic, ONENET_TOPIC_PROP_GET))
{
DynamicJsonDocument doc(100);
DeserializationError error = deserializeJson(doc, payload);
if (error)
{
Serial.println("parse json failed");
return;
}
JsonObject setAlinkMsgObj = doc.as<JsonObject>();
serializeJsonPretty(setAlinkMsgObj, Serial);
String str = setAlinkMsgObj["id"];
Serial.println(str);
char sendbuf[100];
sprintf(sendbuf, "{\"id\": \"%s\",\"code\":200,\"msg\":\"success\",\"data\":{\"temp\":%.2f,\"humi\":%.2f}}", str.c_str(), sht20.temperature(), sht20.humidity());
Serial.println(sendbuf);
client.publish(ONENET_TOPIC_PROP_GET_REPLY, sendbuf);
}
}
void setup()
{
Serial.begin(115200); //初始化串口
Wire.begin();
sht20.begin();
delay(3000);
setupWifi(); //調用函數(shù)連接WIFI
client.setServer(mqtt_server, port); //設置客戶端連接的服務器,連接Onenet服務器, 使用6002端口
client.connect(mqtt_devid, mqtt_pubid, mqtt_password); //客戶端連接到指定的產品的指定設備.同時輸入鑒權信息
if (client.connected())
{
Serial.println("OneNet is connected!"); //判斷以下是不是連好了.
}
client.subscribe(ONENET_TOPIC_PROP_SET);
client.subscribe(ONENET_TOPIC_PROP_GET);
client.setCallback(callback);
tim1.attach(20, sendTempAndHumi); //定時每20秒調用一次發(fā)送數(shù)據(jù)函數(shù)sendTempAndHumi
}
void loop()
{
temp = sht20.temperature();
humi = sht20.humidity();
if (!WiFi.isConnected()) //先看WIFI是否還在連接
{
setupWifi();
}
if (!client.connected()) //如果客戶端沒連接ONENET, 重新連接
{
clientReconnect();
delay(100);
}
client.loop(); //客戶端循環(huán)檢測
}
四. 期望值獲取
#include <Arduino.h>
#include "WiFi.h"
#include "PubSubClient.h"
#include "Ticker.h"
#include "uFire_SHT20.h"
#include "ArduinoJson.h"
uFire_SHT20 sht20;
const char *ssid = "anlengkj"; //wifi名
const char *password = "al77776666"; //wifi密碼
const char *mqtt_server = "218.201.45.7"; //onenet 的 IP地址
const int port = 1883; //端口號
#define mqtt_pubid "Ygy2xf0iYx" //產品ID
#define mqtt_devid "al00002lk0004" //設備名稱
//鑒權信息
#define mqtt_password "version=2018-10-31&res=products%2FYgy2xf0iYx%2Fdevices%2Fal00002lk0004&et=4083930061&method=md5&sign=LF58PMK3%2FRgB8n9CLVuhfA%3D%3D"
WiFiClient espClient; //創(chuàng)建一個WIFI連接客戶端
PubSubClient client(espClient); // 創(chuàng)建一個PubSub客戶端, 傳入創(chuàng)建的WIFI客戶端
Ticker tim1; //定時器,用來循環(huán)上傳數(shù)據(jù)
float temp;
float humi;
//設備期望值獲取請求主題
#define ONENET_TOPIC_DESIRED_GET "$sys/" mqtt_pubid "/" mqtt_devid "/thing/property/desired/get"
//設備期望值獲取響應主題
#define ONENET_TOPIC_DESIRED_GET_RE "$sys/" mqtt_pubid "/" mqtt_devid "/thing/property/desired/get/reply"
//設備期望值刪除請求主題
#define ONENET_TOPIC_DESIRED_DEL "$sys/" mqtt_pubid "/" mqtt_devid "/thing/property/desired/delete"
//設備期望值刪除響應主題
#define ONENET_TOPIC_DESIRED_DEL_RE "$sys/" mqtt_pubid "/" mqtt_devid "/thing/property/desired/delete/reply"
//這是post上傳數(shù)據(jù)使用的模板
#define ONENET_POST_BODY_FORMAT "{\"id\":\"%u\",\"params\":%s}"
int postMsgId = 0; //記錄已經post了多少條
//連接WIFI相關函數(shù)
void setupWifi()
{
delay(10);
Serial.println("connect WIFI");
WiFi.begin(ssid, password);
while (!WiFi.isConnected())
{
Serial.print(".");
delay(500);
}
Serial.println("OK");
Serial.println("Wifi connected!");
}
void getDesired()
{
if (client.connected())
{
//先拼接出json字符串
char param[82];
char jsonBuf[178];
sprintf(param, "[\"set_flag\",\"temp_alarm\"]"); //我們把要上傳的數(shù)據(jù)寫在param里
// sprintf(param, "[\"set_flag\",\"tempL\",\"tempLA\",\"tempU\",\"tempUA\"]"); //我們把要上傳的數(shù)據(jù)寫在param里
postMsgId += 1;
sprintf(jsonBuf, ONENET_POST_BODY_FORMAT, postMsgId, param);
//再從mqtt客戶端中發(fā)布post消息
if (client.publish(ONENET_TOPIC_DESIRED_GET, jsonBuf))
{
Serial.print("Post message to cloud: ");
Serial.println(jsonBuf);
}
else
{
Serial.println("Publish message to cloud failed!");
}
}
}
//重連函數(shù), 如果客戶端斷線,可以通過此函數(shù)重連
void clientReconnect()
{
while (!client.connected()) //再重連客戶端
{
Serial.println("reconnect MQTT...");
if (client.connect(mqtt_devid, mqtt_pubid, mqtt_password))
{
Serial.println("connected");
}
else
{
Serial.println("failed");
Serial.println(client.state());
Serial.println("try again in 5 sec");
delay(5000);
}
}
}
void callback(char *topic, byte *payload, unsigned int length)
{
Serial.println("message rev:");
Serial.println(topic);
for (size_t i = 0; i < length; i++)
{
Serial.print((char)payload[i]);
}
Serial.println();
if (strstr(topic, ONENET_TOPIC_DESIRED_GET))
{
DynamicJsonDocument doc(512);
DeserializationError error = deserializeJson(doc, payload);
if (error)
{
Serial.println("parse json failed");
return;
}
JsonObject setAlinkMsgObj = doc.as<JsonObject>();
serializeJsonPretty(setAlinkMsgObj, Serial);
String str = setAlinkMsgObj["data"]["set_flag"]["value"];
Serial.println(str);
}
}
void setup()
{
Serial.begin(115200); //初始化串口
Wire.begin();
sht20.begin();
delay(3000);
setupWifi(); //調用函數(shù)連接WIFI
client.setServer(mqtt_server, port); //設置客戶端連接的服務器,連接Onenet服務器, 使用6002端口
client.connect(mqtt_devid, mqtt_pubid, mqtt_password); //客戶端連接到指定的產品的指定設備.同時輸入鑒權信息
if (client.connected())
{
Serial.println("OneNet is connected!"); //判斷以下是不是連好了.
}
client.subscribe(ONENET_TOPIC_DESIRED_GET);
client.subscribe(ONENET_TOPIC_DESIRED_GET_RE);
client.setCallback(callback);
tim1.attach(20, getDesired); //定時每20秒調用一次發(fā)送數(shù)據(jù)函數(shù)sendTempAndHumi
}
void loop()
{
temp = sht20.temperature();
humi = sht20.humidity();
if (!WiFi.isConnected()) //先看WIFI是否還在連接
{
setupWifi();
}
if (!client.connected()) //如果客戶端沒連接ONENET, 重新連接
{
clientReconnect();
delay(100);
}
client.loop(); //客戶端循環(huán)檢測
}