用于数据的序号展示
|
|
Temperature
|
储存温度值
|
|
Humidity
|
储存湿度值
|
|
ts
|
储存数据上传时的时间戳
|
Ps:“ID” 字段要勾上 “自动递增” 方便排序,在数据表中看上去更直观
并将表名命名为 “Temp_Humi_Data”
3.2、phpMyAdmin方法
点击 “phpMyAdmin” 或 “管理” 进入phpMyAdmin进行数据库管理
“新建表” 添加以下4个字段,并将表命名为 “Temp_Humi_Data”
三、EMQ X Enterprise的安装与规则创建
下载链接:https://www.emqx.cn/downloads
这里使用的是Ubuntu 18.04 LTS,我使用的是以下下载方法
若系统是Ubuntu 18.04LTS,选择的参数与上图一致,则可依次执行以下指令
- 下载Zip压缩包
wget https://www.emqx.cn/downloads/enterprise/v4.2.5/emqx-ee-ubuntu18.04-4.2.5-x86_64.zip
- 解压下载好的Zip压缩包
unzip emqx-ee-ubuntu18.04-4.2.5-x86_64.zip
- 进入解压后的文件夹emqx
cd ./emqx
- 开启EMQ X服务
./bin/emqx start
2、EMQ X Entterprise配置
在网址栏输入“云服务器公网IP:18083”,进入 EMQ X Dashboard
在左侧选中“规则引擎”—“资源”—“创建”,按照下图填写(注意:带有MySQL字样的参数,都是在宝塔中新建数据库的参数,要保证参数一致)
创建完资源后,接着创建规则,在 “SQL输入” 中输入以下SQL语句
SELECT
payload.Temperature AS Temperature,
payload.Humidity AS Humidity,
payload.ts AS ts
FROM
“Device_pubTopic/Temp_Humi”
这里是获取 “Device_pubTopic/Temp_Humi” payload中“Temperature”、“Humidity”、“ts”字段的值
然后下去添加响应动作
其中 “使用资源” 为我们刚才创建的资源
SQL模板:
INSERT INTO
Temp_Humi_Data
(Temperature
, Humidity
, ts
)
VALUES
(${Temperature}, ${Humidity}, ${ts});
这里的意思是,向 “Temp_Humi_Data” 数据表中写入“Temperature”、“Humidity”、“ts”的值
配置好后,本规则就可以将payload中的 “温湿度及时间戳” 数据提取出来,并转存到MySQL中相应数据库的相应数据表中
3、MQTTX测试
接下来使用MQTTX进行测试,打开MQTTX,新建一个连接,填写以下参数
在EMQ X Dashboard界面左侧“工具”—“WebSocket”填写 “”连接配置“” 的参数,并订阅设备发布的主题 “Device_pubTopic/Temp_Humi”
注意事项:Client_ID不要和MQTTX中的Client_ID相同,不然会导致MQTTX连接后自动断开
由下图可看出消息的发布与接收均正常
(红色为MQTTX发布到服务器的JSON数据,蓝色为服务器发布到MQTTX的JSON数据)
四、代码
本项目获取的时间戳是使用了苏宁网站的授时网页提供的 http://quan.suning.com/getSysTime.do
对此需要对网站内容进行JSON格式解析,提取出 “sysTime2” 字段的值 “2021-04-20 20:29:03”
核心代码
http.setTimeout(5000); //设置5s超时
http.begin(“http://quan.suning.com/getSysTime.do”); //HTTP初始化
int httpCode = http.GET(); //发送HTTP请求,返回状态码
if (httpCode > 0) {
Serial.printf(“[HTTP] GET… code: %d\n”, httpCode);
if (httpCode == HTTP_CODE_OK) {
//读取响应内容
JSON_DATA = http.getString();
//这里返回的是json格式的字符串
deserializeJson(Doc, JSON_DATA);
JsonObject Obj = Doc.as();
Field_Val = Obj[“sysTime2”]; //获取Json数据中的字段值Field(2020-04-20 20:29:03)
}
} else {
Serial.printf(“[HTTP] GET… failed, error: %s\n”, http.errorToString(httpCode).c_str());
}
http.end(); //接收完数据后,触发end事件
1.2、设备消息发布
核心代码
unsigned long now = millis();
if (now - lastMsg > 10000) {
Get_Time(); //从网站获得网页内容
Get_Temp_Humi(); //获取温湿度数据
lastMsg = now;
//String MQTT_Msg = “{“Temperature”: “%.1f”,“Humidity”: “%.1f”,“ts”: “%s”}”;
//将消息模板和温湿度、时间戳数据合并到一起
snprintf (Msg, Msg_LEN, MQTT_Msg, Temp, Humi, Field_Val.c_str());
Serial.print("Publish message: ");
Serial.println(Msg);
client.publish(pubTopic, Msg);
}
1.3、数据库消息
2、完整代码
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <dht.h>
/连接的Wi-Fi、服务器地址/
const char* ssid = “SSID”;
const char* password = “PASSWORD”;
const char* mqtt_server = “xxx.xxx.xxx.xxx”;
/设置发布和订阅的主题/
const char* subTopic = “Cloud_pubTopic”; //subTopic
const char* pubTopic = “Device_pubTopic/Temp_Humi”; //pubTopic
#define MQTT_Msg “{“Temperature”: “%.1f”,“Humidity”: “%.1f”,“ts”: “%s”}”
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
#define Msg_LEN 100
char Msg[Msg_LEN];
HTTPClient http;
String GetUrl = “http://quan.suning.com/getSysTime.do”;
String JSON_DATA;
#define JSON_LEN 100
DynamicJsonDocument Doc(JSON_LEN);
String Target = “sysTime2”;
String Field_Val = “”;
dht DHT;
#define DHT11_PIN D2
float Temp, Humi;
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(“.”);
}
randomSeed(micros());
Serial.println(“”);
Serial.println(“WiFi connected”);
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
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();
// Switch on the LED if an 1 was received as first character
if ((char)payload[0] == ‘1’) {
digitalWrite(BUILTIN_LED, LOW); // Turn the LED on (Note that LOW is the voltage level
// but actually the LED is on; this is because
// it is active low on the ESP-01)
} else {
digitalWrite(BUILTIN_LED, HIGH); // Turn the LED off by making the voltage HIGH
}
}
void reconnect() {
// Loop until we’re reconnected
while (!client.connected()) {
Serial.print(“Attempting MQTT connection…”);
// Create a random client ID
String clientId = “ESP8266Client-”;
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println(“connected”);
// Once connected, publish an announcement…
// client.publish(pubTopic, “hello world”);
// … and resubscribe
client.subscribe(subTopic);
} else {
Serial.print(“failed, rc=”);
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup() {
pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
// 连接苏宁网站的授时网页
http.setTimeout(5000);
http.begin(GetUrl);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
unsigned long now = millis();
if (now - lastMsg > 10000) {
Get_Time(); //从网站获得网页内容
Get_Temp_Humi(); //获取温湿度数据
lastMsg = now;
//String MQTT_Msg = “{“Temperature”: “%.1f”,“Humidity”: “%.1f”,“ts”: “%s”}”;
snprintf (Msg, Msg_LEN, MQTT_Msg, Temp, Humi, Field_Val.c_str());
Serial.print("Publish message: ");
Serial.println(Msg);
client.publish(pubTopic, Msg);
}
}
/**********
- 读取DHT11的温湿度数据
**********/
void Get_Temp_Humi() {
int chk = DHT.read11(DHT11_PIN);
switch (chk)
{
case DHTLIB_OK:
Serial.print(“OK,\t”);
break;
case DHTLIB_ERROR_CHECKSUM:
Serial.print(“Checksum error,\t”);
break;
case DHTLIB_ERROR_TIMEOUT:
Serial.print(“Time out error,\t”);
break;
default:
Serial.print(“Unknown error,\t”);
break;
}
Temp = DHT.temperature;
Humi = DHT.humidity;
}
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
out error,\t");
break;
default:
Serial.print(“Unknown error,\t”);
break;
}
Temp = DHT.temperature;
Humi = DHT.humidity;
}
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-4ZfomFK7-1714720409842)]
[外链图片转存中…(img-6uDATdvC-1714720409843)]
[外链图片转存中…(img-CR0h6EPs-1714720409843)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!