▎ From Reactive Alarms to Predictive Insight: Bringing AI into a Real-World Energy Storage Codebase

一、写在前面:为什么我要写这篇文章

我所在的项目是一套分布式储能管理系统(Energy Storage Management System, ESMS),主控板基于 ARM-Linux,外围挂着 BMS(电池管理系统)、PCS(储能变流器)、电表、温控、消防、光伏逆变器、CCU(电池簇控制器)等十几类设备。整个项目有上百个
samplerreporter 模块,核心数据流是:

设备 → samplerCAN/RS485/Modbus 采集) → DPR(数据处理中心) → reporterMQTT/IEC104/Modbus 上报)

最近半年我在维护这套代码时,反复被一个问题困扰:告警机制本质上是"事后响应"。

举个真实例子。System.sql 里注册了上千条告警,比如:

  INSERT INTO Charger_DeviceModel_Alarms ... VALUES (1041, 'FGridFault',     6607, 250, ..., 'MA', '[$,0,2240]', NULL);
  INSERT INTO Charger_DeviceModel_Alarms ... VALUES (1047, 'OVBUS',          6613, 250, ..., 'CA', '[$,0,2246]', NULL);
  INSERT INTO Charger_DeviceModel_Alarms ... VALUES (1332, 'GridUFP',        2224, 201, ..., 'MA', '[200,0,1332]',
  '[200,3,6]|[200,3,369]');

这些告警的触发表达式 [$,0,2240] 是"状态参量 2240 == 1 时触发"。也就是说,只有当电芯已经过压、母线已经过压、绝缘已经下降到阈值之下,告警才会触发。这是典型的"被动故障响应"——故障已成既定事实,运维人员才被叫醒。

5MWh 以上规模的储能电站里,一次电池热失控的代价可能是几百万。我希望把这套系统从"被动告警"演进到"主动预警"——让 AI在设备真正坏掉前几小时甚至几天,提前发出风险信号。

这篇文章是我对这个演进方向的完整思考:故障模式怎么分类、用什么模型做时序异常检测、剩余寿命怎么预测、推理放在边缘还是云端、数字孪生和强化学习能不能进来。所有论述会结合本项目的实际代码与数据结构,而不是空谈算法。


二、数据基础:我们手上到底有什么

要做预测性维护,第一步永远是问"我能拿到什么数据"。让我们看本项目的实际数据模型。

2.1 BMS 状态数据(电池簇粒度)

blob_model.h里有一段电池簇的状态结构体:

  typedef struct ...
  {
      float fSOC;                    // 荷电状态 (0-100%)
      float fSOE;                    // 能量状态
      float fSOH;                    // 健康状态 (0-100%)
      float fTotalCapacity;          // 总容量

      // ... 十几项电芯极值 ...
      float fInsulation_P_R;         // 正母线对地绝缘阻值
      float fInsulation_N_R;         // 负母线对地绝缘阻值

      USHORT usSystemRunTime;        // 系统运行时间
      // ...
  } A_BLOB_STBATT_BMS_DATA;          // 电池簇 BMS 数据

再加上模块里通过 CAN总线采集的电芯级数据:单体电压、单体温度、最高/最低电压电芯编号、最高/最低温度电芯编号——粒度可以下沉到每只电芯。

2.2 时序采样频率

st_batt_sampler.h 定义:

  #define STBATT_PUSH2CCU_PERIOD       10
  #define URGET_STBATT_PUSH2CCU_PERIOD  1

也就是说 BMS 数据正常情况 10 秒一帧,异常时 1 秒一帧推送给 CCU。一个 1MWh 的电站,假设 16 簇 × 416 串 × 10s
频率,一天能产生 5700 万条电芯电压样本。这是一座非常优质的时序数据矿。

2.3 历史数据持久化

项目本身已经有半小时粒度的历史数据落库:

  if(!(((gmTime_Now.tm_min == 29) || (gmTime_Now.tm_min == 59))
        && (gmTime_Now.tm_sec == 59)) || ...)
  {//半个小时保存一段数据,一天48段数据
      return FALSE;
  }

每半小时把 A_BLOB_TYPE_DATASTORAGE(含日累计电量、各时段电量、各 MPPT 发电量等)写入本地SQLite。这是慢变量长期趋势的金矿——SOH 衰减、容量衰减都是按月、按年才看得出来的。

2.4 我们手上有什么——汇总

  ┌───────────────┬──────────┬──────┬──────────────────────────┐
  │   数据维度    │   频率   │ 粒度 │           用途           │
  ├───────────────┼──────────┼──────┼──────────────────────────┤
  │ 电芯电压/温度 │ 1–10 s   │ 单体 │ 异常检测、热失控早期识别 │
  ├───────────────┼──────────┼──────┼──────────────────────────┤
  │ SOC/SOH/绝缘  │ 1–10 s   │ 簇   │ RUL 预测、绝缘退化预警   │
  ├───────────────┼──────────┼──────┼──────────────────────────┤
  │ 母线电压电流  │ 1 s      │ PCS  │ 拓扑级异常               │
  ├───────────────┼──────────┼──────┼──────────────────────────┤
  │ 累计电量      │ 30 min   │ 站   │ 容量衰减建模             │
  ├───────────────┼──────────┼──────┼──────────────────────────┤
  │ 告警事件      │ 事件触发 │ 设备 │ 监督学习的标签           │
  └───────────────┴──────────┴──────┴──────────────────────────┘

数据足够。问题是——我们之前完全没有把这些数据当成训练集来组织。


三、故障模式分类:FMEA 是 AI 落地的脚手架

3.1 为什么要从 FMEA 开始

很多人讲"AI 预测性维护"上来就说 LSTMTransformer。我踩过这个坑:没有 FMEAFailure Mode and Effects Analysis)做基础的 AI 模型,最后输出一堆"异常",运维根本不知道该处理什么。

正确顺序是:先把故障模式列清楚 → 每种故障模式对应可观测信号 → 再选模型。

3.2 本项目的故障模式映射

我把本项目当前告警库里的告警按"是否可以预警"做了分类:

  ┌──────────────────┬────────────────────────────────┬─────────────────────────┬───────────────────────────────────┐
  │     故障模式     │          当前告警 ID           │       可观测信号        │          提前预警可行性           │
  ├──────────────────┼────────────────────────────────┼─────────────────────────┼───────────────────────────────────┤
  │ 电芯过温         │ 2244 / OIin                    │ 电芯温度时序、温升斜率  │ 高(热失控前 30 min               │
  │                  │                                │                         │ 一般有温升加速)                  │
  ├──────────────────┼────────────────────────────────┼─────────────────────────┼───────────────────────────────────┤
  │ 电芯过压         │ 2246 / OVBUS                   │ 单体电压、SOC、充电电流 │ 高(充电曲线异常可提前识别)      │
  ├──────────────────┼────────────────────────────────┼─────────────────────────┼───────────────────────────────────┤
  │ 电芯欠压         │ 2241 / LVRT                    │ 单体电压、放电深度      │ 高                                │
  ├──────────────────┼────────────────────────────────┼─────────────────────────┼───────────────────────────────────┤
  │ BMS 通信超时     │ 1224 / CommFail(CAN|SCI|SPI)   │ 心跳间隔、丢包率        │ 中(突发型,但累积错误率有趋势)  │
  ├──────────────────┼────────────────────────────────┼─────────────────────────┼───────────────────────────────────┤
  │ 绝缘故障         │ 由 fInsulation_P_R /           │ 绝缘阻值时序            │ 极高(绝缘衰减是慢过程)          │
  │                  │ fInsulation_N_R 触发           │                         │                                   │
  ├──────────────────┼────────────────────────────────┼─────────────────────────┼───────────────────────────────────┤
  │ PCS 模块过流     │ 6611 / OIin                    │ 母线电流、温度          │ 中                                │
  ├──────────────────┼────────────────────────────────┼─────────────────────────┼───────────────────────────────────┤
  │ 电芯不一致性放大 │ 无显式告警                     │ 单体电压标准差          │ 高(隐患指标,提前数月可见)      │
  └──────────────────┴────────────────────────────────┴─────────────────────────┴───────────────────────────────────┘

注意最后一行——"电芯不一致性"在当前告警库里没有。这就是 AI 的入口:告警库有限、阈值告警是离散的0/1,但电芯一致性是连续退化的。把它纳入 AI 监控,比阈值告警领先几个月。

3.3 工程上怎么落

具体到代码层,我在代码采集到电芯电压的位置需要新增一个轻量旁路:

  // 伪代码:在 BMS 数据 push 之后,旁路推送到本地特征提取队列
  void Push_BMS_Data_To_Feature_Queue(A_BLOB_STBATT_BMS_DATA *pBmsData)
  {
      BMS_FEATURE_RECORD rec;
      rec.tmStamp     = _NOW_;
      rec.fVolt_Std   = StdDev(pBmsData->cellVolts, MAX_CELLS);
      rec.fVolt_Range = MaxMin(pBmsData->cellVolts, MAX_CELLS);
      rec.fTemp_Max   = pBmsData->fMaxCellTemp;
      rec.fTemp_Slope = (rec.fTemp_Max - g_lastFeatureRec.fTemp_Max)
                        / (rec.tmStamp - g_lastFeatureRec.tmStamp);
      rec.fInsR_Min   = MIN(pBmsData->fInsulation_P_R,
                            pBmsData->fInsulation_N_R);
      rec.fSOC        = pBmsData->fSOC;

      Ring_Buffer_Push(&g_featureQueue, &rec);
      g_lastFeatureRec = rec;
  }

这是特征工程的最前端——把原始信号变成低维、有物理意义的特征。后面所有模型都吃这个 ring buffer 的输出。


四、时序异常检测:从 Isolation Forest 到 LSTM Autoencoder

4.1 为什么不只用阈值

本项目当前告警的判断逻辑是 [$,0,2240]==1 这种单参数阈值。它的根本缺陷:

  • 静态:阈值一旦设定,不随设备老化、季节温度调整。
  • 单点:母线电压 OK、绝缘 OK、温度 OK,整体就 OK?不一定——可能三个参数同时朝坏的方向漂移,但都还没越线。
  • 无记忆:告警判断只看当前帧,不看过去 1 小时的趋势。

时序异常检测的价值正是补这三块。

4.2 Isolation Forest:第一道防线

Isolation Forest 是我推荐的第一阶段模型,原因:

  1. 无监督:不需要故障样本(储能电站故障样本极其稀缺,一个月可能就几条)。
  2. 高维容忍:可以同时塞进 20+ 维特征。
  3. 训练廉价:CPU 上几分钟就能训练完。
  4. 可在边缘部署:模型本质是一堆决策树,几十 KB,ARM 板能跑。

具体特征向量我会这样设计(基于 4.3 提到的特征队列,按 5 分钟窗口聚合):

  [
    fVolt_Std_mean, fVolt_Std_max,         // 一致性
    fVolt_Range_mean, fVolt_Range_max,
    fTemp_Max_mean, fTemp_Max_slope,       // 热趋势
    fInsR_Min_mean, fInsR_Min_slope,       // 绝缘趋势
    fSOC_mean, fSOC_range,
    ChrgCurr_RMS, DischrgCurr_RMS,
    P_FFT_band1, P_FFT_band2, P_FFT_band3, // 功率频谱(识别 PCS 振荡)
    ...
  ]

输出是一个 0–1 的异常分数。我会再叠一层规则:连续 3 个窗口分数 > 0.7 才升级为预警,避免单帧噪声引发误报。

4.3 LSTM Autoencoder:识别"模式漂移"

Isolation Forest 的弱点是它不理解时序顺序。比如"先升温再过压"和"先过压再升温"对它是一样的,但物理含义完全不同。

LSTM Autoencoder 可以补上这一刀:用过去 N 步重建当前一步,重建误差大 = 模式漂移。

关键设计:

  • 窗口长度:建议 60 步(10 秒采样 = 10 分钟),覆盖一次充放电小循环。
  • 正常样本筛选:从历史数据里剔除告警时段前后 1 小时作为"正常态"训练集。这一步必须做,否则模型会把已知故障也学进去。
  • 正则化:电池退化是个慢过程,验证集要按时间切(早期数据训练、晚期数据验证),不能随机切,否则数据泄漏。

4.4 两个模型怎么配合

  ┌─────────────────────────────────────────────────┐
  │ 5min 窗口聚合特征                                │
  │       │                                         │
  │       ├──► Isolation Forest  ──► score_iso     │
  │       │                                         │
  │       └──► LSTM Autoencoder ──► score_lstm     │
  │                                                 │
  │  combined_score = max(score_iso, score_lstm)    │
  │                                                 │
  │  if combined_score > T_high (持续 3 窗口):       │
  │        升级为「橙色预警」                         │
  │  if combined_score > T_critical (持续 1 窗口):   │
  │        升级为「红色预警」并同步上报 MQTT          │
  └─────────────────────────────────────────────────┘

上报路径上,本项目的已经有 MQTT 通道。我会复用 Sdgs_RaiseAlert()(在
sdgs_msghandler.c 里)的告警路径,新增一类 alertId(比如 30001 = “AI
预警-电池一致性退化”),让告警走现有上行通道。这样不破坏既有运维流程,运维同事不用学新工具。


五、剩余使用寿命(RUL)预测:把"换电池"从被动变主动

5.1 RUL 是经济价值最大的一块

异常检测的价值是避免事故,RUL 预测的价值是优化资产管理。

一组锂电池的运营寿命大约是 8–10 年。如果能提前 3–6 个月预测出"这一簇电池将在 X 月触及容量衰减门槛",业主可以:

  • 提前采购备件,避免现货溢价
  • 在低电价时段安排停机检修
  • 为整站的运营策略做调整(衰减严重的簇降低充放电深度延寿)

5.2 容量衰减建模:物理 + 数据混合

纯数据驱动模型(直接 LSTMSOH序列)有一个致命问题:外推能力差。储能电池的衰减后期会有"膝点"——非线性加速,而历史数据可能根本没观测过膝点之后的形态。

我倾向于物理模型打底 + 数据模型修正残差:

物理基线(半经验公式):

SOH(t)=1−α⋅t−β⋅Ncycles⋅DODγ \text{SOH}(t) = 1 - \alpha \cdot \sqrt{t} - \beta \cdot N_{\text{cycles}} \cdot \text{DOD}^{\gamma} SOH(t)=1αt βNcyclesDODγ

参数 αβγ 用本项目现有的历史数据(A_BLOB_TYPE_DATASTORAGE.fBattTotalChrgKWH_D / fBattTotalDisChrgKWH_D / fBattChrgTimes_D 等字段)做最小二乘拟合。

数据修正层:用 GBDT(如 LightGBM)拟合"实际 SOH - 物理基线 SOH"的残差,输入特征是温度暴露时间、平均
DOD、平均放电倍率等。

RUL 输出:把模型外推到 SOH = 0.8(业内通用 EOL 门槛),找到那个时间点。

5.3 不确定性量化

RUL 预测如果只给一个点估计,业主大概率不会信。我会用 分位数回归 或 MC Dropout 输出:

  RUL_p10 = 142 天    (悲观估计)
  RUL_p50 = 198 天    (中位数)
  RUL_p90 = 271 天    (乐观估计)

业主拿这个区间做决策,比单点数字鲁棒得多。

5.4 与本项目的对接点

已经在做半小时数据持久化。我会扩展 A_BLOB_TYPE_DATASTORAGE,新增几个字段:

  typedef struct {
      // ... 现有字段 ...

      // === AI Predictive Maintenance Extensions ===
      float fSOH_Predicted_p50;        // SOH 预测中位数
      float fSOH_Predicted_p10;
      float fSOH_Predicted_p90;
      int   nRUL_Days_p50;             // RUL 预测中位数(天)
      int   nRUL_Days_p10;
      int   nRUL_Days_p90;
      float fAnomaly_Score;            // 当前异常分数
      UINT  nAnomaly_Pattern_Id;       // 异常模式 ID(FMEA 表里的)
      time_t tmModelLastInfer;         // 模型上次推理时间
  } A_BLOB_TYPE_DATASTORAGE;

这样 AI 输出就是数据流的一等公民,可以走现有的所有上报通道、可以触发现有的事件机制、可以直接在 Web 界面渲染。


六、从"告警"到"预警":N 小时提前量的工程价值

6.1 时间窗口决定价值

预警提前的时间长度,直接决定它的商业价值:

  ┌────────┬──────────────────────┬──────────────┐
  │ 提前量 │     可执行的动作     │   商业价值   │
  ├────────┼──────────────────────┼──────────────┤
  │ 5 分钟 │ 自动降功率、自动隔离 │ 避免事故扩大 │
  ├────────┼──────────────────────┼──────────────┤
  │ 1 小时 │ 通知运维到场         │ 避免设备损毁 │
  ├────────┼──────────────────────┼──────────────┤
  │ 1 天   │ 调度备件、安排检修   │ 避免运营中断 │
  ├────────┼──────────────────────┼──────────────┤
  │ 1 周   │ 计划性大修           │ 优化运维成本 │
  ├────────┼──────────────────────┼──────────────┤
  │ 1 月+  │ 资产置换决策         │ 优化资本支出 │
  └────────┴──────────────────────┴──────────────┘

不同模型对应不同时间窗口:

  • Isolation Forest / LSTM Autoencoder:5 分钟–1 小时
  • 趋势外推(卡尔曼/ARIMA):几小时–1 天
  • RUL 模型:周–月

我推崇的工程做法是多时间尺度并行——同一份数据流,分别喂给三个时间尺度的模型,每个模型出独立的预警。

6.2 预警如何对接现有系统

本项目已经有完整的告警链路:

sampler 采集 → DPR 计算告警表达式 → AlarmEngine 触发 → reporter 上报(MQTT/IEC104

我不打算新建一条 AI 告警链路,而是复用现有的。具体做法:

  1. AI 推理结果写入虚拟参数。在 SQL 注册一个 deviceModel(比如 999 号 “AI Engine”),它的状态参数(StatusParameters)就是各种 AI 输出:异常分、RUL、各 FMEA 模式概率等。
  2. 告警规则用现有表达式语法。例如:
    INSERT INTO Charger_DeviceModel_Alarms VALUES (30001, 'AI-CellInconsistency', ..., 999, ..., 'MA', '[999,3,1001]>0.8', NULL);
  3. [999,3,1001] 就是 AI 模块设备 999、状态参数 1001(一致性异常分)。
  4. 运维端零侵入。前端、IEC104、MQTT 上报、数据库历史记录都自动接进来。

这是借力打力的工程哲学——别造新轮子,把 AI 当成"会推理的虚拟设备"塞进现有体系。


七、模型部署:边缘 vs 云端的选择

7.1 决策表

我用一张表来回答这个问题:

  ┌──────────┬────────────────────────────────┬───────────────────────┐
  │   维度   │            边缘部署            │       云端部署        │
  ├──────────┼────────────────────────────────┼───────────────────────┤
  │ 推理延迟 │ 10–100 ms                      │ 1–30 s(含网络)      │
  ├──────────┼────────────────────────────────┼───────────────────────┤
  │ 网络要求 │ 离线可用                       │ 必须在线              │
  ├──────────┼────────────────────────────────┼───────────────────────┤
  │ 单机算力 │ 受限(ARM CPU + 几百 MB 内存) │ 充裕                  │
  ├──────────┼────────────────────────────────┼───────────────────────┤
  │ 模型大小 │ < 50 MB 推荐                   │ GB 级 OK              │
  ├──────────┼────────────────────────────────┼───────────────────────┤
  │ 版本管理 │ OTA 升级                       │ 一键全量              │
  ├──────────┼────────────────────────────────┼───────────────────────┤
  │ 数据隐私 │ 数据不出站                     │ 数据上云              │
  ├──────────┼────────────────────────────────┼───────────────────────┤
  │ 典型用途 │ 实时预警、紧急保护             │ RUL、Fleet-level 学习 │
  └──────────┴────────────────────────────────┴───────────────────────┘

7.2 我的实际选择:分层部署

  ┌────────────── 边缘(主控板 ARM Linux)──────────────┐
  │ • Isolation Forest                              │
  │ • LSTM Autoencoder(小模型,量化后 < 5MB)        │
  │ • 阈值告警引擎                                   │
  │ • 反馈给 PCS 的紧急降功率指令                     │
  │ 延迟目标:< 100 ms                               │
  └─────────────────────┬────────────────────────────┘
                        │  特征向量(聚合后,不是原始数据)
                        ▼
  ┌────────────── 云端 ──────────────────────────────┐
  │ • RUL 模型(半经验 + LightGBM)                  │
  │ • Fleet-level 特征对比(横向比对所有同型号电站)│
  │ • 数字孪生 / 强化学习训练                        │
  │ • 模型 OTA 下发                                  │
  └──────────────────────────────────────────────────┘

边缘只跑确定性强、需要实时反应的模型。云端跑需要大数据、慢节奏、跨站学习的模型。原始数据不全部上云——一是带宽,二是合规。

7.3 边缘推理的工程难点

本项目主控是 ARM 平台(code/src/mkenv_arm_st 是构建脚本),一般是 Cortex-A53/A72,4 核、1–2 GB RAM。要在上面塞 AI推理:

  • TFLite MicroONNX Runtime ARM 编译版优先。
  • **量化(INT8)**几乎是必须的——浮点模型在 ARM 上慢 3–5 倍。
  • 推理调度要避开 sampler 的实时窗口。sampler_loader.csampler 是周期线程,AI
    推理要在它的空隙跑,或者放低优先级线程。

我倾向于做一个新的 reporter 模块:ai_inference_reporter。它跟 sampler 通过现有的 DAI 接口(dai_model.h)拿特征数据、跑推理、把结果写回参数库。这条路在我前几天的工作中已经验证过——reporter 通过 DAI
双向访问参数库是可行的(虽然 BLOB 写入要注意是 VAR_VALUE 而不是 PARAM_VAL_GET,这是个坑)。


八、数字孪生 + 强化学习:从预测到自治

8.1 数字孪生不是科幻

"数字孪生"被讲烂了,但在储能场景里它有非常具体的含义:在云端运行一份和真实电站状态同步的物理仿真模型。

输入:电池等效电路模型参数(R0, R1, C1…)+ 实时 SOC、温度
输出:在任意控制策略下,未来 1 小时的 SOC、温度、电压预测

这个孪生体的核心是电池的电热耦合模型,已经有大量成熟开源实现(PyBaMM、Cantera 等)。我会把它和本项目的 BMS数据流接起来:

  1. 实时数据每分钟同步一次到孪生体,孪生体做参数辨识(Kalman/UKF)。
  2. 任何控制策略下发之前先在孪生体上跑一遍,看会不会触发异常。
  3. 如果触发,否决该策略;否则放行到真实硬件。

这就是控制级别的预测性维护——不光预警,还要拦下糟糕的控制决策。

8.2 强化学习:策略探索的安全沙盒

数字孪生的另一个用途是RL 的训练场。储能调度本身就是个经典 RL 问题:

  • 状态:SOC、电价、温度、负荷预测、电池退化系数
  • 动作:充电功率、放电功率、是否参与调频
  • 奖励:电费收益 - 退化代价 - 异常惩罚

直接在真实电站上训 RL不可能——一次错误决策代价太大。但在孪生体上训完,再做"灰度上线"(先在低风险时段跑、收集偏差、再修正模型)就靠谱多了。

8.3 与本项目策略下发的对接

本项目的策略下发路径我前阵子刚梳理过——平台通过 MQTT 下发 strategy 报文,最终落到
sdgs_msghandler.cSdgs_ApplyStrategyToLocalEMS(),写到 200,224
备用计划槽,由 RefreshEmsPlan()(sampler_system.c:2849)按时间切到 200,201 运行槽。

这条路径之后可以插入孪生体校验环节:

  平台 → MQTT → SDGS 解析 →
      [新增] 提交孪生体仿真(云端,5 秒内返回) →
      [新增] 风险评分 < 阈值才放行 →
      Apply 到 200,224 → RefreshEmsPlan 切换执行

孪生体的延迟必须控制在秒级,否则会破坏策略下发的实时性。我会做一个保守降级:孪生体不可用或超时,则用本地的轻量物理模型
(在边缘跑)代替,保证主链路不被云端拖累。


九、踩过的坑和工程化建议

最后聊几点我亲身踩过、和这个项目相关的坑:

  1. 数据采样时间戳一定要 UTC。sampler_system.c 里有用 gmtime_r 也有 localtime_r,混着用,AI模型训练时时区错位会让所有时间窗口对不齐。我建议特征落库统一 UTC,前端展示再转本地。
  2. BLOB 写入参数库的接口签名容易写错。我前几天写策略下发的时候用 PARAM_VAL_GETbuffer 传给 pDAI->Set,结果dai_loader.c 里是 *(VAR_VALUE*)pBuffer 强转,buffer 类型不对就被当成垃圾。AI 输出回写参数库时,记得参考
    web_req_handler.c:619-626 的写法——VAR_VALUE varV; varV.blobValue = …。
  3. 告警表达式不会自动计算 AI 输出。本项目的告警引擎是周期触发的,AI 输出参数要主动 push(用 Push_VarValue /Push_BlobValue),否则告警引擎永远看不到值的变化。
  4. 永远要给 AI 一个"被关掉"的开关。在 System.cfg 里加一个 AI_PredictiveMaint = 0/1
    配置项,万一模型抽风可以一秒内禁用。运维不会信任一个关不掉的 AI。
  5. 模型版本和数据版本必须捆绑。“哪个时间段的数据训出来的哪个模型”,这个映射在生产系统出问题时是救命稻草。我会在A_BLOB_TYPE_DATASTORAGE 里加 nModelVersion 字段,跟着每一次推理结果一起落盘。

十、写在最后

这套储能管理系统当前的代码是高度工程化的——告警、上报、协议适配都很扎实,但本质上还是"被动":等故障发生,再处理故障。AI 进来不是要替代任何现有模块,而是给系统装一双"看见未来"的眼睛**。

我对这条路径的期望:

  • 半年内:边缘的异常检测模型上线,把"电芯一致性退化"这种当前告警库里没有的故障模式纳入预警。
  • 一年内:云端 RUL 模型上线,给业主提供季度级的资产健康报告。
  • 两年内:数字孪生 + RL 闭环上线,把策略下发从"被动执行"升级到"主动优化"。

这不是一个炫技的 AI 项目,而是一个让现有系统更可靠的工程演进。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐