|
接触HomeAssistant大概一周了,在论坛找到了很多教程学习。现在特发一个使用攀藤G5通过WidoraAIR(EPS32)接入HomeAssistant教程以回报论坛。
一、硬件介绍:
1.攀藤G5是一款可以同时监测空气中颗粒物浓度和甲醛浓度的二合一传感器。其中颗粒物浓度的监测基于激光散射原理,可连续采集并计算单位体积内空气中不同粒径的悬浮颗粒物个数,即颗粒物浓度分布,进而换算成为质量浓度。甲醛浓度的监测基于电化学原理,具有高精度、高稳定性的特点。颗粒物浓度数值和甲醛浓度数值合并以通用数字接口形式输出。
检测出来的数据通过串口发出来,波特率:9600kbps 校验位:无 停止位:1位
攀藤数据输出格式1
攀藤数据输出格式2
2.WidoraAIR是一款ESP32板子。把攀藤G5接到WidoraAIR第2号串口上,也就是16、17号IO口上。(16:RX,17:TX)。注意攀藤的RX接WidoraAIR的TX,攀藤的TX接WidoraAIR的RX。其实我们只要接收攀藤发送的数据,所以只接攀藤的TX到WidoraAIR的RX也是可以的。攀藤需要5V供电,这个直接接到WidoraAIR的Vin,当然别忘了共地(GND接GND)
二、软件部分:
1.HomeAssistant的配置:
#####################################
sensor:
- platform: mqtt
state_topic: 'stat/kqzl'
name: 'Jia Quan'
unit_of_measurement: 'mg/m3'
value_template: '{{ value_json.jiaquan }}'
- platform: mqtt
state_topic: 'stat/kqzl'
name: 'PM2.5'
unit_of_measurement: 'μg/m3'
value_template: '{{ value_json.pm2p5 }}'
- platform: mqtt
state_topic: 'stat/kqzl'
name: 'PM1.0'
unit_of_measurement: 'μg/m3'
value_template: '{{ value_json.pm1p0 }}'
- platform: mqtt
state_topic: 'stat/kqzl'
name: 'PM10'
unit_of_measurement: 'μg/m3'
value_template: '{{ value_json.pm10 }}'
########################################
新手可能面对这一堆配置不能理解,下面我截取一段讲解一下:
sensor:
- platform: mqtt
state_topic: 'stat/kqzl'
name: 'Jia Quan'
unit_of_measurement: 'mg/m3'
value_template: '{{ value_json.jiaquan }}'
首先yaml格式的配置文件是严格缩进的,所以各位一定要注意各行的缩进。
sensor:
表示你配置的是传感器。不同的设备,HomeAssistant在表现它们的数据的形式上有所不同。比如说sensor,HomeAssistant显示的数值和数据曲线图;而Light则显示一个开关按钮。
- platform: mqtt 表示数据来源平台。这是说明数据是从mqtt协议的消息中来。我们是通过WidoraAIR将数据通过Mqtt发送出去。
state_topic: 'stat/kqzl' 表示这个数据状态订阅的主题(Topic),就是哪个主题的mqtt消息是这个传感器关心的。这个跟后面我们的WidoraAIR的代码是对应的。
name: 'Jia Quan' 表示传感器的名字,如果要显示汉字,请参考论坛的汉化相关帖子。
unit_of_measurement: 'mg/m3' 表示传感器数据的单位。注意相同单位的数据会在“历史”页面显示在同一个曲线表格中,用颜色区分。
value_template: '{{ value_json.jiaquan }}' 表示HomeAssistant怎么从mqtt消息中获取数据。我们发送给HomeAssistant的消息看起来像这样子的:{"jiaquan": 22.30,"pm2p5" : 43.70,"pm1p0" : 43.70,"pm10" : 43.70},这里表示获取消息里面的jiaquan这项数据。
2.WidoraAIR的代码。
开发平台:Arduino core for ESP32 WiFi chip (https://github.com/espressif/arduino-esp32)
使用到的库:pubsubclient(https://github.com/knolleary/pubsubclient)
下载地址:https://github.com/knolleary/pubsubclient/archive/v2.6.zip
下面贴出代码:
/*ESP32做了两件事:
1/ 从攀藤G5读取数据
2/ 通过Mqtt传出数据
*/
#include <WiFi.h>
#include <PubSubClient.h>
/* 改成你自己的wifi信息 */
const char* ssid = "muhome2g";
const char* password = "KuangShan3";
/* 你的MQTT Server地址*/
const char* mqtt_server = "192.168.1.151";
WiFiClient espClient;
PubSubClient client(espClient);
/*LED GPIO pin*/
const char led = 25;
/* topics */
#define TOPICMD "cmnd/light/l1/power"
#define TOPICST "stat/light/l1/power"
#define TOPICKQ "stat/kqzl"//这就是刚刚给大家说的HomeAssistant订阅的Topic
long lastMsg = 0;
char msg[80];
u8_t timecount = 0;;
HardwareSerial Serial1(2);
int dataSum = 0;
//攀藤G5的数据格式
struct _panteng {
unsigned char len[2];
unsigned char pm1_cf1[2];
unsigned char pm2_5_cf1[2];
unsigned char pm10_0_cf1[2];
unsigned char pm1_0[2];
unsigned char pm2_5[2];
unsigned char pm10_0[2];
unsigned char pml0_3[2];
unsigned char pml0_5[2];
unsigned char pml1_0[2];
unsigned char pml2_5[2];
unsigned char pml5[2];
unsigned char pml10[2];
unsigned char jq[2];
unsigned char check[2];
} panteng;
int pm1_0, pm2_5, pm10_0, jq; //PM1.0、PM2.5、PM10
//#define DEBUG
void receivedCallback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message received: ");
Serial.println(topic);
Serial.print("payload: ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload);
}
Serial.println();
if (length > 1)
{
if ((char)payload[1] == 'N') {
Serial.println("Light ON");
digitalWrite(led, HIGH);
client.publish(TOPICST, "ON");
}
else {
digitalWrite(led, LOW);
Serial.println("Light OFF");
client.publish(TOPICST, "OFF");
}
}
}
void mqttconnect() {
/* Loop until reconnected */
while (!client.connected()) {
Serial.print("MQTT connecting ...");
/* client ID */
String clientId = "ESP32Client";
/* connect now */
if (client.connect(clientId.c_str())) {
Serial.println("connected");
/* subscribe topic with default QoS 0*/
client.subscribe(TOPICMD);
}
else {
Serial.print("failed, status code =");
Serial.print(client.state());
Serial.println("try again in 5 seconds");
/* Wait 5 seconds before retrying */
delay(5000);
}
}
}
void setup() {
Serial1.begin(9600);
Serial.begin(115200);
// 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(".");
}
/* set led as output to control led on-off */
pinMode(led, OUTPUT);
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
/* configure the MQTT server with IPaddress and port */
client.setServer(mqtt_server, 1883);
/* this receivedCallback function will be invoked
when client received subscribed topic */
client.setCallback(receivedCallback);
}
void loop() {
/* if client was disconnected then try to reconnect again */
if (!client.connected()) {
mqttconnect();
}
/* this function will listen for incomming
subscribed topic-process-invoke receivedCallback */
client.loop();
//读取攀藤G5 数据
byte c;
char str[100];
static int state = 0;
static int count = 0;
if (Serial1.available()) {
c = Serial1.read();
dataSum += c;
switch (state) {
case 0:
if (0x42 == c)
{
state = 1;
dataSum = 0;
}
break;
case 1:
if (0x4d == c) {
state = 2;
count = 0;
}
break;
case 2:
((unsigned char *)&panteng)[count++] = c;
if (count > 30) {
#ifdef DEBUG
Serial.println(dataSum - panteng.check[0] - panteng.check[1], HEX);
Serial.println(panteng.check[0] * 256 + panteng.check[1], HEX);
#endif
state = 0;
if ((dataSum - panteng.check[0] - panteng.check[1]) == (panteng.check[0] * 256 + panteng.check[1]))
{
#ifdef DEBUG
Serial.println("Data check ok");
//计数 采集5次穿一次 也就是5s
#endif
timecount++;
pm1_0 = panteng.pm1_0[0] * 256 + panteng.pm1_0[1];
pm2_5 = panteng.pm2_5[0] * 256 + panteng.pm2_5[1];
pm10_0 = panteng.pm10_0[0] * 256 + panteng.pm10_0[1];
jq = panteng.jq[0] * 256 + panteng.jq[1];
if (timecount > 60)
{
timecount = 0;
//发送空气信息mqtt
//{
// "jiaquan": 22.30,
// "pm2p5" : 43.70,
// "pm1p0" : 43.70,
// "pm10" : 43.70
//}
//{"jiaquan": 22.30,"pm2p5" : 43.70,"pm1p0" : 43.70,"pm10" : 43.70}
sprintf(msg, "{\"jiaquan\":%d,\"pm2p5\":%d,\"pm1p0\":%d,\"pm10\":%d}",jq,pm2_5,pm1_0,pm10_0);
Serial.println(msg);
client.publish(TOPICKQ, msg);
}
#ifdef DEBUG
Serial.print("jq:");
Serial.println(jq);
Serial.print("pm2.5:");
Serial.println(pm2_5);
#endif
}
}
break;
default:
break;
}
}
}
为了方便大家使用 把代码传附件
esp32MqttTest.zip
(2.1 KB, 下载次数: 63)
最后放出效果图:
效果1
效果2
效果3
|
评分
-
查看全部评分
|