第19章 完整项目实战
19.1 项目需求
构建一个智能农业监控系统:
- 100个传感器节点
- 实时数据采集
- 远程控制
- 数据存储与分析
- Web监控界面
19.2 系统架构
云端
边缘网关
农场节点
桥接
传感器1-50
传感器51-100
控制器
Mosquitto Edge
Mosquitto Cloud
数据库
API服务
Web界面
19.3 边缘部署
Mosquitto配置
bash
# edge.conf
per_listener_settings true
# 本地监听
listener 1883
allow_anonymous false
password_file /etc/mosquitto/passwd
acl_file /etc/mosquitto/acl
# 云桥接
connection cloud-bridge
address cloud.example.com:8883
bridge_cafile /etc/mosquitto/ca.crt
remote_username edge_bridge
remote_password secure_pass
# 桥接主题
topic farm/# out 1
topic cmd/# in 1
19.4 云端部署
Docker Compose
yaml
version: '3.8'
services:
mosquitto:
image: eclipse-mosquitto:2
ports:
- "1883:1883"
- "9001:9001"
volumes:
- ./config:/mosquitto/config
- ./data:/mosquitto/data
influxdb:
image: influxdb:2.7
ports:
- "8086:8086"
volumes:
- influxdb_data:/var/lib/influxdb2
grafana:
image: grafana/grafana
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
api:
build: ./api
ports:
- "8000:8000"
depends_on:
- mosquitto
- influxdb
volumes:
influxdb_data:
grafana_data:
19.5 数据采集脚本
python
import paho.mqtt.client as mqtt
import json
import random
import time
class Sensor:
def __init__(self, sensor_id, location):
self.sensor_id = sensor_id
self.location = location
self.client = mqtt.Client(client_id=f"sensor_{sensor_id}")
self.client.username_pw_set("sensor", "password")
self.client.connect("edge.local", 1883, 60)
def read_data(self):
return {
'sensor_id': self.sensor_id,
'location': self.location,
'temperature': round(random.uniform(15, 35), 2),
'humidity': round(random.uniform(40, 80), 2),
'soil_moisture': round(random.uniform(20, 90), 2),
'light': round(random.uniform(0, 1000), 2),
'timestamp': time.time()
}
def publish(self):
data = self.read_data()
topic = f"farm/{self.location}/sensor/{self.sensor_id}"
self.client.publish(topic, json.dumps(data), qos=1)
print(f"Published: {topic}")
# 模拟传感器
sensors = [
Sensor(i, "greenhouse") for i in range(1, 51)
] + [
Sensor(i, "field") for i in range(51, 101)
]
while True:
for sensor in sensors:
sensor.publish()
time.sleep(60)
19.6 Web监控界面
实时数据展示
html
<!DOCTYPE html>
<html>
<head>
<title>农业监控系统</title>
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<h1>智能农业监控</h1>
<canvas id="tempChart"></canvas>
<div id="sensors"></div>
<script>
const client = mqtt.connect('ws://cloud.example.com:9001');
const tempData = { labels: [], datasets: [{ label: '温度', data: [] }] };
const chart = new Chart(document.getElementById('tempChart'), {
type: 'line',
data: tempData,
options: { scales: { y: { beginAtZero: false } } }
});
client.on('connect', () => {
client.subscribe('farm/#');
});
client.on('message', (topic, message) => {
const data = JSON.parse(message.toString());
if (data.temperature) {
tempData.labels.push(new Date().toLocaleTimeString());
tempData.datasets[0].data.push(data.temperature);
if (tempData.labels.length > 20) {
tempData.labels.shift();
tempData.datasets[0].data.shift();
}
chart.update();
}
});
</script>
</body>
</html>
19.7 性能测试
bash
# 使用mqtt-benchmark测试
mqtt-benchmark -c 100 -s 200 -t farm/+/sensor/+
# 结果分析
# - 连接数: 100
# - 消息大小: 200字节
# - 吞吐量: 约1000 msg/s
19.8 项目总结
通过完整项目实践,掌握了MQTT系统的端到端开发。