玩转OneNET物联网平台之MQTT服务③|玩转OneNET物联网平台之MQTT服务③ —— 远程控制LED(设备自注册)
文章图片
image 1.理论基础
????参考博主线上博文:
- 玩转PubSubClient MQTT库
- 玩转OneNET物联网平台之简介
- 玩转OneNET物联网平台之MQTT服务①
- 玩转OneNET物联网平台之MQTT服务②
- 人为手动控制,对于开发者来说极度不友好;
- 如果设备数量很多,岂不是要手动操作非常多次;
- 为了区分唯一性,我们采用ESP-Mac地址的组合形式
- ESP8266 NodeMcu
- OneNet Mqtt调试工具
- OneNet平台
2.2.1 创建 ESP8266智能灯系统 产品(MQTT协议)
文章图片
image 注意点:
- 务必选择MQTT协议
文章图片
image 注意点:
- 需要记录产品ID,其用来区分产品唯一标识符
- Master-APIkey,网络请求鉴权信息,接口调用需要带入
- P_OneNet_Exam04.ino文件:
/**
*功能:ESP8266 Mqtt客户端自注冊功能,订阅OneNet Mqtt工具发过来的控制Led消息
*作者:单片机菜鸟
*时间:2019-06-30
*描述:
*1.初始化工作:初始化网络配置,Mqtt客户端自注冊,连接鉴权,订阅主题
*2.订阅消息:获取发送过来的消息(json格式),解析消息,实现控制亮灭灯
*/#include
#include #include
#include
#include
#include
#include "H_project.h"#define MAGIC_NUMBER 0xAAint state;
WiFiClient espClient;
//声明方法
void initSystem();
void initOneNetMqtt();
void callback(char* topic, byte* payload, unsigned int length);
void saveConfig();
void loadConfig();
bool parseRegisterResponse();
/**
* 初始化
*/
void setup() {
initSystem();
initOneNetMqtt();
}void loop() {
ESP.wdtFeed();
state = connectToOneNetMqtt();
if(state == ONENET_RECONNECT){
//重连成功 需要重新注册
mqttClient.subscribe(TOPIC,1);
mqttClient.loop();
}else if(state == ONENET_CONNECTED){
mqttClient.loop();
}
delay(2000);
}void initSystem(){
int cnt = 0;
Serial.begin (115200);
Serial.println("\r\n\r\nStart ESP8266 MQTT");
Serial.print("Firmware Version:");
Serial.println(VER);
Serial.print("SDK Version:");
Serial.println(ESP.getSdkVersion());
wifi_station_set_auto_connect(0);
//关闭自动连接
ESP.wdtEnable(5000);
WiFi.disconnect();
delay(100);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
cnt++;
Serial.print(".");
if(cnt>=40){
cnt = 0;
//重启系统
delayRestart(1);
}
}
pinMode(LED_BUILTIN, OUTPUT);
loadConfig();
//还没有注册
if(strcmp(config.deviceid,DEFAULT_ID) == 0){
int tryAgain = 0;
while(!registerDeviceToOneNet()){
Serial.print(".");
delay(500);
tryAgain++;
if(tryAgain == 5){
//尝试5次
tryAgain = 0;
//重启系统
delayRestart(1);
}
}
if(!parseRegisterResponse()){
//重启系统
delayRestart(1);
while(1);
}
}
}void initOneNetMqtt(){
mqttClient.setServer(mqttServer,mqttPort);
mqttClient.setClient(espClient);
mqttClient.setCallback(callback);
initOneNet(PRODUCT_ID,API_KEY,config.deviceid);
}void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0;
i < length;
i++) {
Serial.print((char)payload[i]);
}
Serial.println();
if ((char)payload[0] == '1') {
digitalWrite(LED_BUILTIN, LOW);
} else {
digitalWrite(LED_BUILTIN, HIGH);
}
}/*
* 保存参数到EEPROM
*/
void saveConfig()
{
Serial.println("Save OneNet config!");
Serial.print("deviceId:");
Serial.println(config.deviceid);
EEPROM.begin(150);
uint8_t *p = (uint8_t*)(&config);
for (int i = 0;
i < sizeof(config);
i++)
{
EEPROM.write(i, *(p + i));
}
EEPROM.commit();
}/*
* 从EEPROM加载参数
*/
void loadConfig()
{
EEPROM.begin(150);
uint8_t *p = (uint8_t*)(&config);
for (int i = 0;
i < sizeof(config);
i++)
{
*(p + i) = EEPROM.read(i);
}
EEPROM.commit();
if (config.magic != MAGIC_NUMBER)
{
strcpy(config.deviceid, DEFAULT_ID);
config.magic = MAGIC_NUMBER;
saveConfig();
Serial.println("Restore config!");
}
Serial.println("-----Read config-----");
Serial.print("deviceId:");
Serial.println(config.deviceid);
Serial.println("-------------------");
}/**
* 解析注册返回结果
*/
bool parseRegisterResponse(){
Serial.println("start parseRegisterResponse");
StaticJsonBuffer<200> jsonBuffer;
// StaticJsonBuffer 在栈区分配内存它也可以被 DynamicJsonBuffer(内存在堆区分配) 代替
// DynamicJsonBufferjsonBuffer;
JsonObject& root = jsonBuffer.parseObject(response);
// Test if parsing succeeds.
if (!root.success()) {
Serial.println("parseObject() failed");
return false;
}int errno = root["errno"];
if(errno !=0){
Serial.println("register failed!");
return false;
}else{
Serial.println("register sucess!");
strcpy(config.deviceid, root["data"]["device_id"]);
saveConfig();
return true;
}
}
- H_project.h 代码:
#ifndef _MAIN_H__
#define _MAIN_H__extern "C" {
#include "user_interface.h"
#include "smartconfig.h"
}struct onenet_config
{
char deviceid[15];
uint8_t magic;
};
/************** ESP8266相关操作 **************************/
void delayRestart(float t);
void delayNs(uint8_t m);
/*********************************************************//*************** OneNet MQTT相关操作 ****************************/
void initOneNet(uint8_t *productId,uint8_t *apiKey,uint8_t *deviceId);
int connectToOneNetMqtt();
/*********************************************************//**************** OneNet Http相关操作 ***************************/
HTTPClient http;
String response;
const char* host = "api.heclouds.com";
bool registerDeviceToOneNet();
/****************************************************************/#define ONENET_DISCONNECTED 1 //已经断开
#define ONENET_CONNECTED 2//已经连接上
#define ONENET_RECONNECT 3//重连成功//常量
#define VER"MQTT_LED_V1.0"
const char* ssid = "xxxxxxxx";
//wifi账号
const char* password = "xxxxxxx";
//wifi秘密//OneNet相关
PubSubClient mqttClient;
const char* mqttServer = "183.230.40.39";
//mqtt服务器
const uint16_t mqttPort = 6002;
#define PRODUCT_ID"253190" //此为博哥自己的产品id 请新建自己的
#define API_KEY"aat9ivuJls3gcAFWnLoxfbwW8bI="
#define DEFAULT_ID "123456"
#define TOPIC"esp8266led"unsigned long lastWiFiCheckTick = 0;
bool ledState = 0;
onenet_config config;
#endif
????全部工程代码,博哥放在个人QQ群里。
文章图片
image 注意点:
- 这里用到了JSON,请参考博哥上线博文 玩转ArduinoJson库 V5版本;
- 我们这里使用到了ESP8266 HttpClient来封装Http请求;
文章图片
image
文章图片
image
文章图片
image ????同时,也可以在OneNet平台看到设备情况,如下:
文章图片
image ????接下来就可以通过mqtt调试工具进行远程控制led了。
3.总结 【玩转OneNET物联网平台之MQTT服务③|玩转OneNET物联网平台之MQTT服务③ —— 远程控制LED(设备自注册)】在理解MQTT协议的基础上,本篇是非常容易操作的,但是也需要注意几点:
- 创建自己的OneNet产品,不要用博哥创建的
- 理解订阅主题含义,尝试去使用onenet提供的api接口。
推荐阅读
- 看财报|“0糖”不香了?三元生物上半年净利润减少50%,股价半年近腰斩 | 看财报
- 整数有约 | 深言科技(一款应用拯救“词不达意”,理工科也能玩转浪漫)
- 【真送礼物】1|【真送礼物】1 分钟 Serverless 极速部署盲盒平台,自己部署自己抽!
- 投稿|灵魂人物离职,特斯拉是否会坚持纯视觉?
- 生物医药|制药巨头也不好混了?
- 父母能给孩子的最好礼物是什么()
- 【宠物喂食器】
- 物联网|数字孪生 - 认知篇
- 物联网|物联网平台通用后端架构设计
- 物流|【零售流通周报】 每日优鲜被强制执行127万元;今年全球电子商务将首次出现萎缩;考拉海购业务团队从400人收缩至不足20人;格力电器试图进军外卖