*openUBMC 支持TPSU turbo电容寿命预测功能详细设计说明书*

<table>
    <tr>
        <td>所属SIG组:</td>
        <td>hardware_sig</td>
    </tr>
    <tr>
        <td>落入版本:</td>
        <td>25.12</td>
    </tr>
    <tr>
        <td>设计人员:</td>
        <td>付明权</td>
    </tr>
    <tr>
        <td>日期:</td>
        <td>2025.11.21</td>
    </tr>
</table>

**Copyright © 2025 openUBMC Community**

您对&quot;本文档&quot;的复制，使用，修改及分发受木兰宽松许可证, 第2版协议(以下简称&quot;MulanPSL2&quot;)的约束。
为了方便用户理解，您可以通过访问<https://license.coscl.org.cn/MulanPSL2>了解MulanPSL2的概要 (但不是替代)。
MulanPSL2的完整协议内容您可以访问如下网址获取：<https://license.coscl.org.cn/MulanPSL2>。

**改版记录**

<table>
    <tr>
        <th>日期</th>
        <th>修订版本</th>
        <th>修订描述</th>
        <th>作者</th>
        <th>审核</th>
    </tr>
    <tr>
        <td>xxx</td>
        <td>xxx</td>
        <td>xxx</td>
        <td>xxx</td>
        <td>xxx</td>
    </tr>
    <tr>
        <td>xxx</td>
        <td>xxx</td>
        <td>xxx</td>
        <td>xxx</td>
        <td>xxx</td>
    </tr>
</table>

**List of abbreviations**  **缩略语清单** ：

<table>
    <tr>
        <th>Abbreviations 缩略语</th>
        <th>Full spelling 英文全名</th>
        <th>Chinese explanation 中文解释</th>
    </tr>
    <tr>
        <td>xxx</td>
        <td>xxx</td>
        <td>xxx</td>
    </tr>
    <tr>
        <td>xxx</td>
        <td>xxx</td>
        <td>xxx</td>
    </tr>
</table>

[TOC]

# 1.功能分析
## 1.1 功能背景
<!-- 描述该需求的来源或背景，比如：支撑XXX功能、XXX优化等；以及该需求对用户（含组件）带来什么具体价值，如果没有该需求，对用户（含组件）带来什么损失； -->
BMC需要对TPSU turbo电容的寿命进行预测，在电容充放电、寿命预测等操作成功后在维护日志中记录下相应电源turbo电容数据，以便后续收集数据评估准确性，并用于turbo电容寿命预警策略管理

## 1.2 功能描述
<!-- 描述该需求交付的整体功能，主要实现XXX功能，解决XXX问题，明确方案如何实现 -->
BMC基于PSU提供的基础参数记录，进行turbo电容寿命计算，并在相关操作成功后记录下电源turbo电容的数据

## 1.3 功能场景
<!-- 描述该需求的业务使用场景，内容包括：
1) 场景出发条件及对象：什么角色/工具/接口等在什么具体情况下使用该特性，使用对象技能如何？
2) 使用时间及频度
3) 描述该特性主要有哪些场景、子场景及关键任务操作 -->
1、TPSU turbo电容寿命预测<br>
2、维护日志记录TPSU turbo电容相关数据

## 1.4 功能列表
<!-- 描述该需求交付的功能列表，内容包括：列出功能详细描述，标题、描述。 -->
| 功能编号 | 功能标题 | 功能描述 |
| ------- | ------- | -------- |
| 1 | 支持TPSU turbo电容寿命预测和预警 | turbo电容寿命计算和预警策略管理 |
| 2 | 支持TPSU turbo信息记录 | 维护日志记录turbo电容相关统计数据 |


# 2.功能设计
## 2.1 总体方案分析
<!-- 描述该方案的总体设计（注：相关输出方案可同步刷新到各组件仓） -->

### 2.1.1 方案详细设计
#### 2.1.1.1 方案概述
<!-- 描述该方案的整体实现，内容包括：涉及的关键点，实现策略等 -->
**TPSU侧：**
1、通过0x0515上报当前TPSU存储的最大放电档位，需要BMC侧查询所有档位数据并计算<br>
2、TPSU记录turbo电容的放电深度（考虑裕量按55v）、频率、温度分档下的放电次数。BMC侧通过0x0516命令逐次查询放电次数，<strong style = "color:red">下发索引2s后</strong>再读取放电次数<br>
3、放电次数存flash，下电后信息不丢失

**BMC侧：**
1、BMC侧需要通过0x0515命令，明确需要读取多少个放电次数的数据；然后通过0x0516命令逐个查询当前TPSU的放电次数并计算，保障所有数据均全部查询完成<br>
2、寿命计算：寿命预测任务定时遍历电源，每次下发TPSU一个查询命令，TPSU上报（深度、频率、温度）下不同组合下的次数，<strong style = "color:red">RM310通过次数*加权系数得出当前寿命裕量</strong>，寿命加权后先计算，再统一取整<br>
3、寿命计算周期：每个月BMC主动定期查询一次<br>
4、升级策略：电容寿命模型修正对应加权系数同步修改，采用硬编码加权系数的方式，只需升级BMC软件即可达到升级加权系数

<strong style = "color:red">寿命公式 = 2.6亿 - Σ（充放电次数 * 加权系数）</strong>

#### 2.1.1.2 开发视图
<!-- 开发视图面向系统开发及软件管理，描述系统代码结构，构建结构的视图，主要解决系统技术实现和开发的问题，它依托逻辑视图，描述代码、构建结构 -->

```mermaid
graph TD
    subgraph 组件业务层
        App[寿命预测定时任务]
        RM310[RM310寿命模型/系数库]
        OnePowerList[OnePower对象列表<br/>PSU1..PSUn]
    end

    subgraph TPSU侧
        TPSU[TPSU]
        Flash[Flash放电统计]
    end

    App --> RM310
    App --> OnePowerList
    OnePowerList --> TPSU
    TPSU --> Flash
    Flash --> TPSU

    classDef task fill:#e1f5fe,stroke:#7ab8f5;
    classDef tpsu fill:#ffe5cc,stroke:#d68c45;
    class App,RM310,OnePowerList task;
    class TPSU,Flash tpsu;
```

#### 2.1.1.3 运行视图
<!-- 运行视图面向系统运行，描述系统启动过程、运行期交互的视图，主要解决系统运行期交互，描述各可执行交付件在运行期的交互关系 -->

```mermaid
sequenceDiagram
    participant App as 寿命预测定时任务
    participant RM310 as 寿命预测模型
    participant OnePower as OnePower对象
    participant TPSU as TPSU
    participant Flash as TPSU Flash

    loop 每月周期/人工触发
        App->>App: 获取OnePower对象列表

        loop 遍历每个OnePower对象(PSU[i])
            App->>OnePower: 迭代PSU[i]上下文(包含地址/档位缓存)
            OnePower->>TPSU: 发送0x0515命令(查询最大放电档位)
            TPSU->>Flash: 读取最大放电档位信息
            TPSU-->>OnePower: 返回最大档位N
            OnePower-->>App: N
            App->>App: 初始化档位索引=0

            loop 档位0..N
                App->>OnePower: 下发0x0516(索引i)
                Note right of App: 下发索引后等待2s再读取
                OnePower->>TPSU: PMBus 0x0516 写索引i
                TPSU->>Flash: 读取分档次数(深度/频率/温度)
                TPSU-->>OnePower: 返回i档位放电次数
                OnePower-->>App: 传回次数
                App->>RM310: 传递PSU[i]的次数及档位属性
                RM310->>RM310: 次数*加权系数→累加寿命裕量
                App->>App: 累积当前PSU[i]查询完成标记
            end

            RM310-->>App: 返回PSU[i]寿命裕量(取整)
        end

    end
```

### 2.1.2 内部依赖分析
<!-- 是否涉及与其他组件接口依赖，如果涉及需要确认当前是否已完成，是否匹配当前需求开发诉求 -->
不涉及

### 2.1.3 外部依赖分析
<!-- 是否涉及与平台SDK的依赖关系 -->
不涉及

### 2.1.4 北向接口分析
<!-- 需要分析当前功能是否有以下接口影响，如果有影响，则需要具体的补充影响点。其中注意点如下：
（1）如果有新增IPMI接口，请排查代码中IPMI命令注册的过滤字段，是否完全和IPMI命令的定义一致？
（2）新增一个接口时，需要咨询SIG组是否还有其他的接口受影响 -->
| 特性 | SNMP | CLI | WEB | KVM_VMM | IPMI(RMCP/RMCP+) | HMM | Redfish |
| ---- | ---- | ---- | --- | ------ | ---------------- | --- | ------- |
| 支持电源模块接触不良告警及输出欠压告警优化 | NA | NA | NA | NA | NA | NA | NA |

### 2.1.5 兼容性分析
<!-- 当前的功能对现有在网的功能是否有影响，具体的影响点进行分析之后输出影响分析表格 -->
不涉及

### 2.1.6 定制化接口分析
<!-- 如果支持定制化设置，则需要给出定制化时的默认值（空定制化项条件下的设置值），如果涉及到定制化接口变更或新增，注意定制化接口文档需配套修改。注意定制化默认值变更对白牌包的影响 -->
不涉及

### 2.1.7 导入导出分析
<!-- 如果支持导入导出的配置，则需要分析导入导出的schema。 -->
不涉及

### 2.1.8 传感器分析
<!-- 如果需要新增传感器，则需要提前登记和评审新增的传感器要素。新增传感器评审需要上SIG-Interface进行评审 -->
不涉及

### 2.1.9 精准告警事件分析
<!-- 如果需要新增事件，则需要提前登记和评审新增的时间要素 -->
不涉及

### 2.1.10 系统锁定分析
<!-- 对外的接口或者命令是否支持系统锁定 -->
不涉及

### 2.1.11 用例场景分析
<!-- 以表格的形式输出该需求涉及的用例场景 -->
|用例编号|	场景|	预期|
|---|---|---|
|1|	定时任务在PSU正常供电时查询turbo电容寿命	|成功获取全部档位放电次数并计算寿命裕量|
|2|	TPSU返回的档位组合与BMC模型不匹配	|跳过该PSU寿命预测，不记录维护日志|
|3|	获取电源放电数据失败	|重试3次后跳过该PSU，任务继续处理其它PSU|
|4|	TPSU返回的放电次数数据索引异常	|判定数据非法，跳过当前PSU，本轮不记录寿命日志|
|5|	使用电源打桩包写死放电统计数据，BMC解析寿命计算结果	|BMC解析桩包返回的次数，计算结果与预设期望一致|


## 2.2 非功能质量属性设计
### 2.2.1 扩展性分析
<!-- 考虑后续新增类似功能可以很好地扩展 -->
不涉及

### 2.2.2 重用性分析
<!-- 是否为通用处理方式、接口，如果是得考虑重用性 -->
不涉及

### 2.2.3 可测试性分析
<!-- 此需求如何验证，是否可直接验证，or通过XXX功能覆盖验证，or需要单独怎加测试接口验证 -->
可通过电源打桩包和实际环境验证

### 2.2.4 资料分析
<!-- 是否涉及资料修改 -->
不涉及

### 2.2.5 资源使用分析
<!-- 新增线程、内存分配、模型属性名长度是否合理，CPU占用率是否会激增，Flash中新增文件是否合理（频繁读写Flash会大幅缩短emmc寿命）；是否涉及消息队列，如果涉及请检查是否存在某些场景下消息队列会满导致消息丢失，例如大量消息发送到队列且处理消息需要耗费较长时间的场景。 -->
不涉及

### 2.2.6 可靠性分析
电源输出欠压告警：
| 编号 | 场景 | 问题描述 | 可靠性影响 | 问题级别 | 建议解决方案/需求 | 讨论结果 | 跟踪人 | 备注 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | BMC重启中断定时任务 | 定时任务执行到一半BMC重启，部分PSU未查询 | 部分PSU寿命预测失败 | 一般 | 重启后任务重新进行轮询预测 |  |  |  |
| 2 | TPSU通讯异常 | CanBus命令返回超时或异常码 | 单个PSU寿命无法更新 | 一般 | 对失败PSU进行重试，累计一定次数后跳过进行后续PSU预测 |  |  |  |
| 3| PSU热插拔 | 轮询过程中PSU拔掉 | 该PSU本轮预测失败 | 一般 | 任务跳过该电源继续进行后续的预测 |  |  |  |
| 4 | TPSU数据与模型不符 | TPSU获取的电源放电次数与模型不符 | 该PSU无法进行寿命预测 | 一般 | 任务跳过该电源的预测，继续进行后续电源寿命预测 |  |  |  |



### 2.2.7 安全性分析
| 安全合规项 | 是否涉及 | 现有的防护措施 |
| --- | --- | --- |
| 访问控制（通道、文件权限、用户权限、查询权限、配置权限、接口权限） | 不涉及 |  |
| 敏感数据 | 不涉及 |  |
| 日志（操作日志、维护日志、安全日志、运行日志） | 不涉及 |  |
| 文档 | 不涉及 |  |
| 加密及算法 | 不涉及 |  |
| 新增关键资源（密钥、证书、关键配置）备份、恢复 | 不涉及 |  |
| 新增对外接口入参校验 | 不涉及 |  |
| 新增开源及三方软件引入 | 不涉及 |  |
# 3.功能实现
<!-- 通过表格、流程图、简明文字描述提供，力求容易看懂、容易实现，详细描述细节。 -->
## 3.1【功能编号】支持TPSU turbo电容寿命预测
### 3.1.1 功能实现设计
**TPSU侧：**<br>
1、通过0x0515上报当前TPSU存储的最大放电档位，需要BMC侧查询所有档位数据并计算<br>
2、TPSU记录turbo电容的放电深度（考虑裕量按55v）、频率、温度分档下的放电次数。BMC侧通过0x0516命令逐次查询放电次数，<strong style = "color:red">下发索引2s后</strong>再读取放电次数<br>
3、放电次数存flash，下电后信息不丢失

**BMC侧：**<br>
1、BMC侧需要通过0x0515命令，明确需要读取多少个放电次数的数据；然后通过0x0516命令逐个查询当前TPSU的放电次数并计算，保障所有数据均全部查询完成<br>
2、寿命计算：寿命预测任务定时遍历电源，每次下发TPSU一个查询命令，TPSU上报（深度、频率、温度）下不同组合下的次数，<strong style = "color:red">BMC通过次数*加权系数得出当前寿命裕量</strong>，寿命加权后先计算，再统一取整<br>
3、寿命计算周期：每个月BMC主动定期查询一次<br>
4、升级策略：电容寿命模型修正对应加权系数同步修改，采用硬编码加权系数的方式，只需升级BMC软件即可达到升级加权系数

<strong style = "color:red">寿命公式 = 2.6亿 - Σ（充放电次数 * 加权系数）</strong><br>
计算示例（具体系数可见life_prediction_model.lua）<br>若获取的各个组合下充放电次数为1，则计算结果为2.6亿 - (1 * 组合1系数 + 1 * 组合2系数 + ......  + 1 * 组合240系数)

### 3.1.2 功能详细设计
capacitor_mgmt中增加一个电容寿命预测的定时任务，任务周期为10分钟。当距离上一次预测周期间隔1个月时，重新遍历电源进行寿命预测，对于获取数据失败的电源进行重试，失败一定次数后，跳过该电源的检测。<br>

**寿命预测流程如下：**<br>
1、capacitor_mgmt启动寿命预测定时任务<br>
2、检查距离上一次预测时间间隔是否满足1个月，若满足，继续后续流程<br>
3、capacitor_mgmt遍历电源，调用每个OnePower对象的寿命预测方法<br>
4、单个TPSU通过0x0515获取最大放电档位，判断电源是否与预测模型的匹配（返回数据的Byte2低4位表示放电深度最大档位，Byte3高4位表示放电周期最大档位，Byte3低四位表示电容温度最大档位），若不匹配则跳过该电源，不记录维护日志，继续后续电源流程<br>
5、通过0x0516依次获取每个组合（深度、频率、温度）下的放电次数，若获取失败，则进行重试（最多3次），若还是失败则跳过该电源；成功获取的数据先缓存在内存中，待该电源全部组合读取完成后再处理<br>
6、获取完所有合法数据后，根据预测模型查找对应的预置加权系数，对缓存数据统一计算寿命裕量，仅当计算成功时记录寿命维护日志<br>
7、遍历进行下一个电源的寿命预测，直到电源遍历完成；数据获取异常（含PSU拔插导致通讯失败）按重试策略处理，失败后直接跳过且不写日志<br>
**流程图：**<br>

```mermaid
flowchart TD
    Start([定时任务触发]) --> CheckCycle{距上次预测>=1个月?}
    CheckCycle -->|否| Wait([结束当前周期])
    CheckCycle -->|是| BuildList[遍历OnePower生成PSU列表]
    BuildList --> LoopPSU{还有PSU?}
    LoopPSU -->|否| Finish([全部PSU处理完毕])
    LoopPSU -->|是| Send0515[0x0515获取最大档位]
    Send0515 --> MatchModel{档位与模型匹配?}
    MatchModel -->|否| SkipModel[跳过该电源] --> LoopPSU
    MatchModel -->|是| Loop0516{组合遍历结束?}
    Loop0516 -->|是| CalcLife[按模型系数统一计算寿命]
    Loop0516 -->|否| Send0516[0x0516读取分档次数]
    Send0516 --> CheckResp{返回成功?}
    CheckResp -->|否| Retry{重试<3?}
    Retry -->|是| Send0516
    Retry -->|否| SkipFail[跳过该电源] --> LoopPSU
    CheckResp -->|是| Validate{数据合法?}
    Validate -->|否| SkipData[跳过该电源] --> LoopPSU
    Validate -->|是| Accumulate[缓存档位次数] --> Loop0516
    CalcLife --> Log[记录寿命维护日志] --> LoopPSU
```

**时序图：**<br>

```mermaid
sequenceDiagram
    participant Task as 寿命预测任务
    participant OnePower as OnePower对象
    participant TPSU as TPSU
    participant Log as 维护日志

    Task->>Task: 判断是否到达1个月周期
    alt 周期已到
        Task->>OnePower: 获取PSU列表
        loop 遍历PSU
            Task->>OnePower: 请求0x0515
            OnePower->>TPSU: 0x0515
            TPSU-->>OnePower: 返回最大档位
            OnePower-->>Task: 上报档位
            alt 档位不匹配
                Task->>Task: 跳过当前电源
            else 档位匹配
                loop 档位组合
                    Task->>OnePower: 请求0x0516
                    OnePower->>TPSU: 0x0516
                    TPSU-->>OnePower: 返回次数或异常
                    alt 响应成功
                        Task->>Task: 校验数据
                        alt 数据合法
                            Task->>Task: 缓存档位次数
                        else 数据异常
                            Task->>Task: 标记数据异常跳过并结束该PSU处理
                        end
                    else 响应失败
                        Task->>Task: 增加重试次数
                        alt 重试未超限
                            Task-->>OnePower: 继续0x0516
                        else 重试超限
                            Task->>Task: 标记通讯/PSU异常跳过并结束该PSU处理
                        end
                    end
                end
                Task->>Task: 匹配模型系数并统一计算寿命
                Task->>Log: 写入寿命维护日志
            end
        end
    else 周期未到
        Task->>Task: 等待下次调度
    end
```

**日志记录：**<br>
1、当BMC成功操作电源进行一次充放电（半年一次）后，记录电容的容量到维护日志<br>
PSU%s execute capaticors calibrate finished, capacity microfarads: %s<br>
2、当BMC成功预测电源的寿命裕量时，记录电容的寿命裕量到相应的维护日志<br>
Power supply %s predicted lifespan successful, lifespan:%s<br>
3、当进行一件收集时，将电源的放电深度+频率的次数疾苦在维护日志中<br>
PSU%s discharge count info, dod%s freq%s: %s<br>

### 3.1.3 开发者测试
<!--
增加模块接口：以活动图/流程图等形式明确模块内处理流程，针对模块处理流程中的分支进行覆盖
修改模块接口处理流程：覆盖修改影响流程分支
-->
DT设计参考：
| 组件名 | 用例类型 | 测试用例描述 | 用例名称 | 预置条件 | 操作步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- |
| firmware_mgmt | IT | 测试BMC固件更新生效状态 | test_update_bmc_active_status | 状态机为parallel_upgrading | 1.更新固件生效资源<br/>2.访问bmc.kepler.firmware_mgmt下/bmc/kepler/UpdateService/FirmwareActive/BMC接口<br/>3.查看/bmc/kepler/UpdateService/FirmwareActive中生效对象生效信息<br/>4.查看/bmc/kepler/UpdateService/FirmwareActive/BMC下bmc.kepler.UpdateService.FirmwareActiveInfo中生效信息 | 1.更新成功<br/>2.访问成功<br/>3.查询到bmc生效资源<br/>4.bmc生效信息：'FirmwareId'='BMC', 'FirmwareType'='BMC', 'ActiveStatus'='Ready' |
#### 3.1.3.1 单元测试
<!-- UT，主要是功能单元测试，测试对象是功能单元接口。UT测试设计要从黑盒（功能）角度设计，从输入(I)、处理（B）、预期输出（O）的角度进行用例分析设计，测试覆盖率仅作为反馈，用于分析哪些功能场景没有覆盖到，从而指导测试设计优化并补充测试用例 -->
| 组件名 | 用例类型 | 测试用例描述 | 用例名称 | 预置条件 | 操作步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- |
| power_mgmt | UT | 测试dump_log记录放电次数信息 | test_dump_log | dod_freq_count_map中有PSU放电数据 | 调用dump_log方法 | 正确格式化并记录维护日志，包含PSU ID、深度、频率、次数信息 |
| power_mgmt | UT | 测试dump_log空数据场景 | test_dump_log_empty | dod_freq_count_map为空 | 调用dump_log方法 | 不记录日志或记录空信息 |
| power_mgmt | UT | 测试正常计算寿命 | test_predicted_lifespan_success | psu_obj对象已初始化，model_level=0x568 | 打桩set_life_prediction_count_index和get_life_prediction_count返回成功，调用predicted_lifespan | 返回E_OK和计算出的寿命裕量，dod_freq_count_map正确更新 |
| power_mgmt | UT | 测试设置放电次数索引失败 | test_predicted_lifespan_set_index_failed | psu_obj对象已初始化 | 打桩set_life_prediction_count_index返回失败 | 返回错误信息，不继续后续流程 |
| power_mgmt | UT | 测试获取放电次数失败 | test_predicted_lifespan_get_count_failed | psu_obj对象已初始化 | 打桩get_life_prediction_count返回失败 | 返回错误信息，不继续后续流程 |
| power_mgmt | UT | 测试获取放电次数索引不匹配 | test_predicted_lifespan_index_mismatch | psu_obj对象已初始化 | 打桩get_life_prediction_count返回的index与预期不一致 | 返回E_FAILED，记录错误日志 |
| power_mgmt | UT | 测试寿命预测档位匹配场景 | test_life_prediction_execute_level_match | 多个PSU对象，model_level=0x568 | 打桩get_life_prediction_level返回0x568，predicted_lifespan返回成功 | 所有匹配的PSU都执行预测，记录维护日志 |
| power_mgmt | UT | 测试寿命预测档位不匹配跳过 | test_life_prediction_execute_level_mismatch | 多个PSU对象，model_level=0x568 | 打桩get_life_prediction_level返回0x567 | 跳过该PSU，不执行预测，记录错误日志 |
| power_mgmt | UT | 测试获取寿命预测档位失败 | test_life_prediction_execute_get_level_failed | 多个PSU对象 | 打桩get_life_prediction_level返回失败 | 跳过该PSU，不执行预测 |


#### 3.1.3.2 集成测试
<!-- IT，主要是组件/模块内的集成测试，测试对象是模块/组件接口。IT测试设计将模块/组件当作黑盒测试，IT测试用例中禁止对组件/模块内部代码打桩，如果确实有少量场景难以构造，可以考虑在测试框架中统一打桩并提供接口供测试用例调用构造场景。
说明：API测试属于IT，其测试对象是微服务接口。
PCST，是指PC上的服务集成测试，测试对象是功能需求。PCST测试设计，要覆盖正常功能、异常功能和交叉功能，采用灰盒 -->
无
