[Follow me Season 2 Episode 2] Smart Home - Smart Study
[Copy link]
This post was last edited by 鲜de芒果 on 2024-10-2 17:28
1. Task Requirements
- Upload temperature and humidity to HA through external LTR-329 ambient light sensor, and display data through HA panel
- Upload temperature and humidity to HA through external AHT20 temperature and humidity sensor, and display data through HA panel
- Use the onboard LED to simulate a desk lamp, and control its switch and brightness adjustment through the HA panel
- Automatic light adjustment in the study is an important part of a smart study. It can automatically adjust the brightness or switch status of the desk lamp according to changes in ambient light to ensure that the light is sufficient and comfortable when reading or working.
2. Hardware Preparation
3. HomeAssistant integration
**MQTT** device discovery will enable people to use **MQTT** devices with minimal configuration work on the [HomeAssistant](https://www.home-assistant.io) side. Configuration is done on the device itself and the topics used by the device.
> MQTT discovery is enabled by default, but can be disabled. The prefix of the discovery topic (default: `homeassistant`) can be changed. See the [MQTT options section]( https://www.home-assistant.io/integrations/mqtt#configure-mqtt-options) for configuration details
3.1 Configure the theme
After sending the configuration topic to MQTT , HomeAssistant will automatically discover the current sensor. In the current task, an onboard LED light is used as the Light component in HomeAssistant . This component can remotely control the onboard LED on and off in the HomeAssistant dashboard . Use the MQTT client to send a message to the configuration topic. This project uses three sensors + a desk lamp. The specific configuration topics are as follows:
// 台灯 消息
{
"name":"table-lamp",
"device_class": "light",
"command_topic":"homeassistant/light/FollowMe2-2-table-lamp/switch",
"state_topic":"homeassistant/sensor/FollowMe2-2/state",
"brightness_command_topic": "homeassistant/light/FollowMe2-2-table-lamp/brightness/set",
"brightness_state_topic": "homeassistant/sensor/FollowMe2-2/state",
"state_value_template": "{{ value_json.builtinLed }}",
"brightness_value_template": "{{ value_json.brightness }}",
"unique_id":"FollowMe2-2-table-lamp",
"device":{
"identifiers":[
"Arduino UNO R4 WiFi"
],
"name":"UNO R4 WiFi",
"manufacturer": "Arduino",
"model": "UNO R4 WiFi",
"hw_version": "1.0"
}
}
// 书房 温度传感器 消息
{
"device_class":"temperature",
"state_topic":"homeassistant/sensor/FollowMe2-2/state",
"unit_of_measurement":"°C",
"value_template":"{{ value_json.temperature}}",
"unique_id":"FollowMe2-2-study-temperature",
"device":{
"identifiers":[
"Arduino UNO R4 WiFi"
],
"name":"UNO R4 WiFi",
"manufacturer": "Arduino",
"model": "UNO R4 WiFi",
"hw_version": "1.0"
}
}
// 书房 湿度传感器 消息
{
"device_class":"humidity",
"state_topic":"homeassistant/sensor/FollowMe2-2/state",
"unit_of_measurement":"%",
"value_template":"{{ value_json.humidity}}",
"unique_id":"FollowMe2-2-study-humidity",
"device":{
"identifiers":[
"Arduino UNO R4 WiFi"
],
"name":"UNO R4 WiFi",
"manufacturer": "Arduino",
"model": "UNO R4 WiFi",
"hw_version": "1.0"
}
}
// 书房 环境光传感器 消息
{
"device_class":"illuminance",
"state_topic":"homeassistant/sensor/FollowMe2-2/state",
"unit_of_measurement":"lx",
"value_template":"{{ value_json.ambientLight}}",
"unique_id":"FollowMe2-2-study-illuminance",
"device":{
"identifiers":[
"Arduino UNO R4 WiFi"
],
"name":"UNO R4 WiFi",
"manufacturer": "Arduino",
"model": "UNO R4 WiFi",
"hw_version": "1.0"
}
}
4. Code Implementation
/**
* FollowMe 2-2 任务4:
* 1. 通过Wi-Fi,利用MQTT协议接入到开源的智能家居平台HA(HomeAssistant)
*/
#include <Wire.h>
#include <WiFiS3.h>
#include <ArduinoMqttClient.h>
#include <ArduinoJson.h>
#include <Adafruit_AHTX0.h>
#include <Adafruit_LTR329_LTR303.h>
#include "arduino_secrets.h"
#define LOOP_DELAY 10 // loop函数延时(单位:毫秒)
#define SENSOR_REPORT_INTERVAL 5 // 传感器数据更新间隔(单位:秒)
#define STATE_ON "ON" // HA LED开状态
#define STATE_OFF "OFF" // HA LED关状态
char ssid[] = SECRET_SSID; // WIFI SSID
char pass[] = SECRET_PASS; // WIFI PASSWD
int status = WL_IDLE_STATUS; // WIFI 状态
// MQTT
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
const char broker[] = "192.168.2.120"; // HomeAssistant MQTT服务器地址
int port = 1883; // HomeAssistant MQTT服务器端口
char mqtt_user[] = MQTT_USER; // MQTT 用户名
char mqtt_pass[] = MQTT_PASS; // MQTT 密码
// 订阅主题(接收 HomeAssistant 控制板载LED开关指令)
const char switch_subscribe_topic[] = "homeassistant/light/FollowMe2-2-table-lamp/switch";
// 订阅主题(接收 HomeAssistant 控制板载LED亮度调节指令)
const char brightness_subscribe_topic[] = "homeassistant/light/FollowMe2-2-table-lamp/brightness/set";
bool isNeedReportState = true; // 是否需要更新状态到HA
bool ledState = false; // 板载LED状态
// 发布主题(上报板载LED状态至 HomeAssistant的状态主题)
const char publish_topic[] = "homeassistant/sensor/FollowMe2-2/state";
uint32_t tick = 0; // loop循环次数
uint8_t brightness = 0; // 灯亮度调节
Adafruit_AHTX0 aht; // AHT20 传感器
float temperature = 0; // AHT20 采集到的温度值
float humidity = 0; // AHT20 采集到的湿度值
Adafruit_LTR329 ltr = Adafruit_LTR329(); // LTR329传感器
float ambientLight = 0; // 环境光强度
ltr329_gain_t gain = LTR3XX_GAIN_1; // ALS增益
ltr329_integrationtime_t integrationTime = LTR3XX_INTEGTIME_100; // 积分时间
float integrationTimeVal = 0.1;
uint16_t visible_plus_ir; // 可见光
uint16_t infrared; // 红外
/**
* 设置板载LED状态
*/
void setLightState() {
if (ledState) {
if(0 == brightness) {
brightness = 255;
}
analogWrite(LED_BUILTIN, brightness);
} else {
analogWrite(LED_BUILTIN, 0);
}
}
void setup() {
// 初始化串口
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT); // 初始化板载LED引脚为输出
// 初始化 QWIIC 接口的 I2C 总线
Wire1.begin();
// 检查WIFI模块
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("WiFi模块通信失败!");
while (true);
}
// 连接到WIFI
Serial.print("尝试连接到 WIFI SSID: ");
Serial.println(ssid);
while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
Serial.print(".");
delay(5 * 1000);
}
Serial.println("WIFI 连接成功!");
// 连接MQTT
mqttClient.setUsernamePassword(mqtt_user, mqtt_pass);
Serial.print("尝试连接到MQTT服务器: ");
Serial.println(broker);
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT 连接失败! ");
Serial.println(mqttClient.connectError());
while (1);
}
Serial.println("MQTT连接成功!");
// 订阅主题
mqttClient.onMessage(onMqttMessage);
mqttClient.subscribe(switch_subscribe_topic);
mqttClient.subscribe(brightness_subscribe_topic);
// AHT20 初始化
if (!aht.begin(&Wire1)) {
Serial.println("未找到 AHTX0 传感器!");
while (1) delay(10);
}
Serial.println("AHTX0 传感器初始化成功!");
if (!ltr.begin(&Wire1)) {
Serial.println("未找到 LTR329 传感器!");
while (1) delay(10);
}
Serial.println("LTR329 传感器初始化成功!");
}
void loop() {
if(isNeedReportState) {
// 汇报当前板载LED状态到HA
char msg[100] = {0};
sprintf(msg, "{\"builtinLed\": \"%s\", \"brightness\": %d,\"temperature\":%.2f,\"humidity\":%.2f, \"ambientLight\":%.2f}",
ledState ? STATE_ON : STATE_OFF, brightness, temperature, humidity, ambientLight);
mqttClient.beginMessage(publish_topic);
mqttClient.print(msg);
mqttClient.endMessage();
isNeedReportState = false; // 上报板载LED状态到HA后重置汇报状态
}
if(0 == (tick % (SENSOR_REPORT_INTERVAL * 1000 / LOOP_DELAY))) { // 根据传感器数据更新间隔 SENSOR_REPORT_INTERVAL 宏定义进行上报传感器数据
// 读取 AHT20 传感器数据
sensors_event_t humi, temp;
aht.getEvent(&humi, &temp);
temperature = temp.temperature;
humidity = humi.relative_humidity;
// 读取 LTR329 传感器数据
if (ltr.newDataAvailable()) {
ltr.readBothChannels(visible_plus_ir, infrared);
// 环境光照度计算
float ratio = infrared / (visible_plus_ir + infrared);
if(ratio < 0.45) {
ambientLight = (1.7743 * visible_plus_ir + 1.1059 * infrared) / (1 << gain) / integrationTimeVal;
} else if(ratio < 0.64 && ratio >= 0.45) {
ambientLight = (4.2785 * visible_plus_ir - 1.9548 * infrared) / (1 << gain) / integrationTimeVal;
} else if(ratio < 0.85 && ratio >= 0.64) {
ambientLight = (0.5926 * visible_plus_ir + 0.1185 * infrared) / (1 << gain) / integrationTimeVal;
} else {
ambientLight = 0;
}
}
// 更新状态,更新传感器数据到HA
isNeedReportState = true;
}
// 更新板载LED状态
setLightState();
mqttClient.poll(); // 定期检查新MQTT消息
delay(LOOP_DELAY); // 主循环延时时长
tick ++;
}
// MQTT 订阅消息回调,接收HA控制板载LED的指令(ON:开,OFF:关)
void onMqttMessage(int messageSize) {
char topic[100] = {0};
String message;
// 打印消息主题
Serial.print("Received message from topic: ");
strcpy(topic, mqttClient.messageTopic().c_str());
Serial.println(topic);
// 读取消息内容
for (int i = 0; i < messageSize; i++) {
message += (char)mqttClient.read();
}
// 打印消息的内容
Serial.print("Received message: ");
Serial.println(message);
if(0 == strcmp(switch_subscribe_topic, topic)) {
// 开关
if(0 == strcmp(STATE_ON, message.c_str())) {
if(false == ledState) {
// 需要更新板载LED状态到HA
isNeedReportState = true;
}
ledState = true;
} else {
if(true == ledState) {
// 需要更新板载LED状态到HA
isNeedReportState = true;
}
ledState = false;
}
} else if(0 == strcmp(brightness_subscribe_topic, topic)) {
// 亮度
uint8_t b = message.toInt();
if (brightness < 0 || brightness > 255) { // 范围校验
// do nothing...
return;
} else {
brightness = b;
setLightState();
isNeedReportState = true;
}
}
}
5. Smart Home Automation
In this project, the Adafruit LTR-329 Light Sensor ambient light sensor module is used as a study room ambient light monitoring module. When the light is lower than the threshold, the desk lamp is automatically turned on (in this example, there is no real smart desk lamp connected, and the onboard LED is used for simulation, which can control the switch and brightness). When the light is sufficient, the desk lamp is automatically turned off. Automatically adjust the light in the study room without manual intervention. In terms of energy saving, avoid unnecessary lighting and save electricity. At the same time, keep the light in the study room at the optimal level to protect the eyes and improve reading and work efficiency.
6. Effect display
7. Demonstration Video
8. Conclusion
Arduino Uno R4 WiFi Smart Study Room is a smart home project based on Arduino Uno R4 development board and ESP8266 Wi-Fi module. The main function of this project is to achieve remote control and management of the study room environment and various devices through Wi-Fi connection.
Through this project, we not only improved our understanding and application of IoT technology, but also learned how to transform theory into practical applications to solve practical problems. I hope these experiences and insights can provide reference and inspiration for future projects.
9. References
10. Portal
11. Project source code
源码.zip
(7.76 KB, downloads: 2)
|