mirror of
https://gitee.com/beecue/fastbee.git
synced 2025-12-17 16:36:03 +08:00
固件优化
This commit is contained in:
296
sdk/Arduino/WumeiArduino/User.cpp
Normal file
296
sdk/Arduino/WumeiArduino/User.cpp
Normal file
@@ -0,0 +1,296 @@
|
||||
/*********************************************************************
|
||||
* function: 用户自定义功能
|
||||
* board: esp8266 core for arduino v3.0.2
|
||||
* library: PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
|
||||
* source: https://gitee.com/kerwincui/wumei-smart
|
||||
* copyright: wumei-smart and kerwincui all rights reserved.
|
||||
********************************************************************/
|
||||
|
||||
#include "User.h"
|
||||
#define BUTTON 14 // 按键引脚
|
||||
#define RELAY 12 // 继电器引脚
|
||||
|
||||
OneButton button;
|
||||
// 按钮单击事件
|
||||
static void buttonClick();
|
||||
// 按钮双击事件
|
||||
static void buttonDoubleClick();
|
||||
// 按钮长按事件
|
||||
static void buttonLongPress();
|
||||
|
||||
// 初始化用户配置
|
||||
void initUser()
|
||||
{
|
||||
// 初始化按键为低电平,并添加单击、双击、长按事件
|
||||
button = OneButton(BUTTON, true, true);
|
||||
button.attachClick(buttonClick);
|
||||
button.attachDoubleClick(buttonDoubleClick);
|
||||
button.attachLongPressStart(buttonLongPress);
|
||||
}
|
||||
|
||||
// Mqtt回调
|
||||
void mqttCallback(char *topic, byte *payload, unsigned int length)
|
||||
{
|
||||
blink();
|
||||
printMsg("接收数据:");
|
||||
String data = "";
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
Serial.print((char)payload[i]);
|
||||
data += (char)payload[i];
|
||||
}
|
||||
|
||||
if (strcmp(topic, (prefix + sOtaTopic).c_str()) == 0)
|
||||
{
|
||||
printMsg("订阅到设备升级指令...");
|
||||
StaticJsonDocument<256> doc;
|
||||
DeserializationError error = deserializeJson(doc, payload);
|
||||
if (error)
|
||||
{
|
||||
Serial.print(F("deserializeJson() failed: "));
|
||||
Serial.println(error.f_str());
|
||||
return;
|
||||
}
|
||||
String newVersion = doc["version"];
|
||||
String downloadUrl = doc["downloadUrl"];
|
||||
printMsg("固件版本:" + newVersion);
|
||||
printMsg("下载地址:" + downloadUrl);
|
||||
}
|
||||
else if (strcmp(topic, (prefix + sInfoTopic).c_str()) == 0)
|
||||
{
|
||||
printMsg("订阅到设备信息...");
|
||||
// 发布设备信息
|
||||
publishInfo();
|
||||
}
|
||||
else if (strcmp(topic, (prefix + sNtpTopic).c_str()) == 0)
|
||||
{
|
||||
printMsg("订阅到NTP时间...");
|
||||
StaticJsonDocument<256> doc;
|
||||
DeserializationError error = deserializeJson(doc, payload);
|
||||
if (error)
|
||||
{
|
||||
Serial.print(F("deserializeJson() failed: "));
|
||||
Serial.println(error.f_str());
|
||||
return;
|
||||
}
|
||||
// 计算设备当前时间:(${serverRecvTime} + ${serverSendTime} + ${deviceRecvTime} - ${deviceSendTime}) / 2
|
||||
float deviceSendTime = doc["deviceSendTime"];
|
||||
float serverSendTime = doc["serverSendTime"];
|
||||
float serverRecvTime = doc["serverRecvTime"];
|
||||
float deviceRecvTime = millis();
|
||||
float now = (serverSendTime + serverRecvTime + deviceRecvTime - deviceSendTime) / 2;
|
||||
printMsg("当前时间:" + String(now, 0));
|
||||
}
|
||||
else if (strcmp(topic, (prefix + sPropertyTopic).c_str()) == 0 || strcmp(topic, (prefix + sPropertyOnline).c_str()) == 0)
|
||||
{
|
||||
printMsg("订阅到属性指令...");
|
||||
processProperty(data);
|
||||
}
|
||||
else if (strcmp(topic, (prefix + sFunctionTopic).c_str()) == 0 || strcmp(topic, (prefix + sFunctionOnline).c_str()) == 0)
|
||||
{
|
||||
printMsg("订阅到功能指令...");
|
||||
processFunction(data);
|
||||
}
|
||||
else if (strcmp(topic, (prefix + sMonitorTopic).c_str()) == 0)
|
||||
{
|
||||
printMsg("订阅到实时监测指令...");
|
||||
StaticJsonDocument<128> doc;
|
||||
DeserializationError error = deserializeJson(doc, payload);
|
||||
if (error)
|
||||
{
|
||||
Serial.print(F("deserializeJson() failed: "));
|
||||
Serial.println(error.f_str());
|
||||
return;
|
||||
}
|
||||
monitorCount = doc["count"];
|
||||
monitorInterval = doc["interval"];
|
||||
}
|
||||
}
|
||||
|
||||
// 随机生成监测值
|
||||
String randomPropertyData()
|
||||
{
|
||||
// 匹配云端定义的监测数据,随机数代替监测值
|
||||
float randFloat = 0;
|
||||
int randInt = 0;
|
||||
StaticJsonDocument<1024> doc;
|
||||
JsonObject objTmeperature = doc.createNestedObject();
|
||||
objTmeperature["id"] = "temperature";
|
||||
randFloat = random(1000, 3000);
|
||||
objTmeperature["value"] = (String)(randFloat / 100);
|
||||
objTmeperature["remark"] = (String)millis();
|
||||
|
||||
JsonObject objHumidity = doc.createNestedObject();
|
||||
objHumidity["id"] = "humidity";
|
||||
randFloat = random(3000, 6000);
|
||||
objHumidity["value"] = (String)(randFloat / 100);
|
||||
objHumidity["remark"] = (String)millis();
|
||||
|
||||
JsonObject objCo2 = doc.createNestedObject();
|
||||
objCo2["id"] = "co2";
|
||||
randInt = random(400, 1000);
|
||||
objCo2["value"] = (String)(randInt);
|
||||
objCo2["remark"] = (String)millis();
|
||||
|
||||
JsonObject objBrightness = doc.createNestedObject();
|
||||
objBrightness["id"] = "brightness";
|
||||
randInt = random(1000, 10000);
|
||||
objBrightness["value"] = (String)(randInt);
|
||||
objBrightness["remark"] = (String)millis();
|
||||
|
||||
printMsg("模拟监测数据值:");
|
||||
serializeJson(doc, Serial);
|
||||
String output;
|
||||
serializeJson(doc, output);
|
||||
return output;
|
||||
}
|
||||
|
||||
// 物模型-属性处理
|
||||
void processProperty(String msg)
|
||||
{
|
||||
StaticJsonDocument<1024> doc;
|
||||
DeserializationError error = deserializeJson(doc, msg);
|
||||
if (error)
|
||||
{
|
||||
Serial.print(F("deserializeJson() failed: "));
|
||||
Serial.println(error.f_str());
|
||||
return;
|
||||
}
|
||||
for (JsonObject object : doc.as<JsonArray>())
|
||||
{
|
||||
// 匹配云端定义的属性(不包含属性中的监测数据)
|
||||
const char *id = object["id"];
|
||||
const char *value = object["value"];
|
||||
printMsg((String)id + ":" + (String)value);
|
||||
}
|
||||
// 最后发布属性,服务端订阅存储(重要)
|
||||
publishProperty(msg);
|
||||
}
|
||||
|
||||
// 物模型-功能处理
|
||||
void processFunction(String msg)
|
||||
{
|
||||
StaticJsonDocument<1024> doc;
|
||||
DeserializationError error = deserializeJson(doc, msg);
|
||||
if (error)
|
||||
{
|
||||
Serial.print(F("deserializeJson() failed: "));
|
||||
Serial.println(error.f_str());
|
||||
return;
|
||||
}
|
||||
for (JsonObject object : doc.as<JsonArray>())
|
||||
{
|
||||
// 匹配云端定义的功能
|
||||
const char *id = object["id"];
|
||||
const char *value = object["value"];
|
||||
if (strcmp(id, "switch") == 0)
|
||||
{
|
||||
printMsg("开关 switch:" + (String)value);
|
||||
if (strcmp(value, "1") == 0)
|
||||
{
|
||||
// 打开继电器
|
||||
relayStatus(true);
|
||||
}
|
||||
else if (strcmp(value, "0") == 0)
|
||||
{
|
||||
// 关闭继电器
|
||||
relayStatus(false);
|
||||
}
|
||||
}
|
||||
else if (strcmp(id, "gear") == 0)
|
||||
{
|
||||
printMsg("档位 gear:" + (String)value);
|
||||
}
|
||||
else if (strcmp(id, "light_color") == 0)
|
||||
{
|
||||
printMsg("灯光颜色 light_color:" + (String)value);
|
||||
}
|
||||
else if (strcmp(id, "message") == 0)
|
||||
{
|
||||
printMsg("屏显消息 message:" + (String)value);
|
||||
}
|
||||
else if (strcmp(id, "report_monitor") == 0)
|
||||
{
|
||||
String msg = randomPropertyData();
|
||||
printMsg("订阅到上报监测数据指令,上报数据:");
|
||||
printMsg(msg);
|
||||
publishProperty(msg);
|
||||
}
|
||||
}
|
||||
// 最后发布功能,服务端订阅存储(重要)
|
||||
publishFunction(msg);
|
||||
}
|
||||
|
||||
// 物模型-事件上传
|
||||
void processEvent()
|
||||
{
|
||||
// 匹配云端的事件
|
||||
StaticJsonDocument<512> doc;
|
||||
JsonObject objTmeperature = doc.createNestedObject();
|
||||
objTmeperature["id"] = "height_temperature";
|
||||
objTmeperature["value"] = "40";
|
||||
objTmeperature["remark"] = "温度过高警告";
|
||||
|
||||
JsonObject objException = doc.createNestedObject();
|
||||
objException["id"] = "exception";
|
||||
objException["value"] = "异常消息,消息内容XXXXXXXX";
|
||||
objException["remark"] = "设备发生错误";
|
||||
|
||||
printMsg("发布事件:");
|
||||
serializeJson(doc, Serial);
|
||||
String output;
|
||||
serializeJson(doc, output);
|
||||
|
||||
// 最后发布功能,服务端订阅存储(重要)
|
||||
publishEvent(output);
|
||||
}
|
||||
|
||||
//打开继电器A
|
||||
void relayStatus(bool status)
|
||||
{
|
||||
pinMode(RELAY, OUTPUT);
|
||||
if (status)
|
||||
{
|
||||
digitalWrite(RELAY, HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
digitalWrite(RELAY, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
// 按钮单击事件
|
||||
static void buttonClick()
|
||||
{
|
||||
printMsg("检测到按键单击,打开继电器");
|
||||
relayStatus(true);
|
||||
// 匹配云端定义的开关,格式如:[{"id":"switch","value":"1"}]
|
||||
String msg = "[{\"id\":\"switch\",\"value\":\"1\"}]";
|
||||
publishProperty(msg);
|
||||
}
|
||||
|
||||
// 按钮双击事件
|
||||
static void buttonDoubleClick()
|
||||
{
|
||||
printMsg("检测到按键双击,关闭继电器");
|
||||
relayStatus(false);
|
||||
// 匹配云端定义的开关,格式如:[{"id":"switch","value":"0"}]
|
||||
String msg = "[{\"id\":\"switch\",\"value\":\"0\"}]";
|
||||
publishProperty(msg);
|
||||
}
|
||||
|
||||
// 按钮长按事件,进入配网模式
|
||||
static void buttonLongPress()
|
||||
{
|
||||
printMsg("检测到按键长按");
|
||||
if (isApMode)
|
||||
{
|
||||
printMsg("设备重启...");
|
||||
ESP.restart();
|
||||
}
|
||||
else
|
||||
{
|
||||
printMsg("开始AP配网");
|
||||
startApConfig();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user