
去年帮某新一线城市城投做城市级停充一体平台时,我们遇到了一个 “致命问题”:
路内停车的地磁数据(来自 NB-IoT 设备)和路外停车场的道闸数据(来自 RS485 设备)根本不通 —— 车主用停车 APP 找到一个 “空闲车位”,到了现场才发现旁边的充电桩早被占了;而充电桩运营商的系统里,“空闲充电桩” 对应的车位其实已经停了车。
这不是某家企业的问题,而是传统 “停车 + 充电” 两套系统的底层矛盾:设备协议碎片化、业务逻辑割裂、数据无法联动。为了解决这些问题,我们团队用了 6 个月时间,基于 SpringCloud 搭建了YunParking 停充一体平台。今天就从技术实现、踩坑调优、实战案例三个维度,聊点真干货。
一、传统方案的 3 个 “技术坑”,我们全踩过
做停充一体之前,我们先复盘了传统方案的痛点 —— 不是 “体验不好”,而是技术架构上的天生缺陷:
1. 设备接入:协议碎片化,每加一个设备就要写一套代码
传统停车系统用的是地磁(NB-IoT)、道闸(RS485),充电系统用的是充电桩(Modbus / 云快充协议),每类设备的通信协议都不一样。比如:
- 地磁用 NB-IoT 发送 “01 03 00 00 00 01” 这样的十六进制指令;
- 道闸用 RS485 发送 “JF:OPEN” 这样的字符串指令;
- 充电桩用云快充的 REST API 发送 “/v1/charger/status” 请求。
早期我们尝试为每个设备写适配代码,结果接入 10 类设备后,代码量膨胀了 3 倍,维护成本直线上升。
2. 业务联动:“停车” 和 “充电” 是两条平行线
传统系统里,停车的 “车位占用” 状态存在 MySQL 的parking_space表,充电的 “充电桩状态” 存在charger表,两者没有关联。比如:
车主停入车位(parking_space.status变为 “占用”),但充电桩系统根本不知道这个车位被用了,依然显示 “空闲”;
车主发起充电请求,充电桩系统要先查 “车位是否空闲”,但只能去停车系统的 API 查 —— 跨系统调用的延迟高达 500ms,体验极差。
3. 分账逻辑:多角色分润,传统支付系统扛不住
停充一体的核心是利益分配:停车费归停车场,充电费归充电桩运营商,政府还要抽成 10%。传统支付系统的分账逻辑是 “固定比例”,比如 “订单金额的 80% 给 A,20% 给 B”,但实际场景中:
- 某停车场的充电费要分 3 成给物业;
- 某充电桩运营商的分润比例随充电时长变化(比如充电 1 小时内分 70%,超过 1 小时分 60%)。
传统支付系统根本无法处理这种动态多角色分账,我们曾试过用支付宝的分账 API,结果因为 “分账角色超过 5 个” 被拒。
二、YunParking 的核心技术:用 3 层架构解决 “停充割裂”
针对上述问题,我们设计了 \\“物联接入层 - 业务逻辑层 - 支付分账层”\\ 的三层架构,从底层打通 “停充” 的每一个环节。
1. 底层:YunIOT—— 统一设备接入层,搞定协议碎片化
我们的目标是:不管设备用什么协议,接入 YunIOT 后都变成 “标准数据”。实现方式是 \\“协议网关 + 适配器模式”\\:
(1)核心设计:协议适配器工厂
我们定义了一个DeviceAdapter接口,每个设备协议对应一个实现类:
public interface DeviceAdapter {
// 设备上报数据解析:把原始数据转成标准DTO
DeviceDataDTO parseRawData(String rawData);
// 下发指令:把标准指令转成设备能懂的格式
String buildCommand(DeviceCommandDTO command);
}比如,NB-IoT 地磁的适配器:
public class NBiotAdapter implements DeviceAdapter {
@Override
public DeviceDataDTO parseRawData(String rawData) {
// 解析NB-IoT的十六进制数据:比如“01 03 00 00 00 01”→“占用”
byte[] bytes = HexUtils.decode(rawData);
int status = bytes[3] & 0xFF;
return new DeviceDataDTO().setStatus(status == 1 ? "occupied" : "free");
}
@Override
public String buildCommand(DeviceCommandDTO command) {
// 把“开闸”指令转成NB-IoT的十六进制:比如“OPEN”→“01 06 00 00 00 01”
return HexUtils.encode(new byte[]{0x01, 0x06, 0x00, 0x00});
}
}然后用工厂模式根据设备类型获取适配器:
public class DeviceAdapterFactory {
private static Map<String, DeviceAdapter> adapters = new HashMap<>();
static {
adapters.put("NB-IoT", new NBiotAdapter());
adapters.put("RS485", new RS485Adapter());
adapters.put("CloudCharge", new CloudChargeAdapter());
}
public static DeviceAdapter getAdapter(String deviceType) {
return adapters.get(deviceType);
}
}(2)消息中间件:私有化 RabbitMQ,解决高并发延迟
早期我们用阿里云 MQTT 接入设备,结果 1000 个设备同时上报数据时,消息延迟高达8 秒(因为 MQTT 的 QoS1 模式要确认消息)。后来换成私有化 RabbitMQ,做了两个优化:
- 队列配置:设置
durable=true(持久化队列),auto_delete=false(不自动删除),避免消息丢失; - 消费者配置:调整
prefetch_count=10(每次拉取 10 条消息),减少 ACK 次数,并发处理能力提升 3 倍。
优化后,设备上报数据的延迟稳定在500ms 以内。
2. 中层:YunParking—— 场景联动引擎,让 “停车” 和 “充电” 说话
停充一体的核心是 \\“场景联动”:比如 “车主停入车位→系统自动推荐空闲充电桩”“车主发起充电→系统锁定对应车位”。我们用规则引擎 \\ 实现了这个逻辑。
####(1)规则引擎设计:事件驱动 + 动态规则
我们定义了两类事件(Event):
- 设备事件:比如 “车位占用”(来自地磁)、“充电桩空闲”(来自充电桩);
- 用户事件:比如 “车主发起停车请求”“车主发起充电请求”。
然后用规则引擎(我们用了Drools,轻量级且易集成)匹配事件和规则:
// 定义规则:当车主停入车位,推荐附近空闲充电桩
rule "Recommend Charger When Parking"
when
$event : ParkingEvent(status == "occupied")
$charger : Charger(status == "free", distanceFrom($event.parkingSpace) < 50) // 查询50米内的空闲充电桩
then
sendRecommendMessage($event.user, $charger); // 给车主发送推荐消息
end####(2)性能优化:Redis 缓存设备状态
早期查询充电桩状态时,要联表查询charger和parking_space,SQL 耗时200ms。我们把充电桩的 “实时状态”(比如 “空闲 / 充电中”)缓存到 Redis,设置5 秒过期时间:
// 查询充电桩状态:先查Redis,再查DB
public ChargerStatus getChargerStatus(String chargerId) {
String key = "charger:status:" + chargerId;
ChargerStatus status = redisTemplate.opsForValue().get(key);
if (status == null || status.isExpired()) {
status = chargerDao.selectStatusById(chargerId);
redisTemplate.opsForValue().set(key, status, 5, TimeUnit.SECONDS);
}
return status;
}优化后,查询时间从 200ms 降到25ms,场景联动的响应时间从原来的 1.2 秒降到500ms。
3. 上层:YunPay—— 动态分账系统,搞定多角色利益分配
停充一体的最后一步是分钱—— 要给停车场、充电桩运营商、政府、物业等多角色分润。传统支付系统的 “固定比例分账” 根本不够用,我们做了 \\“分账规则引擎”\\。
####(1)分账规则设计:JSON 配置,支持动态调整
我们用 JSON 定义分账规则,比如某商业综合体的规则:
{
"ruleId": "mall-001",
"scenario": "parking+charging", // 场景:停车+充电
"parties": [ // 分账方
{"partyId": "parking-lot", "name": "停车场", "type": "proportion", "value": 0.8}, // 停车费80%
{"partyId": "charger-operator", "name": "充电桩运营商", "type": "proportion", "value": 0.7}, // 充电费70%
{"partyId": "government", "name": "政府", "type": "fixed", "value": 0} // 政府抽10%(从总金额里扣)
],
"conditions": [ // 条件:充电时长超过1小时,充电桩运营商分润降10%
{"field": "chargingDuration", "operator": ">", "value": 60, "adjust": {"partyId": "charger-operator", "value": -0.1}}
]
}####(2)分账算法实现:先算总金额,再按规则拆分
分账的核心逻辑是 \\“先算总金额,再按规则拆分给每个角色”\\:
public List<ProfitShareDTO> calculateShare(OrderDTO order) {
List<ProfitShareDTO> result = new ArrayList<>();
// 1. 获取订单对应的分账规则
ShareRule rule = shareRuleDao.getByScenario(order.getScenario());
// 5%,总金额1万,政府分500)
// 这里先处理固定金额分账(比如政府抽成10%)
if (hasFixedShare(rule)) {
handleFixedShare(order, rule, result);
}
// 2. 处理比例分账(比如停车场分80%,充电桩运营商分70%)
for (ShareParty party : rule.getParties()) {
if (party.getType().equals("proportion")) {
double amount = order.getAmount() * party.getValue();
result.add(new ProfitShareDTO(party.getPartyId(), amount));
}
}
// 3.处理条件调整(比如充电时长超过1小时,充电桩运营商分润降10%)
if (hasConditionAdjust(rule)) {
handleConditionAdjust(order, rule, result);
}
return result;
}这个算法支持动态调整分账规则(比如政府突然要提高抽成比例,只需修改 JSON 配置,不用改代码),目前已处理了50 万 + 笔订单,分账准确率 100%。
三、实战案例:某商业综合体的 “停充一体” 改造
聊了这么多技术细节,再讲个真实落地案例—— 某商业综合体的停车场改造(原道闸用捷顺的 RS485 协议,充电桩用云快充协议)。
1. 改造前的问题
- 道闸和充电桩系统独立,车主停好车后要再打开充电 APP 找充电桩,体验差;
停车场收入只有停车费,充电桩的利用率只有60%(因为车主找不到充电桩)。
改造步骤
(1)设备接入:用 YunIOT 的 RS485 适配器适配捷顺道闸,用云快充适配器适配充电桩;
(2)场景联动:配置规则引擎 ——“车主停入车位→系统自动推荐 50 米内的空闲充电桩”;
()分账规则:设置 “停车费 80% 归停车场,20% 归物业;充电费 70% 归充电桩运营商,20% 归停车场,10% 归政府”。
改造效果
- 车主体验:停充流程从 “2 个 APP、5 步操作” 变成 “1 个 APP、3 步操作”,满意度提升40%;
- 运营数据:充电桩利用率从65%提升到85%,停车场月收入增加25%(因为充电费的 20% 归停车场);
- 技术指标:设备上报延迟450ms,场景联动响应时间600ms,分账接口并发处理能力10QPS(支持 10 笔订单同时分账)。
四、未来规划:从 “功能一体” 到 “智能一体”
停充一体不是终点,我们正在做 \\“智能一体”\\—— 用 AI 让系统更懂用户:
1. AI 预测调度:用 LSTM 模型预测车位占用率
我们用LSTM(长短期记忆网络)训练了一个模型,输入 “历史车位占用率、节假日、天气” 三个特征,预测未来2 小时的车位占用率。目前模型的预测准确率达 85%,可以提前引导车主到空闲停车场,减少绕路时间。
2. 车机联动:对接 CAN 总线,实现自动停充
我们正在和某新势力车厂合作,对接车辆的CAN 总线(控制器局域网):
- 车辆自动发送 “找车位 + 充电” 请求(通过 CAN 总线获取车辆的位置和电量);
- YunParking 返回 “最优车位 + 充电桩” 路径(基于实时数据);
- 车辆自动导航到车位,系统自动开闸、锁定充电桩。
目前 Demo 测试已通过,响应时间 \\<1 秒 \\。
五、写在最后:停充一体的本质是 “技术融合”
做 YunParking 的半年里,我们最深的体会是:停充一体不是 “停车系统 + 充电系统” 的拼接,而是 “设备协议、业务逻辑、数据链路” 的底层融合。
对技术开发者来说,这是一个 “全栈式” 的实践场 —— 要懂物联网(设备接入)、懂微服务(SpringCloud)、懂大数据(Redis 缓存、LSTM 模型)、懂支付(分账逻辑);对企业来说,这是 “降本增效” 的关键 —— 统一平台减少了运维成本,充电业务增加了收入来源。
如果你的企业也在做停充一体,欢迎和我交流 —— 我们踩过的坑,或许能帮你少走弯路。

