3、数据采集架构设计:边缘采集 vs 云端采集、采集网关硬件选型、采集频率与数据压缩策略、数据缓存与断点续传机制

大家好,我是老张。今天咱们聊聊数据采集架构设计。说实话,这一块是储能数据系统的地基。地基没打好,后面ETL做得再漂亮也是白搭。我在几个大型储能项目里都踩过坑,今天把这些经验掰开揉碎了讲给你听。

3.1 边缘采集 vs 云端采集:不是二选一,是配合

很多人一上来就问:「我该用边缘采集还是云端采集?」我的回答是:别急着二选一。你想想看,储能系统里既有毫秒级的BMS数据,也有小时级的电表数据,怎么可能一套方案通吃?

边缘采集,说白了就是在设备端附近完成数据采集和初步处理。我习惯在采集网关上跑一个轻量级的采集程序,把高频数据先收上来,做一次清洗和聚合,再往云端推。

云端采集,则是设备直接上报原始数据到云平台,由云端的ETL任务去处理。这种方式架构简单,但对网络和带宽要求高。

我个人建议采用边缘+云端混合架构。核心逻辑是这样的:

  • 高频数据(≤1秒):边缘采集,本地缓存,按需聚合后上报
  • 中频数据(1秒~1分钟):边缘采集,实时上报,云端做二次处理
  • 低频数据(≥1分钟):直接云端采集,设备主动上报

核心原则:边缘负责「快」和「稳」,云端负责「全」和「智」。两者各司其职,别让边缘干云端的活,也别让云端处理边缘该做的事。

下面这张图是我自己画的混合采集架构,你看一眼就明白了:

储能数据混合采集架构 设备层(BMS / PCS / 电表 / 温控) BMS PCS 电表 温控 其他传感器 边缘采集层(采集网关) 高频采集 数据缓存 断点续传 数据压缩 协议转换 云端采集层(IoT Hub / 数据平台) 数据接收 数据校验 数据存储 ETL处理 数据分发 注:高频数据走边缘→云端,低频数据可设备直连云端

3.2 采集网关硬件选型:别只看参数,要看场景

采集网关选型,我踩过最大的坑就是「参数党」。曾经有个项目,我看某款网关CPU主频高、内存大,直接拍板买了。结果到现场发现,这玩意功耗太高,在户外机柜里散热根本扛不住。嗯,后来全换了。

选型时我一般看这几个维度:

维度 关键指标 我的建议
计算能力 CPU主频、核心数 ARM Cortex-A系列起步,别用M系列,跑不了协议栈
存储 RAM、eMMC/Flash RAM ≥ 512MB,存储 ≥ 8GB(要缓存数据)
接口 RS485、CAN、以太网、4G/5G RS485至少2路,CAN至少1路,以太网必备
环境适应性 工作温度、防护等级 工业级:-40℃~85℃,户外选IP65以上
功耗 典型功耗、待机功耗 ≤15W,太阳能供电场景≤5W
可靠性 MTBF、看门狗、双机热备 MTBF ≥ 100000小时,必须有硬件看门狗

我的经验:如果现场有4G网络,优先选带4G模块的网关。别指望现场拉网线,储能站大多在偏远地方。我曾经在一个山顶储能站调试,4G信号只有两格,还好网关支持外接天线,不然数据都传不回来。

3.3 采集频率与数据压缩策略:别把带宽当自来水

采集频率怎么定?我见过最夸张的项目,BMS数据每100毫秒采一次,一天下来一个电池簇就产生800多万条记录。你想想看,100个簇呢?数据量直接爆炸。

我的原则是:按需采集,能聚合就别存原始值

具体来说:

  • 电压、电流、温度:这些变化快,建议100ms~1s采集一次。但上报时可以做聚合——比如每秒上报一次平均值、最大值、最小值,原始数据本地存一份就行。
  • SOC、SOH:变化慢,1分钟采集一次足够。别学某些项目每秒采一次SOC,那玩意算法算出来的,一秒能变多少?
  • 告警事件:触发式采集,平时不采,有告警才记录。这个最省带宽。

数据压缩方面,我常用的策略:

  1. 死区压缩:数值变化不超过阈值就不记录。比如电压变化小于0.01V,直接忽略。这个在储能场景特别管用,因为很多数据是平稳的。
  2. 旋转门压缩:用线性拟合的方式,只记录趋势变化的关键点。适合长时间序列数据。
  3. Gzip/Zlib压缩:传输层压缩,对JSON格式数据压缩率能达到5:1以上。

避坑指南:我曾经在一个项目里用了死区压缩,阈值设得太大了,结果电压波动没被记录,导致后续的SOC估算偏差很大。后来我把阈值调小,同时保留每5分钟一个强制采样点,问题就解决了。

3.4 数据缓存与断点续传机制:别让网络断了就丢数据

储能站网络不稳定是常态。4G信号时好时坏,光纤被挖断也是常有的事。所以数据缓存和断点续传是必须的,不是可选项。

我一般这样设计:

缓存策略

  • 内存缓存:用环形缓冲区,存最近1分钟的数据。速度快,但掉电就丢。
  • 本地文件缓存:每1分钟把内存数据刷到本地SQLite或文件中。掉电不丢,但要注意写入频率,别把Flash写坏了。
  • 分级缓存:内存→本地文件→SD卡。数据量大了就往下一级挪。

断点续传机制

  1. 每条数据生成一个唯一ID(时间戳+设备ID+序号)。
  2. 上传时记录已上传的最大ID。
  3. 网络恢复后,从断点处开始补传。
  4. 补传时按时间顺序,先传最新的,再补旧的(保证实时性)。

代码示例(伪代码,展示核心逻辑):

// 数据缓存与断点续传核心逻辑
class DataCacheManager {
    private:
        string lastUploadedId;  // 已上传的最大ID
        Queue<DataPoint> cacheQueue;  // 内存缓存队列
        
    public:
        void onDataReceived(DataPoint dp) {
            dp.id = generateUniqueId();
            cacheQueue.push(dp);
            
            // 每100条数据刷一次本地缓存
            if (cacheQueue.size() >= 100) {
                flushToLocalStorage();
            }
        }
        
        void onNetworkRecovered() {
            // 从本地存储读取未上传的数据
            vector<DataPoint> pendingData = readFromLocalStorage(lastUploadedId);
            
            // 按时间排序,先传最新的
            sort(pendingData, byTimestampDesc);
            
            for (auto& dp : pendingData) {
                if (uploadToCloud(dp)) {
                    lastUploadedId = dp.id;
                } else {
                    break;  // 网络又断了,下次继续
                }
            }
        }
        
        void flushToLocalStorage() {
            // 写入SQLite或文件
            // 注意:写入频率不要超过每秒1次,保护Flash
        }
};

重要提醒:本地缓存一定要设置上限。我见过一个项目,缓存数据攒了3个月没上传,结果SD卡写满了,新数据全丢了。建议设置缓存上限为7天数据量,超过上限就覆盖最旧的数据。

好了,数据采集架构设计就聊到这儿。核心就三句话:边缘和云端要配合好,网关选型看场景别只看参数,缓存和续传机制必须做扎实。下一节咱们聊数据清洗和标准化,那又是另一番天地了。


公众号:蓝海资料掘金营,微信deep3321