【BIGTREETECH PI开发板】将各种传感器和控制器通过mqtt接入智能中枢
[复制链接]
本帖最后由 moveing 于 2023-8-8 23:51 编辑
传感器就像智能家居的眼睛,收集环境中的各项数据,汇总起来按情况执行设定好的自动化程序。控制器相当于智能家居的手,自动化任务要通过控制器来实现。原有的项目中使用了温度、湿度、光照、可燃气、人体存在、人脸识别等传感器,舵机、门禁等执行器。
每个传感器都在不同房间的不同位置,所以想接入中枢只能靠无线的方式,目前主流的有蓝牙、WiFi、ZigBee。蓝牙传输距离较短,并且令需一个单片机控制蓝牙模块、ZigBee价格比较贵...每个传感器都配一个ZigBee,全屋大概有二三十个算下来成本惊人,而WiFi就比较友好了,资料多型号多传输距离长无需另外配网关,最关键的是成本极低!esp01s:8mbflash、2个gpio、3v供电71mA。可以说是带WiFi功能的单片机,个人小批量采购单价只需5r+!
直接接入是不行的,需要通过我们前面搭建的mqtt服务器。可以这么理解:mqtt服务器是传输的数据中心,所有的传感器,后面的控制器,以及hass智能中枢都要接入它。
在传输过程中数据是不加密的,以广播的形式在局域网内发送,每个数据包都有一个Topic,网内所有设备都会收到这个数据包,但如果Topic与自己订阅的不相符设备就会直接丢弃,相符时才会进一步读取数据。
所以我们要为每一个传感器分配一个唯一的Topic(是每一个不是每一种哦)用来发布,然后hass要订阅所有传感器的Topic;每一个执行器要订阅一个唯一的Topic用来接收hass的指令。
虽然每个传感器都不一样,但大体思路是相同的。传感器:esp-01s配置好WiFi、mqtt地址、发布的Topic、读取传感器的数据,定时发送。执行器:配置好WiFi、mqtt地址、提前选好订阅的topic、构造好数据包结构、写好解包函数、写好动作函数。esp-01sflash太小是不好做ota了,所以一定要测试好程序,否则需要拆下来重新烧录,很麻烦。
有一点要注意:正常开机运行时GPIO0是不可以下拉的,会进入烧录模式,有些传感器需要用到两个GPIO口,连接时需要注意。如果实在无法避免还有一个办法,先给esp-01s上电,延迟三秒再给传感器上电,这样就可以避免进入烧录模式,具体怎么实现就不细说了。
这里给一个dht11温湿度的程序,其他光照、可燃气、人体等传感器与之类似没有结构性的变化
#include <SimpleDHT.h>
#include <PubSubClient.h>
#include <ESP8266WiFi.h>
const char* ssid = "3.1415926";
const char* password = "13305451048";
const char* mqtt_server = "192.168.100.182";
const char* client_id = "North-Room-dht11-1";
const char* TOPIC = "homeassistant/sensor/North-Room-dht11-1/state";//发布的Topic
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
int pinDHT11 = 2;//dht11连接esp-01s 2gpio口
SimpleDHT11 dht11(pinDHT11);
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();
}//回调函数
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");// 正在连接mqtt
if (client.connect(client_id)) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");// 5秒后重试
delay(5000);
}
}
}
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}//连接WiFi函数
void setup() {
Serial.begin(115200);
Serial.println("system setup");
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
Serial.println("---------------------------");
byte temperature = 0;
byte humidity = 0;//温湿度变量
int err = SimpleDHTErrSuccess;
if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
Serial.print("Read DHT11 failed, err=");
Serial.println(err);
delay(1000);
return;
}
Serial.print("Sample OK: ");
Serial.print((int)temperature);
Serial.print(" *C, ");
Serial.print((int)humidity);
Serial.println(" H");
String payload = "{";
payload += "\"温度\":";
payload += "\"";
payload += temperature;
payload += "\"";
payload += ",";
payload += "\"湿度\":";
payload += "\"";
payload += humidity;
payload += "\"";
payload += "}";
char attributes[100];
payload.toCharArray(attributes, 100);
client.publish(TOPIC, attributes);//发送数据
delay(1500);//不要频繁发送,减小网络压力
}
烧录好程序,上电,打开emqx服务器web端,就可以看到出现了一个新的连接
连接的传感器都可以在这里看到,一定要定义好名称,方便管理
接下来将传感器的信息显示到hass面板上
configuration.yaml中,将各种传感器按类型分类,输入各自的topic
mqtt:
light:
- command_topic: "homeassistant/light/Room/"
name: "客厅灯"
sensor:
- state_topic: "homeassistant/sensor/North-Room-dht11-1/state"
name: "北卧室温度"
unit_of_measurement: "℃"
value_template: '{{ value_json.batt }}'
- state_topic: "homeassistant/sensor/North-Room-Ray-1/state"
name: "北卧室窗外光线"
unit_of_measurement: ""
value_template: '{{ value_json.batt }}'
- state_topic: "homeassistant/sensor/North-Room-Ray-2/state"
name: "北卧室室内光线"
unit_of_measurement: ""
value_template: '{{ value_json.batt }}'
- state_topic: "homeassistant/sensor/South-Room-Ray-1/state"
name: "南卧室窗外光线"
unit_of_measurement: ""
value_template: '{{ value_json.batt }}'
- state_topic: "homeassistant/sensor/South-Room-Ray-2/state"
name: "南卧室窗内光线"
unit_of_measurement: ""
value_template: '{{ value_json.batt }}'
- state_topic: "homeassistant/sensor/Kitchen-fire/state"
name: "可燃气传感器"
unit_of_measurement: ""
value_template: '{{ value_json.batt }}'
binary_sensor:
- state_topic: "homeassistant/sensor/North-Room-body/state"
name: "北卧室人体"
device_class: opening
value_template: '{{ value.x }}'
- state_topic: "homeassistant/sensor/South-Room-body/state"
name: "南卧室人体"
device_class: opening
value_template: '{{ value.x }}'
在仪表盘里添加各种传感器即可
|