点击此处查看详细分析解答
如何在代码中创建并更新 NVMeMaxTemp_0 对象供 SR 文件同步引用
您提出的问题是:在 SR 配置中,ThresholdSensor_NVMeFrontBPMaxTemp 使用了同步语法 <=/NVMeMaxTemp_0.NVMeFrontBPMaxTemp 来获取温度值,但 NVMeMaxTemp_0 这个对象并未在 MDS 模型或 mdb_interface 中定义。您希望在代码中动态创建该对象,并通过程序更新其属性(如 NVMeFrontBPMaxTemp),供 SR 中的传感器同步使用。
核心目标
- 创建一个名为
NVMeMaxTemp_0 的 MDS 对象,使其在资源树中可被访问。
- 定义其属性
NVMeFrontBPMaxTemp 和 NVMeBackBPMaxTemp。
- 在业务代码中(如 Lua 脚本)更新该对象的属性值。
- 确保 SR 文件中的
<=/NVMeMaxTemp_0.NVMeFrontBPMaxTemp 同步语法能实时感知到数值变化。
解决方案步骤详解
步骤 1:确认当前系统模型支持情况
您提到 NVMeMaxTemp_0 没有在 mds/model.json 或 mdb_interface 中定义,这意味着该对象目前未被 MDS 框架识别,不能直接用于同步。
同步语法 <=/ 的前提:被引用对象必须是一个合法的、已注册到资源树中的 MDS 对象,并具备属性变更通知机制(emit-changed)
因此,第一步就是将 NVMeMaxTemp_0 注册为一个有效的 MDS 对象。
步骤 2:在 mds/model.json 中定义 NVMeMaxTemp_0 类
在您的组件(如 my_app)的 mds/model.json 文件中,添加如下类定义:
{
"classes": {
"NVMeMaxTemp": {
"path": "/bmc/demo/NVMeMaxTemp/:Id",
"interfaces": {
"bmc.demo.NVMeMaxTemp": {
"properties": {
"NVMeFrontBPMaxTemp": {
"type": "int",
"default": 0,
"access": "readwrite",
"emits-changed": true
},
"NVMeBackBPMaxTemp": {
"type": "int",
"default": 0,
"access": "readwrite",
"emits-changed": true
}
}
}
}
}
}
}
说明:
path: 定义对象路径模板,:Id 表示实例可通过 ID 区分。
emits-changed: true: 关键配置! 表示当属性修改时,会发送 PropertiesChanged 信号,触发同步语法更新。
- 类名
NVMeMaxTemp 是类模板,生成的对象如 NVMeMaxTemp_0。
步骤 3:在 SR 文件中实例化该对象(推荐)
在您的 SR 文件(如 root.sr 或专用 .sr 文件)中,显式创建该对象实例:
"NVMeMaxTemp_0": {
"@Object": "NVMeMaxTemp",
"Id": "0",
"NVMeFrontBPMaxTemp": 0,
"NVMeBackBPMaxTemp": 0
}
这样确保对象在系统启动时就被创建,并加入资源树。
步骤 4:在代码中获取并更新对象属性(以 Lua 为例)
假设您在 my_app_app.lua 中运行逻辑,可通过以下方式获取并更新对象:
function MyApp:init()
-- 获取 NVMeMaxTemp_0 对象
local nvme_max_temp = self:get_object("/bmc/demo/NVMeMaxTemp/0")
if nvme_max_temp then
-- 假设从某个接口获取当前最大 NVMe 温度
local temp = self:get_max_nvme_temp() -- 您的业务逻辑
-- 更新属性(自动触发 PropertiesChanged 信号)
nvme_max_temp:set_property("NVMeFrontBPMaxTemp", temp)
nvme_max_temp:set_property("NVMeBackBPMaxTemp", temp)
end
end
function MyApp:get_max_nvme_temp()
-- 您的温度获取逻辑,例如读 SMbus、IPMI、或其他传感器
return 75 -- 示例值
end
set_property 会触发 D-Bus 信号,SR 中的 <=/ 同步语法会自动感知并更新。
步骤 5:SR 中传感器配置保持不变(已正确)
您已配置的 ThresholdSensor_NVMeFrontBPMaxTemp 是正确的:
"Reading": "<=/NVMeMaxTemp_0.NVMeFrontBPMaxTemp |> expr($1 > 128 ? 128 : $1)"
由于:
NVMeMaxTemp_0 是合法对象
NVMeFrontBPMaxTemp 属性启用了 emits-changed
- 使用了
<=/ 同步语法
因此,当代码中调用 set_property 时,传感器读数将自动更新。
步骤 6:验证配置是否生效
方法 1:使用 mdbctl 查看对象和属性
mdbctl lsprop NVMeMaxTemp_0
输出应包含:
bmc.demo.NVMeMaxTemp
NVMeFrontBPMaxTemp=75
NVMeBackBPMaxTemp=75
方法 2:查看传感器读数
mdbctl lsprop ThresholdSensor_NVMeFrontBPMaxTemp
确认 Reading 值是否随 NVMeMaxTemp_0 更新而变化。
方法 3:检查信号(调试)
dbus-monitor --system "interface='org.freedesktop.DBus.Properties'"
应能捕获 PropertiesChanged 信号。
附加建议
1. 命名一致性
- 建议将类命名为
NVMeMaxTemp,实例命名为 NVMeMaxTemp_0。
- 确保路径
/bmc/demo/NVMeMaxTemp/0 与 SR 文件和代码一致。
2. 默认值和边界处理
- 在
model.json 中设置合理的 default 值。
- 在表达式中做边界处理(如
> 128 ? 128 : $1),防止越界。
3. 代码健壮性
- 在调用
get_object 后判空。
- 使用定时器或事件驱动周期性更新温度。
self:register_timer(5000, function()
self:update_nvme_max_temp()
end)
总结
| 步骤 |
操作 |
说明 |
| 1 |
在 mds/model.json 中定义 NVMeMaxTemp 类 |
确保对象结构合法 |
| 2 |
在 SR 中创建 NVMeMaxTemp_0 实例 |
加入资源树 |
| 3 |
启用 emits-changed: true |
触发同步更新 |
| 4 |
在 Lua 代码中通过 get_object 获取对象 |
使用 MDS API |
| 5 |
使用 set_property 更新属性值 |
自动触发同步 |
| 6 |
SR 中使用 <=/ 同步语法 |
实现自动感知 |
只要 NVMeMaxTemp_0 是一个具备 emits-changed 的合法 MDS 对象,您就可以在代码中安全地更新其属性,并被 SR 中的传感器自动同步。
如未定义在模型中,<=/ 同步将无法感知属性变化,导致读数不变(即出现“假死”现象)。
参考知识库:
CreateMyMDSModel 用于创建 MDS 对象
emits-changed 是同步更新的关键(见 YMQMKK 案例)
model.json 定义所有可被同步的对象结构
如有需要,可提供 model.json 和 Lua 代码模板。