多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

3 家厂商 3 套逻辑:多品牌逆变器 API 归一化的深水区避雷指南

3 家厂商 3 套逻辑:多品牌逆变器 API 归一化的深水区避雷指南 去年 3 月在江苏跑一个 40MW 的分布式工商业项目业主点名要接入华为、阳光和固德威三个牌子的逆变器数据。当时我想得挺美反正都有云端 API无非就是写几个请求函数把数据拉回来往数据库里一塞前端画个图表不就完事了吗结果上线第一周就翻车了。有的电站发电量曲线在大跳水有的电站明明太阳还没落山功率就清零了。到后台一查有的厂商给的是 kW有的是 W有的厂商时间戳带时区有的直接给个服务器本地字符串。那天晚上我和两个工程师硬生生对着三份几百页的文档一行一行抠字段差点没在办公室睡着。做多品牌逆变器数据聚合最难的不是写那几行 API 调用代码而是如何面对「异构数据」带来的降维打击。今天不谈虚的就聊聊我们在实战中总结出的数据归一化逻辑。一、 文档背后的真相那些「名字一样、内涵不同」的坑当你同时对接华为 FusionSolar、阳光电源 iSolarCloud 和固德威的 SEMS 平台时你会发现程序员对同一个物理量的命名能有多少种花样。虽然大家都遵循光伏的基本逻辑但具体的 Schema 设计简直是各过各的。1. 发电量Yield的统计逻辑差异这是最容易让运维人员打架的地方。有的厂商 API 返回的是daily_energy有的叫daily_yield甚至有的叫e_today。名字不同也就算了关键是统计逻辑。比如华为的某些版本接口返回的是「逆变器侧累计值」而有些厂商返回的是「经过云端修正后的值」。如果你的监控平台直接拿来就用你会发现厂商 A 在凌晨 00:00 准时清零当月发电量。厂商 B 在凌晨 00:05 才清零。厂商 C 如果设备离线当日发电量可能直接返回 0 或者 null而不是上一时刻的保持值。2. 功率字段的单位陷阱你以为功率单位一定是 kW太天真了。我们在接入某二线品牌时API 返回的实时功率单位居然是 W而且是个长整型。而阳光的某些接口默认是 kW。如果不做归一化你的大屏上就会出现「某台逆变器功率 50kW隔壁台功率 50000W」的奇观直接把统计图表撑爆。// 典型的异构数据对比// 品牌 A{activePower:12.5,// kWtotalYield:1234.5}// 品牌 B{p_ac:12500,// Wetotal:1234.50}二、 架构设计的核心如何设计一套「能包容万物」的 Schema既然厂商不统一我们就必须在自己的数据采集层和业务层之间强行插进去一个「归一化层」。这个层的核心任务就是屏蔽厂商差异输出标准模型。我们的做法是定义一套「标准点表」。不论底层是哪家 API进入我们的时序数据库我们目前用的是 TimescaleDB之前必须经过一个 Transformer 模块。1. 字段标准化映射表我们内部维护了一张极其详细的映射表部分核心字段如下标准字段名 (Internal)华为 (FusionSolar)阳光 (iSolarCloud)固德威 (SEMS)单位归一说明p_activeactive_powerp_acpackW有功功率e_dayday_capdaily_energyedaykWh当日发电量v_abuabv_abvac1V线电压statusdev_statusstatestatusEnum运行状态码2. 状态码的归一化处理这是最头疼的。华为的 0 可能代表正常阳光的 0 可能代表待机。我们强制定义了一套内部状态码10: 运行, 20: 待机, 30: 故障, 40: 离线。Transformer 模块会根据每个厂商的原始状态码进行逻辑路由。比如如果阳光返回state 2我们会将其映射为业务层通用的30 (故障)。三、 补传与时区那些被忽略的隐形炸弹在做 50MW 以上的大型工商业项目时数据连续性是命根子。逆变器 API 经常会因为网络波动或者厂商服务器维护出现丢包。1. 离线补传的逻辑盲点很多 API 只有实时数据接口没有历史补传接口。或者即使有调用频率限制也极低比如 1 分钟只能请求 10 次。如果某电站断网 2 小时恢复后你要补传这 2 小时的分钟级数据直接调用实时接口会把你的 Token 刷爆。我们现在的策略是优先级队列拉取。优先保证实时功率显示后台异步小批量拉取历史发电量。如果是华为的 API要特别注意其getHistoryInfo接口的字段限制单次请求不能跨度太大。2. 时区的坑UTC 还是 Local去年我们在做一个东南亚的项目时发现数据怎么都对不上。后来发现某厂商 API 返回的时间戳是 UTC0而固德威某些接口返回的是电站所在地的本地时间。如果你的系统统一用北京时间UTC8处理这数据就全乱了。永远记住在归一化层所有时间戳必须在第一时间强制转化为标准的 Unix Timestamp秒级或毫秒级或 ISO8601 UTC 格式。四、 性能挑战限流与并发的平衡当你管理超过 100 个电站时API 限流Rate Limiting就是悬在头上的达摩克利斯之剑。阳光的 API 对 Token 刷新频率有严格限制华为则对单个 IP 的并发数有限制。我们放弃了「随用随调」的模式改为「分布式任务调度」。每个厂商的 API 对接都有一个独立的 Worker 池根据厂商的限流规则严格控制 QPS。比如针对阳光的接口我们会在 Redis 里缓存 Token并在过期前 5 分钟自动刷新避免业务请求瞬间涌入导致所有请求因 Token 失效而报错。我们的判断与选择说实话如果是为了接一两个电站自己写代码硬磕文档还能撑得住。但如果你是要做一个面向资产方或者大型 EPC 的监控平台这种「打补丁式」的开发会让你陷入无尽的运维地狱。厂商文档一更新你的代码可能就得推倒重来。这也是我们后来把这套逻辑抽离出来的初衷。我们把 30 多家主流逆变器、电表、气象站的 API 全部做了深度适配封装成了一个叫 ZenovaConnect 的中间件。它存在的独有的意义就是让你的业务系统不需要知道什么是p_ac或者uab你只需要问它要p_active就行了。它替你扛掉了所有的 API 限流、字段转换、补传逻辑和厂商版本变更。目前我们已经在这个架构上跑了超过 10000 台设备稳定性基本能达到 99.9% 以上。最后想问问各位同行在对接过这么多家 API 后哪个品牌的文档是你心目中的「白月光」哪个又是让你想连夜辞职的「噩梦」欢迎在评论区吐槽交流。了解 ZenovaConnect 完整方案
返回列表