充电桩或充电宝 IoT 系统设计方案

241 阅读4分钟

充电桩或充电宝 IoT 系统的设计方案


一、方案如下

1. 场景描述

在充电桩或共享充电宝场景中,设备会实时产生大量的时间序列数据(如电流、电压、充电功率、温度等),以及用户相关的使用数据(如充电时长、费用)。系统需要实现:

  1. 设备监控:实时监控设备运行状态,捕捉故障信息并触发报警。
  2. 使用记录:记录用户每次充电的历史数据。
  3. 数据分析:分析设备的使用频率、充电效率、用户行为等,为优化运营决策提供支持。
  4. 可扩展性:支持未来增加更多设备、用户或功能模块。

2. 使用的技术栈

  1. 时序数据库:InfluxDB,用于存储设备时间序列数据(如充电状态、电流、电压等)。
  2. 消息传输协议:基于 MQTT 协议(使用 EMQX 作为 MQTT Broker)。
  3. 后端服务:Spring Boot 构建 Java 后端,用于数据接收、存储和接口提供。
  4. 可视化工具:Grafana,用于实时监控和可视化充电桩或充电宝的数据。
  5. 未来扩展:结合机器学习算法(如 TensorFlow 或 PyTorch)分析预测设备故障或优化充电效率。

二、组件安装与部署

1. 时序数据库是什么

参考:时序数据库是什么

2. 部署 InfluxDB

InfluxDB 被选为时序数据库,存储充电桩设备数据和用户相关的时间序列数据。

安装步骤(Linux 环境):
  1. 下载并解压:
wget https://dl.influxdata.com/influxdb/releases/influxdb2-2.7.0-linux-amd64.tar.gz
tar -xvf influxdb2-2.7.0-linux-amd64.tar.gz
sudo mv influxdb2 /usr/local/influxdb
  1. 启动服务:

    sudo /usr/local/influxdb/influxd &
    
  2. 配置并初始化:

    • 打开浏览器访问 http://localhost:8086
    • 设置管理员账户、组织名称(如 ChargingOrg)和默认 Bucket(如 charging_data)。
    • 设置数据保留策略为 30 天。
  3. 验证 CLI 是否可用:

    influx bucket list
    

2. 部署 EMQX(MQTT Broker)

EMQX 作为 MQTT Broker,用于设备数据的发布和处理。

安装步骤(Linux 环境):

参考:EMQX + MQTT + Java 后台服务器完整实现文档

3. 部署 Grafana

用于可视化充电桩或充电宝的运行状态和历史数据。

安装步骤(Linux 环境):
  1. 安装 Grafana:

    sudo apt-get install -y grafana
    
  2. 启动服务:

    sudo systemctl start grafana-server
    
  3. 配置数据源:

    • 登录 Grafana 页面(默认 http://localhost:3000),默认账户为 admin/admin
    • 添加 InfluxDB 作为数据源,InluxDB 地址为 http://localhost:8086,认证使用之前配置的 Token。

三、后端实践(Java 实现)

1. 技术选型

  • Spring Boot:用于构建后端服务,处理设备数据并与 InfluxDB 交互。
  • InfluxDB Java Client:实现数据的读写。
  • MQTT 客户端:使用 Eclipse Paho 实现消息订阅和处理。

2. 环境准备

pom.xml 文件中添加以下依赖:

<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <!-- InfluxDB Java 客户端 -->
    <dependency>
        <groupId>com.influxdb</groupId>
        <artifactId>influxdb-client-java</artifactId>
        <version>6.10.0</version>
    </dependency>
    <!-- MQTT 客户端 -->
    <dependency>
        <groupId>org.eclipse.paho</groupId>
        <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
        <version>1.2.5</version>
    </dependency>
</dependencies>

3. 连接 InfluxDB

创建配置类,初始化 InfluxDB 客户端:

import com.influxdb.client.InfluxDBClient;
import com.influxdb.client.InfluxDBClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class InfluxDBConfig {

    private static final String INFLUXDB_URL = "http://localhost:8086";
    private static final String TOKEN = "your-influxdb-token";
    private static final String ORG = "ChargingOrg";

    @Bean
    public InfluxDBClient influxDBClient() {
        return InfluxDBClientFactory.create(INFLUXDB_URL, TOKEN.toCharArray(), ORG);
    }
}

4. 接收 MQTT 数据并写入 InfluxDB

创建 MQTT 客户端服务类:

import com.influxdb.client.InfluxDBClient;
import com.influxdb.client.write.Point;
import org.eclipse.paho.client.mqttv3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MqttService {

    private static final String MQTT_BROKER = "tcp://localhost:1883";
    private static final String TOPIC = "iot/charging/#";

    @Autowired
    private InfluxDBClient influxDBClient;

    public MqttService() {
        connectAndSubscribe();
    }

    private void connectAndSubscribe() {
        try {
            MqttClient client = new MqttClient(MQTT_BROKER, MqttClient.generateClientId());
            client.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable cause) {
                    System.err.println("Connection lost");
                }

                @Override
                public void messageArrived(String topic, MqttMessage message) {
                    String payload = new String(message.getPayload());
                    System.out.println("Message received: " + payload);

                    // 假设消息格式为 JSON,解析后写入 InfluxDB
                    Point point = Point.measurement("charging_data")
                        .addField("voltage", 220.0)
                        .addField("current", 10.0)
                        .addField("power", 2200.0)
                        .time(System.currentTimeMillis(), WritePrecision.MS);

                    influxDBClient.getWriteApiBlocking().writePoint("charging_data", "ChargingOrg", point);
                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken token) {}
            });

            client.connect();
            client.subscribe(TOPIC);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

5. 查询数据接口

创建 REST API 提供查询服务:

import com.influxdb.client.QueryApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ChargingDataController {

    @Autowired
    private QueryApi queryApi;

    @GetMapping("/charging/history")
    public String getChargingHistory(@RequestParam String deviceId) {
        String fluxQuery = "from(bucket: \"charging_data\") |> range(start: -7d) |> filter(fn: (r) => r.device_id == \"" + deviceId + "\")";
        return queryApi.query(fluxQuery);
    }
}

后续扩展

  1. 告警系统

    • 设置阈值(如电流、电压异常)并集成告警通知(如邮件、短信或钉钉)。
  2. 数据分析

    • 使用机器学习模型(如 TensorFlow/Scikit-learn)分析预测设备故障或优化充电效率。
  3. 用户行为分析

    • 汇总用户充电数据,分析高峰时段、热销设备等运营指标。
  4. 大规模集群

    • 部署分布式 InfluxDB 或切换到分布式时序数据库(如 TimescaleDB 或 VictoriaMetrics)。
    • 使用 Kubernetes 实现容器化部署和弹性扩展。
  5. 边缘计算

    • 在设备端集成轻量级数据库(如 SQLite 或 TimescaleDB-edge),减少网络流量。

该方案覆盖了从设备数据采集、数据存储到后端查询与扩展的完整流程,并为未来功能扩展提供了方向,是 IoT 场景下的一套高效、灵活的解决方案。