• 全栈物联网云平台搭建:MQTT、Node.js、MongoDB、InfluxDB与React的应用示例


    一、项目概述

    随着物联网(IoT)技术的迅速发展,越来越多的设备和应用需要连接到互联网,实现数据的实时采集、传输和分析。本项目旨在搭建一个物联网云平台,能够支持多种传感器数据的采集与处理,为用户提供实时监控、数据分析及决策支持。平台将涵盖设备管理、数据存储与处理、可视化界面等功能,为智能家居、工业监控和环境监测等应用场景提供支持。

    二、系统架构

    本系统架构分为四个主要层次:边缘层、传输层、云层和应用层。

    1. 边缘层:
    • 单片机:选择ESP32作为设备的核心控制器,具备Wi-Fi和蓝牙功能,适合IoT应用。

    • 传感器技术:使用温湿度传感器(如DHT11)、光照传感器等,采集环境数据。

    1. 传输层:
    • 无线通信协议:采用MQTT协议进行设备与云端的通信,因其轻量级和低延迟的特点,适合物联网场景。
    1. 云层:
    • 云计算平台:选择AWS作为云服务提供商,利用其丰富的服务支持。

    • 大数据处理:使用Apache Spark进行数据处理与分析。

    • 数据库:选择MongoDB存储传感器数据,使用InfluxDB进行时间序列数据的存储。

    1. 应用层:
    • API设计:使用RESTful API进行前后端数据交互,GraphQL用于复杂数据查询。

    • 前端开发:使用React框架开发用户界面,方便用户查看实时数据。

    • 后端开发:使用Node.js构建后端服务,提供数据处理和API接口。

    1. 安全技术:
    • 实施SSL/TLS加密,确保数据在传输过程中的安全性。

    • 使用OAuth 2.0进行身份验证和授权管理。

    三、环境搭建

    根据系统架构的技术栈,以下是环境搭建的步骤:

    1. 单片机开发环境:
    • 下载并安装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并安装
      
    1. 云环境:
    • 注册AWS账号,创建EC2实例,选择Ubuntu Server作为操作系统。

    • 安装Node.js和npm:

      sudo apt updatesudo apt install nodejs npm
      
    1. 数据库环境:
    • 安装MongoDB:

      sudo apt install -y mongodb
      
    • 安装InfluxDB:

      sudo apt install influxdb
      
    1. 大数据处理环境:
    1. 前端环境:
    • 使用Create React App快速搭建前端开发环境:

      npx create-react-app my-iot-appcd my-iot-appnpm start
      

    四、代码实现

    本部分将详细实现物联网云平台的各个组件,包括ESP32设备的代码、Node.js后端服务、MongoDB数据库、InfluxDB时间序列存储、以及React前端界面。每个部分都将附上详细的代码示例和说明。

    1. ESP32设备代码

    ESP32作为边缘设备,负责采集温度数据并通过MQTT协议发送到云端。以下是ESP32的代码示例:

    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的连接管理,确保设备始终保持在线。

    2. Node.js 后端服务

    后端服务的主要功能是接收来自MQTT Broker的消息,并将温度数据存储到MongoDB和InfluxDB中,同时提供RESTful API供前端访问。

    Node.js代码示例
    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服务器,监听指定端口。

    3. MongoDB和InfluxDB数据库

    MongoDB用于存储温度数据,InfluxDB用于时间序列数据的高效存储和查询。确保您在本地或云端安装并运行这两个数据库。

    MongoDB安装
    # 安装MongoDB (Ubuntu示例)
    sudo apt updatesudo apt install -y mongodbsudo 
    systemctl start mongodbsudo 
    systemctl enable mongodb
    
    InfluxDB安装
    # 安装InfluxDB (Ubuntu示例)
    sudo apt updatesudo apt install influxdbsudo 
    systemctl start influxdbsudo 
    systemctl enable influxdb
    
    创建InfluxDB数据库

    在InfluxDB中,我们需要创建一个用于存储温度数据的数据库。以下是创建数据库的步骤:

    1. 进入InfluxDB命令行:

      influx
      
    2. 创建数据库:

      在InfluxDB命令行界面中,输入以下命令以创建数据库:

      CREATE DATABASE iot_data
      
    3. 查看已创建的数据库:

      运行以下命令查看当前数据库列表,确保iot_data数据库已成功创建:

      SHOW DATABASES
      
    4. 创建时间序列数据的测量:

      在我们的Node.js应用中,已经在InfluxDB连接时定义了测量(measurement)为temperature。不需要手动创建,数据会在插入时自动生成。

    4. React 前端实现

    前端将展示从后端获取的温度数据。我们将使用React构建用户界面,允许用户查看最新的温度数据。

    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获取的温度数据。

    • 数据获取:定义fetchTemperaturesfetchInfluxData函数,分别从后端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安全认证机制,确保数据的安全性和完整性。

  • 相关阅读:
    南阳市卧龙区中医院综合楼施工组织设计及投标报价
    Android系统10 RK3399 init进程启动(四十三) ROM定制开机自启动服务(C++程序)
    鸿蒙开发|鸿蒙系统项目开发前的准备工作
    常数据成员(1)
    嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第七天-内核函数接口(物联技术666)
    Java急速转职GoLang工程师资料
    详解MySQL隔离级别
    SpringBootWeb 篇-入门了解 Apache POI 使用方法
    基于springboot实现休闲娱乐代理售票平台系统项目【项目源码+论文说明】
    Nginx常用命令
  • 原文地址:https://blog.csdn.net/qq_40431685/article/details/140986190