智能家居控制器 #
一、项目概述 #
1.1 项目目标 #
构建一个基于树莓派的智能家居控制器,实现以下功能:
text
┌─────────────────────────────────────────────────────────┐
│ 智能家居控制器架构 │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 云平台 / 手机APP │ │
│ └────────────────────────┬────────────────────────┘ │
│ │ MQTT │
│ ┌────────────────────────┴────────────────────────┐ │
│ │ 智能家居控制器 (树莓派) │ │
│ │ ┌─────────┬─────────┬─────────┬─────────┐ │ │
│ │ │ 温湿度 │ 光照 │ 人体感应 │ 烟雾 │ │ │
│ │ │ 传感器 │ 传感器 │ 传感器 │ 传感器 │ │ │
│ │ └────┬────┴────┬────┴────┬────┴────┬────┘ │ │
│ │ │ │ │ │ │ │
│ │ ┌────┴────┬────┴────┬────┴────┬────┴────┐ │ │
│ │ │ 灯光 │ 空调 │ 窗帘 │ 门锁 │ │ │
│ │ │ 控制 │ 控制 │ 控制 │ 控制 │ │ │
│ │ └─────────┴─────────┴─────────┴─────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
1.2 功能模块 #
| 模块 | 功能 |
|---|---|
| 环境监测 | 温湿度、光照、空气质量监测 |
| 安防监控 | 人体感应、烟雾报警、门窗状态 |
| 设备控制 | 灯光、空调、窗帘、门锁控制 |
| 场景联动 | 自动化场景规则执行 |
| 远程通信 | MQTT云平台连接 |
二、硬件准备 #
2.1 硬件清单 #
| 设备 | 数量 | 用途 |
|---|---|---|
| Raspberry Pi 4B | 1 | 主控制器 |
| DHT22温湿度传感器 | 1 | 环境监测 |
| BH1750光照传感器 | 1 | 光照监测 |
| HC-SR501人体感应 | 2 | 安防监控 |
| MQ-2烟雾传感器 | 1 | 烟雾检测 |
| 4路继电器模块 | 1 | 设备控制 |
| 舵机SG90 | 2 | 窗帘/门锁 |
2.2 接线图 #
text
Raspberry Pi 4B
┌─────────────────────────────────────────┐
│ GPIO17 ── DHT22 数据线 │
│ GPIO18 ── BH1750 SDA (I2C) │
│ GPIO19 ── BH1750 SCL (I2C) │
│ GPIO22 ── HC-SR501 #1 输出 │
│ GPIO23 ── HC-SR501 #2 输出 │
│ GPIO24 ── MQ-2 数字输出 │
│ GPIO25 ── 继电器 IN1 (灯光) │
│ GPIO5 ── 继电器 IN2 (空调) │
│ GPIO6 ── 继电器 IN3 (风扇) │
│ GPIO12 ── 继电器 IN4 (插座) │
│ GPIO13 ── 舵机 #1 PWM (窗帘) │
│ GPIO16 ── 舵机 #2 PWM (门锁) │
└─────────────────────────────────────────┘
三、软件架构 #
3.1 项目结构 #
text
smart-home/
├── src/main/java/com/example/smarthome/
│ ├── Main.java
│ ├── config/
│ │ └── AppConfig.java
│ ├── sensor/
│ │ ├── Sensor.java
│ │ ├── TemperatureSensor.java
│ │ ├── LightSensor.java
│ │ └── MotionSensor.java
│ ├── actuator/
│ │ ├── Actuator.java
│ │ ├── Relay.java
│ │ └── Servo.java
│ ├── controller/
│ │ ├── HomeController.java
│ │ └── SceneController.java
│ ├── network/
│ │ ├── MQTTClient.java
│ │ └── HttpServer.java
│ └── automation/
│ ├── Rule.java
│ └── RuleEngine.java
├── src/main/resources/
│ └── config.properties
└── pom.xml
3.2 核心代码 #
主程序入口
java
package com.example.smarthome;
import com.example.smarthome.config.AppConfig;
import com.example.smarthome.controller.HomeController;
import com.example.smarthome.network.MQTTClient;
import com.pi4j.Pi4J;
public class Main {
public static void main(String[] args) {
System.out.println("智能家居控制器启动...");
var pi4j = Pi4J.newAutoContext();
AppConfig config = AppConfig.load();
HomeController controller = new HomeController(pi4j, config);
MQTTClient mqtt = new MQTTClient(config.getMqttBroker(), "smart-home");
mqtt.connect();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("正在关闭...");
controller.shutdown();
mqtt.disconnect();
pi4j.shutdown();
}));
controller.start();
}
}
传感器管理
java
package com.example.smarthome.sensor;
import java.util.Map;
import java.util.concurrent.*;
public class SensorManager {
private final Map<String, Sensor> sensors = new ConcurrentHashMap<>();
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(2);
public void register(String id, Sensor sensor) {
sensors.put(id, sensor);
}
public void startPolling(int intervalMs) {
scheduler.scheduleAtFixedRate(() -> {
for (Map.Entry<String, Sensor> entry : sensors.entrySet()) {
try {
double value = entry.getValue().read();
System.out.printf("[%s] %s: %.2f%n",
System.currentTimeMillis(),
entry.getKey(), value);
} catch (Exception e) {
e.printStackTrace();
}
}
}, 0, intervalMs, TimeUnit.MILLISECONDS);
}
public double getValue(String sensorId) {
Sensor sensor = sensors.get(sensorId);
return sensor != null ? sensor.getLastValue() : 0;
}
public Map<String, Double> getAllValues() {
Map<String, Double> values = new ConcurrentHashMap<>();
sensors.forEach((id, sensor) -> values.put(id, sensor.getLastValue()));
return values;
}
public void shutdown() {
scheduler.shutdown();
}
}
设备控制器
java
package com.example.smarthome.controller;
import com.example.smarthome.actuator.*;
import com.example.smarthome.sensor.*;
import com.example.smarthome.automation.RuleEngine;
import com.pi4j.context.Context;
import java.util.concurrent.*;
public class HomeController {
private final Context pi4j;
private final SensorManager sensors;
private final ActuatorManager actuators;
private final RuleEngine ruleEngine;
private final ScheduledExecutorService scheduler;
public HomeController(Context pi4j, AppConfig config) {
this.pi4j = pi4j;
this.sensors = new SensorManager();
this.actuators = new ActuatorManager();
this.ruleEngine = new RuleEngine();
this.scheduler = Executors.newScheduledThreadPool(4);
initializeSensors();
initializeActuators();
initializeRules();
}
private void initializeSensors() {
sensors.register("temperature", new TemperatureSensor(pi4j, 17));
sensors.register("humidity", new HumiditySensor(pi4j, 17));
sensors.register("light", new LightSensor(pi4j, 1, 0x23));
sensors.register("motion_living", new MotionSensor(pi4j, 22));
sensors.register("motion_bedroom", new MotionSensor(pi4j, 23));
sensors.register("smoke", new SmokeSensor(pi4j, 24));
}
private void initializeActuators() {
actuators.register("light_living", new Relay(pi4j, 25, true));
actuators.register("light_bedroom", new Relay(pi4j, 5, true));
actuators.register("ac", new Relay(pi4j, 6, true));
actuators.register("fan", new Relay(pi4j, 12, true));
actuators.register("curtain", new ServoMotor(pi4j, 13));
actuators.register("lock", new ServoMotor(pi4j, 16));
}
private void initializeRules() {
ruleEngine.addRule("auto_light", (sensors, actuators) -> {
double light = sensors.getValue("light");
boolean motion = sensors.getValue("motion_living") > 0;
if (light < 100 && motion) {
actuators.on("light_living");
} else if (!motion) {
actuators.off("light_living");
}
});
ruleEngine.addRule("smoke_alarm", (sensors, actuators) -> {
double smoke = sensors.getValue("smoke");
if (smoke > 500) {
actuators.on("fan");
System.out.println("烟雾报警!启动排风扇");
}
});
}
public void start() {
sensors.startPolling(5000);
scheduler.scheduleAtFixedRate(() -> {
ruleEngine.evaluate(sensors, actuators);
}, 0, 1, TimeUnit.SECONDS);
}
public void shutdown() {
sensors.shutdown();
scheduler.shutdown();
}
}
四、自动化规则 #
4.1 规则引擎 #
java
package com.example.smarthome.automation;
import com.example.smarthome.sensor.SensorManager;
import com.example.smarthome.actuator.ActuatorManager;
import java.util.*;
import java.util.function.BiConsumer;
public class RuleEngine {
private final Map<String, BiConsumer<SensorManager, ActuatorManager>> rules =
new LinkedHashMap<>();
public void addRule(String name, BiConsumer<SensorManager, ActuatorManager> rule) {
rules.put(name, rule);
}
public void removeRule(String name) {
rules.remove(name);
}
public void evaluate(SensorManager sensors, ActuatorManager actuators) {
for (Map.Entry<String, BiConsumer<SensorManager, ActuatorManager>> entry :
rules.entrySet()) {
try {
entry.getValue().accept(sensors, actuators);
} catch (Exception e) {
System.err.println("规则执行错误: " + entry.getKey());
e.printStackTrace();
}
}
}
public List<String> getRuleNames() {
return new ArrayList<>(rules.keySet());
}
}
五、远程控制 #
5.1 MQTT集成 #
java
package com.example.smarthome.network;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import com.example.smarthome.controller.HomeController;
public class MQTTClient implements MqttCallback {
private MqttAsyncClient client;
private final String broker;
private final String clientId;
private HomeController controller;
public MQTTClient(String broker, String clientId) {
this.broker = broker;
this.clientId = clientId;
}
public void connect() throws MqttException {
client = new MqttAsyncClient(broker, clientId,
new MemoryPersistence());
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(true);
options.setAutomaticReconnect(true);
client.setCallback(this);
client.connect(options).waitForCompletion();
client.subscribe("home/+/command", 1);
client.subscribe("home/scene/activate", 1);
}
public void publish(String topic, String payload) throws MqttException {
client.publish(topic, payload.getBytes(), 1, false);
}
@Override
public void connectionLost(Throwable cause) {
System.out.println("MQTT连接丢失: " + cause.getMessage());
}
@Override
public void messageArrived(String topic, MqttMessage message) {
String payload = new String(message.getPayload());
System.out.println("收到消息: " + topic + " -> " + payload);
if (topic.endsWith("/command")) {
handleCommand(topic, payload);
} else if (topic.equals("home/scene/activate")) {
handleScene(payload);
}
}
private void handleCommand(String topic, String payload) {
String[] parts = topic.split("/");
if (parts.length >= 3) {
String device = parts[1];
String action = payload.toLowerCase();
if ("on".equals(action)) {
controller.turnOn(device);
} else if ("off".equals(action)) {
controller.turnOff(device);
}
}
}
private void handleScene(String sceneName) {
controller.activateScene(sceneName);
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
}
public void disconnect() throws MqttException {
if (client != null && client.isConnected()) {
client.disconnect();
}
}
}
六、总结 #
智能家居控制器项目要点:
- 模块化设计:传感器、执行器、控制器分离
- 事件驱动:使用事件机制处理传感器数据
- 规则引擎:灵活的自动化规则配置
- 远程通信:MQTT协议实现远程控制
- 资源管理:正确管理硬件资源生命周期
下一章我们将学习环境监测站项目。
最后更新:2026-03-27