随着物联网(IoT)技术的迅速发展,越来越多的设备和应用需要连接到互联网,实现数据的实时采集、传输和分析。本项目旨在搭建一个物联网云平台,能够支持多种传感器数据的采集与处理,为用户提供实时监控、数据分析及决策支持。平台将涵盖设备管理、数据存储与处理、可视化界面等功能,为智能家居、工业监控和环境监测等应用场景提供支持。
本系统架构分为四个主要层次:边缘层、传输层、云层和应用层。
单片机:选择ESP32作为设备的核心控制器,具备Wi-Fi和蓝牙功能,适合IoT应用。
传感器技术:使用温湿度传感器(如DHT11)、光照传感器等,采集环境数据。
云计算平台:选择AWS作为云服务提供商,利用其丰富的服务支持。
大数据处理:使用Apache Spark进行数据处理与分析。
数据库:选择MongoDB存储传感器数据,使用InfluxDB进行时间序列数据的存储。
API设计:使用RESTful API进行前后端数据交互,GraphQL用于复杂数据查询。
前端开发:使用React框架开发用户界面,方便用户查看实时数据。
后端开发:使用Node.js构建后端服务,提供数据处理和API接口。
实施SSL/TLS加密,确保数据在传输过程中的安全性。
使用OAuth 2.0进行身份验证和授权管理。
根据系统架构的技术栈,以下是环境搭建的步骤:
下载并安装Arduino IDE,配置ESP32开发环境。
使用以下命令在Arduino IDE中安装ESP32库:
File -> Preferences -> Additional Board Manager URLs: https://dl.espressif.com/dl/package\_esp32\_index.json
Tools -> Board -> Board Manager -> 搜索ESP32并安装
注册AWS账号,创建EC2实例,选择Ubuntu Server作为操作系统。
安装Node.js和npm:
sudo apt updatesudo apt install nodejs npm
安装MongoDB:
sudo apt install -y mongodb
安装InfluxDB:
sudo apt install influxdb
使用Create React App快速搭建前端开发环境:
npx create-react-app my-iot-appcd my-iot-appnpm start
本部分将详细实现物联网云平台的各个组件,包括ESP32设备的代码、Node.js后端服务、MongoDB数据库、InfluxDB时间序列存储、以及React前端界面。每个部分都将附上详细的代码示例和说明。
ESP32作为边缘设备,负责采集温度数据并通过MQTT协议发送到云端。以下是ESP32的代码示例:
#include
#include
// WiFi和MQTT Broker的配置
const char* ssid = "YOUR_SSID"; // WiFi名称
const char* password = "YOUR_PASSWORD"; // WiFi密码
const char* mqttServer = "YOUR_MQTT_BROKER"; // MQTT Broker地址
const int mqttPort = 1883; // MQTT Broker端口
WiFiClient espClient; // WiFi客户端
PubSubClient client(espClient); // MQTT客户端
// 温度传感器引脚
const int sensorPin = 34; // 假设温度传感器连接在GPIO 34引脚
void setup() {
Serial.begin(115200); // 初始化串口
connectWiFi(); // 连接到WiFi
client.setServer(mqttServer, mqttPort); // 设置MQTT服务器
}
// 主循环
void loop() {
if (!client.connected()) { // 检查MQTT连接
reconnect();
}
client.loop(); // 处理MQTT消息
// 模拟温度数据采集
int rawValue = analogRead(sensorPin); // 读取传感器的原始值
float voltage = (rawValue / 4095.0) * 3.3; // 将原始值转换为电压
float temperature = (voltage - 0.5) * 100; // 将电压转换为温度(假设传感器为LM35)
String payload = String(temperature); // 将温度数据转换为字符串
client.publish("home/temperature", payload.c_str()); // 发送数据到MQTT主题
delay(5000); // 每5秒发送一次数据
}
// 连接WiFi
void connectWiFi() {
WiFi.begin(ssid, password); // 开始连接WiFi
while (WiFi.status() != WL_CONNECTED) { // 等待连接成功
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi"); // 连接成功
}
// 重新连接MQTT
void reconnect() {
while (!client.connected()) { // 循环直到重新连接
Serial.print("Attempting MQTT connection...");
if (client.connect("ESP32Client")) { // 尝试连接
Serial.println("connected"); // 连接成功
} else {
Serial.print("failed, rc="); // 连接失败
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000); // 5秒后重试
}
}
}
代码说明:
WiFi配置:将WiFi网络名称、密码和MQTT Broker地址进行配置。
数据采集:从连接的温度传感器读取原始模拟值,并将其转换为温度。
MQTT发布:通过MQTT协议将采集到的温度数据发布到主题home/temperature
。
连接管理:实现WiFi和MQTT的连接管理,确保设备始终保持在线。
后端服务的主要功能是接收来自MQTT Broker的消息,并将温度数据存储到MongoDB和InfluxDB中,同时提供RESTful API供前端访问。
const express = require('express'); // 引入Express框架
const mongoose = require('mongoose'); // 引入Mongoose库
const mqtt = require('mqtt'); // 引入MQTT库
const Influx = require('influx'); // 引入InfluxDB库
const app = express(); // 创建Express应用
const PORT = process.env.PORT || 3000; // 设定端口
// MongoDB连接
mongoose.connect('mongodb://localhost:27017/iotdata', {
useNewUrlParser: true,
useUnifiedTopology: true
});
// 定义温度数据模型
const TemperatureSchema = new mongoose.Schema({
value: Number,
timestamp: { type: Date, default: Date.now } // 默认时间戳
});
const Temperature = mongoose.model('Temperature', TemperatureSchema); // 创建模型
// InfluxDB连接
const influx = new Influx.InfluxDB({
host: 'localhost',
database: 'iot_data',
schema: [
{
measurement: 'temperature',
fields: {
value: Influx.FieldType.FLOAT
},
tags: [
'sensor' // 可以添加更多标签以区分传感器
]
}
]
});
// MQTT连接
const mqttClient = mqtt.connect('mqtt://YOUR_MQTT_BROKER');
mqttClient.on('connect', () => {
mqttClient.subscribe('home/temperature', (err) => {
if (!err) {
console.log('Subscribed to home/temperature');
}
});
});
// 处理MQTT消息
mqttClient.on('message', (topic, message) => {
const temperatureValue = parseFloat(message.toString()); // 解析温度值
const newTemperature = new Temperature({ value: temperatureValue }); // 创建新的温度记录
newTemperature.save().then(() => console.log('Temperature saved to MongoDB')); // 保存到MongoDB
// 保存到InfluxDB
influx.writePoints([
{
measurement: 'temperature',
tags: { sensor: 'ESP32' }, // 添加传感器标签
fields: { value: temperatureValue },
}
]).catch(err => {
console.error(`Error saving data to InfluxDB! ${err.stack}`)
});
});
// API接口:获取最新的10条温度数据
app.get('/temperature', async (req, res) => {
try {
const temperatures = await Temperature.find().sort({ timestamp: -1 }).limit(10); // 从MongoDB获取数据
res.json(temperatures); // 返回温度数据
} catch (error) {
res.status(500).send(error); // 处理错误
}
});
// API接口:获取InfluxDB中的温度数据
app.get('/influx/temperature', async (req, res) => {
try {
const result = await influx.query(`SELECT * FROM temperature ORDER BY time DESC LIMIT 10`); // 从InfluxDB获取数据
res.json(result); // 返回温度数据
} catch (err) {
res.status(500).send(err); // 处理错误
}
});
// 启动Express服务器
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
代码说明:
MongoDB连接:使用Mongoose连接到MongoDB数据库,并定义温度记录的Schema。
InfluxDB连接:使用InfluxDB库连接到InfluxDB数据库,并定义数据的schema。
MQTT连接:连接到MQTT Broker并订阅home/temperature
主题,处理接收到的消息。
消息处理:将接收到的温度数据保存到MongoDB和InfluxDB中。
RESTful API:
/temperature
接口:从MongoDB中获取最近的10条温度记录并返回。
/influx/temperature
接口:从InfluxDB中获取最近的10条温度记录并返回。
启动服务器:启动Express服务器,监听指定端口。
MongoDB用于存储温度数据,InfluxDB用于时间序列数据的高效存储和查询。确保您在本地或云端安装并运行这两个数据库。
# 安装MongoDB (Ubuntu示例)
sudo apt updatesudo apt install -y mongodbsudo
systemctl start mongodbsudo
systemctl enable mongodb
# 安装InfluxDB (Ubuntu示例)
sudo apt updatesudo apt install influxdbsudo
systemctl start influxdbsudo
systemctl enable influxdb
在InfluxDB中,我们需要创建一个用于存储温度数据的数据库。以下是创建数据库的步骤:
进入InfluxDB命令行:
influx
创建数据库:
在InfluxDB命令行界面中,输入以下命令以创建数据库:
CREATE DATABASE iot_data
查看已创建的数据库:
运行以下命令查看当前数据库列表,确保iot_data
数据库已成功创建:
SHOW DATABASES
创建时间序列数据的测量:
在我们的Node.js应用中,已经在InfluxDB连接时定义了测量(measurement)为temperature
。不需要手动创建,数据会在插入时自动生成。
前端将展示从后端获取的温度数据。我们将使用React构建用户界面,允许用户查看最新的温度数据。
首先,确保你已经使用create-react-app
创建了一个新的React应用:
npx create-react-app my-iot-app
cd my-iot-app
npm start
然后,修改src/App.js
文件如下:
import React, { useEffect, useState } from 'react';
const App = () => {
const [temperatures, setTemperatures] = useState([]); // 存储温度数据
const [influxData, setInfluxData] = useState([]); // 存储InfluxDB数据
// 获取MongoDB温度数据
const fetchTemperatures = async () => {
const response = await fetch('http://localhost:3000/temperature');
const data = await response.json();
setTemperatures(data); // 更新状态
};
// 获取InfluxDB温度数据
const fetchInfluxData = async () => {
const response = await fetch('http://localhost:3000/influx/temperature');
const data = await response.json();
setInfluxData(data); // 更新状态
};
useEffect(() => {
fetchTemperatures(); // 组件挂载时获取数据
fetchInfluxData(); // 组件挂载时获取InfluxDB数据
}, []);
return (
<div>
<h1>温度数据(来自MongoDB)</h1>
<ul>
{temperatures.map((temp, index) => (
<li key={index}>
温度: {temp.value} °C, 时间: {new Date(temp.timestamp).toLocaleString()}
</li>
))}
</ul>
<h1>温度数据(来自InfluxDB)</h1>
<ul>
{influxData.map((data, index) => (
<li key={index}>
温度: {data.value} °C, 时间: {new Date(data.time).toLocaleString()}
</li>
))}
</ul>
</div>
);
};
export default App;
代码说明:
状态管理:使用useState
钩子来管理从MongoDB和InfluxDB获取的温度数据。
数据获取:定义fetchTemperatures
和fetchInfluxData
函数,分别从后端API获取MongoDB和InfluxDB的温度数据。
组件挂载:使用useEffect
钩子在组件挂载时调用数据获取函数。
数据显示:使用map
函数遍历温度数据并在网页上显示。
本项目成功搭建了一个物联网(IoT)云平台,涵盖了数据采集、传输、存储和可视化的完整流程。选择ESP32作为边缘设备,连接温度传感器(如LM35)以实时采集环境温度数据。通过MQTT协议进行数据传输,ESP32将采集到的温度数据发布到主题home/temperature
,确保数据及时传输至云端。后端使用Node.js创建服务,处理来自MQTT Broker的消息并将数据存储到MongoDB和InfluxDB中,提供RESTful API接口以获取最新的温度记录。MongoDB用于快速检索和管理温度数据,而InfluxDB则作为时间序列数据库,支持复杂的时序数据分析。前端应用使用React构建,用户可以通过API实时查看温度变化。此外,项目在数据传输过程中采用SSL/TLS加密技术和OAuth 2.0安全认证机制,确保数据的安全性和完整性。