充电桩或充电宝 IoT 系统的设计方案
一、方案如下
1. 场景描述
在充电桩或共享充电宝场景中,设备会实时产生大量的时间序列数据(如电流、电压、充电功率、温度等),以及用户相关的使用数据(如充电时长、费用)。系统需要实现:
- 设备监控:实时监控设备运行状态,捕捉故障信息并触发报警。
- 使用记录:记录用户每次充电的历史数据。
- 数据分析:分析设备的使用频率、充电效率、用户行为等,为优化运营决策提供支持。
- 可扩展性:支持未来增加更多设备、用户或功能模块。
2. 使用的技术栈
- 时序数据库:InfluxDB,用于存储设备时间序列数据(如充电状态、电流、电压等)。
- 消息传输协议:基于 MQTT 协议(使用 EMQX 作为 MQTT Broker)。
- 后端服务:Spring Boot 构建 Java 后端,用于数据接收、存储和接口提供。
- 可视化工具:Grafana,用于实时监控和可视化充电桩或充电宝的数据。
- 未来扩展:结合机器学习算法(如 TensorFlow 或 PyTorch)分析预测设备故障或优化充电效率。
二、组件安装与部署
1. 时序数据库是什么
参考:时序数据库是什么
2. 部署 InfluxDB
InfluxDB 被选为时序数据库,存储充电桩设备数据和用户相关的时间序列数据。
安装步骤(Linux 环境):
- 下载并解压:
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
-
启动服务:
sudo /usr/local/influxdb/influxd & -
配置并初始化:
- 打开浏览器访问
http://localhost:8086。 - 设置管理员账户、组织名称(如
ChargingOrg)和默认 Bucket(如charging_data)。 - 设置数据保留策略为 30 天。
- 打开浏览器访问
-
验证 CLI 是否可用:
influx bucket list
2. 部署 EMQX(MQTT Broker)
EMQX 作为 MQTT Broker,用于设备数据的发布和处理。
安装步骤(Linux 环境):
参考:EMQX + MQTT + Java 后台服务器完整实现文档
3. 部署 Grafana
用于可视化充电桩或充电宝的运行状态和历史数据。
安装步骤(Linux 环境):
-
安装 Grafana:
sudo apt-get install -y grafana -
启动服务:
sudo systemctl start grafana-server -
配置数据源:
- 登录 Grafana 页面(默认
http://localhost:3000),默认账户为admin/admin。 - 添加 InfluxDB 作为数据源,InluxDB 地址为
http://localhost:8086,认证使用之前配置的 Token。
- 登录 Grafana 页面(默认
三、后端实践(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);
}
}
后续扩展
-
告警系统
- 设置阈值(如电流、电压异常)并集成告警通知(如邮件、短信或钉钉)。
-
数据分析
- 使用机器学习模型(如 TensorFlow/Scikit-learn)分析预测设备故障或优化充电效率。
-
用户行为分析
- 汇总用户充电数据,分析高峰时段、热销设备等运营指标。
-
大规模集群
- 部署分布式 InfluxDB 或切换到分布式时序数据库(如 TimescaleDB 或 VictoriaMetrics)。
- 使用 Kubernetes 实现容器化部署和弹性扩展。
-
边缘计算
- 在设备端集成轻量级数据库(如 SQLite 或 TimescaleDB-edge),减少网络流量。
该方案覆盖了从设备数据采集、数据存储到后端查询与扩展的完整流程,并为未来功能扩展提供了方向,是 IoT 场景下的一套高效、灵活的解决方案。