智能家居控制系统

0

基于ESP32的智能家居控制系统,支持远程控制家电、温湿度监测和手机APP联动。

项目简介

智能家居控制系统是一个完整的物联网解决方案,通过ESP32作为核心控制节点,实现对家中电器的智能化控制。

系统架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
                        ┌─────────────┐
│ Cloud Server│
│ (MQTT) │
└──────┬──────┘

┌──────────────────────┼──────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ ESP32节点1 │ │ ESP32节点2 │ │ ESP32节点3 │
│ (客厅) │ │ (卧室) │ │ (厨房) │
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ 继电器/传感器 │ │ 继电器/传感器 │ │ 继电器/传感器 │
└───────────────┘ └───────────────┘ └───────────────┘

硬件清单

设备 数量 说明
ESP32 DevKit 3 主控芯片
继电器模块 6 5V单路继电器
DHT22 3 温湿度传感器
HC-SR501 2 人体红外感应
BH1750 3 光照传感器
电源模块 3 5V 2A

功能特性

  • 远程开关控制
  • 温湿度监测
  • 定时任务
  • 手机APP联动
  • 场景模式
  • 能耗统计

核心代码

1. ESP32主程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>

#define DHTPIN 4
#define DHTTYPE DHT22

const char* ssid = "YourWiFi";
const char* password = "YourPassword";
const char* mqtt_server = "broker.emqx.io";

DHT dht(DHTPIN, DHTTYPE);
WiFiClient espClient;
PubSubClient client(espClient);

// 继电器引脚
const int relayPins[] = {5, 18, 19, 21, 22, 23};
bool relayState[] = {false, false, false, false, false, false};

void setup_wifi() {
delay(10);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}

void callback(char* topic, byte* payload, unsigned int length) {
char message[length + 1];
for (int i = 0; i < length; i++) {
message[i] = payload[i];
}
message[length] = '\0';

// 解析JSON命令
if (strcmp(topic, "home/relay/set") == 0) {
int pin = message[0] - '0';
bool state = message[2] == '1';
digitalWrite(relayPins[pin], state ? HIGH : LOW);
relayState[pin] = state;
}
}

void reconnect() {
while (!client.connected()) {
if (client.connect("ESP32Client")) {
client.subscribe("home/relay/set");
client.subscribe("home/sensor/get");
} else {
delay(5000);
}
}
}

void publishSensors() {
float h = dht.readHumidity();
float t = dht.readTemperature();

char payload[50];
sprintf(payload, "{\"temp\":%.1f,\"humid\":%.1f}", t, h);
client.publish("home/sensor/data", payload);
}

void setup() {
Serial.begin(115200);
dht.begin();

for (int i = 0; i < 6; i++) {
pinMode(relayPins[i], OUTPUT);
}

setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}

void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();

static unsigned long lastMsg = 0;
if (millis() - lastMsg > 5000) {
lastMsg = millis();
publishSensors();
}
}

2. Node.js后端服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// server/index.js
const mqtt = require('mqtt');
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');

const app = express();
app.use(cors());
app.use(express.json());

const client = mqtt.connect('mqtt://broker.emqx.io:1883');

// 设备状态管理
const deviceStates = new Map();

// MQTT消息处理
client.on('connect', () => {
console.log('MQTT Connected');
client.subscribe('home/#');
});

client.on('message', (topic, message) => {
if (topic === 'home/sensor/data') {
const data = JSON.parse(message.toString());
// 存储到数据库
saveSensorData(data);
}
});

// REST API
app.get('/api/devices', (req, res) => {
res.json(Array.from(deviceStates.entries()));
});

app.post('/api/control', (req, res) => {
const { device, state } = req.body;
client.publish('home/relay/set', `${device}:${state ? 1 : 0}`);
res.json({ success: true });
});

app.get('/api/history', async (req, res) => {
// 返回历史数据
const data = await getSensorHistory();
res.json(data);
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

3. React Native APP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// App.js
import React, { useState, useEffect } from 'react';
import { View, Text, Switch, FlatList, TouchableOpacity, StyleSheet } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';

const API_URL = 'http://your-server:3000/api';

export default function App() {
const [devices, setDevices] = useState([]);
const [sensors, setSensors] = useState({ temp: 0, humid: 0 });

useEffect(() => {
fetchDevices();
// 定时刷新传感器数据
const interval = setInterval(fetchSensors, 5000);
return () => clearInterval(interval);
}, []);

const fetchDevices = async () => {
const res = await fetch(`${API_URL}/devices`);
const data = await res.json();
setDevices(data);
};

const fetchSensors = async () => {
const res = await fetch(`${API_URL}/sensors`);
const data = await res.json();
setSensors(data);
};

const toggleDevice = async (deviceId, currentState) => {
await fetch(`${API_URL}/control`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ device: deviceId, state: !currentState })
});
fetchDevices();
};

const renderDevice = ({ item }) => (
<View style={styles.deviceItem}>
<Text style={styles.deviceName}>设备 {item[0]}</Text>
<Switch
value={item[1]}
onValueChange={() => toggleDevice(item[0], item[1])}
/>
</View>
);

return (
<SafeAreaView style={styles.container}>
<View style={styles.header}>
<Text style={styles.title}>智能家居</Text>
<View style={styles.sensorCard}>
<Text>温度: {sensors.temp}°C</Text>
<Text>湿度: {sensors.humid}%</Text>
</View>
</View>
<FlatList
data={devices}
renderItem={renderDevice}
keyExtractor={item => item[0]}
/>
</SafeAreaView>
);
}

const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#f5f5f5' },
header: { padding: 20 },
title: { fontSize: 24, fontWeight: 'bold' },
sensorCard: { flexDirection: 'row', justifyContent: 'space-around', marginTop: 10, padding: 15, backgroundColor: '#fff', borderRadius: 10 },
deviceItem: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', padding: 20, backgroundColor: '#fff', marginTop: 10, marginHorizontal: 20, borderRadius: 10 }
});

4. 数据库模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// models/SensorData.js
const mongoose = require('mongoose');

const sensorSchema = new mongoose.Schema({
timestamp: { type: Date, default: Date.now },
temperature: Number,
humidity: Number,
light: Number,
device_id: String
});

sensorSchema.index({ timestamp: -1 });

module.exports = mongoose.model('SensorData', sensorSchema);

// 使用示例
async function saveSensorData(data) {
const sensorData = new SensorData({
temperature: data.temp,
humidity: data.humid,
device_id: data.device_id || 'main'
});
await sensorData.save();
}

项目成果

  • 已部署3个ESP32节点
  • 响应延迟 < 500ms
  • 稳定运行3个月
  • 支持6路设备控制

总结

智能家居控制系统展示了物联网技术的完整应用,从硬件到云端再到移动端,构建了一套完整的智能化解决方案。