sensor传感器显示值的问题

sensor 中会有一个bmc.kepler.Systems.ThresholdSensorDisplay 接口里面的值展示,修改只能生效在web ,但是ipmitool 命令不生效,如果更改接口bmc.kepler.Systems.ThresholdSensor ,这里的值为只读,如果需要同时生效在web 以及ipmitool ,怎么处理尼

答案内容由AI生成,仅供参考:

:white_check_mark: 总结:如何实现“双生效”?

目标 实现方式
修改 Web 显示值 修改 CSR 中 ThresholdSensorDisplayReadingDisplay 表达式
修改 ipmitool 输出 修改 IPMI SDR 或 sensor 采集表达式
双端同步生效 从 sensor 数据源(Scanner 表达式或硬件采集逻辑)统一修改

:key: 根本原则:修改源头数据,而非展示层

点击此处查看详细分析解答

关于传感器显示值在 Web 与 IPMI 中不一致问题的解决方案

您提出的问题是:bmc.kepler.Systems.ThresholdSensorDisplay 接口中修改的传感器显示值仅在 Web 界面生效,但不影响 ipmitool sensor 命令的输出;而 bmc.kepler.Systems.ThresholdSensor 的值为只读,无法直接修改。这实际上涉及 显示层与数据源层的分离机制。以下是完整的分析与解决方案。


:magnifying_glass_tilted_left: 问题本质分析

1. 两套系统:IPMI 与 Web(Redfish/D-Bus)

  • ipmitool sensor
    调用的是 IPMI 协议栈 的 Sensor Data Record (SDR) 数据,其数据来源于 IPMI 固件层,由 BMC 的 IPMI 服务(如 ipmid)提供。
  • Web 界面
    通常基于 Redfish 或 D-Bus 接口,依赖 bmc.kepler.Systems.ThresholdSensorDisplay 这样的 D-Bus 接口进行展示,数据通过 sensor 组件解析并注册到资源协作接口。

:white_check_mark: 因此,ThresholdSensorDisplay 是一个“展示适配层”,它不对原始传感器数据做持久化修改,仅用于 Web 前端格式化输出。


2. bmc.kepler.Systems.ThresholdSensor 为何只读?

  • 该接口代表的是 底层物理或逻辑传感器的原始数据,包括:
    • 实际读数(Reading)
    • 状态(Status)
    • 单位(Unit)
    • 阈值(Thresholds)

这些值由 Scanner 模块从硬件采集,或通过 表达式计算得出,因此在运行时是动态生成且只读的,不能通过接口直接写入。


3. bmc.kepler.Systems.ThresholdSensorDisplay 的作用

根据知识库:

bmc.kepler.Systems.ThresholdSensorDisplay 是一个 D-Bus 接口类,提供显示相关的属性(如 ReadingDisplay, UpperCriticalDisplay),用于 Web 界面展示。

它的字段如:

  • ReadingDisplay
  • Status
  • Health
  • UnitDisplay

这些是展示用字段,独立于 IPMI 输出。


:pushpin: 如何实现 Web 与 ipmitool 显示一致?

要让 Web 和 ipmitool sensor 同时生效,必须从 数据源头 修改,而不是仅改展示层。


:white_check_mark: 解决方案

:white_check_mark: 方案一:修改 IPMI SDR 记录(推荐)

ipmitool sensor 输出的内容来自 Sensor Data Record (SDR) 缓存。需要通过以下方式修改:

步骤 1:确认 SDR 是否可配置

# 查看当前 SDR 列表
ipmitool sdr list

步骤 2:修改 SDR 配置(需权限与工具支持)

使用 ipmiflashsdr 工具 修改 SDR 条目。例如:

# 导出 SDR
ipmitool sdr dump sdr.bin
# 修改对应 sensor 的 display/format 属性
# 重新导入
ipmitool sdr restore sdr.bin

:warning: 风险较高,可能导致传感器不可用,请在测试环境验证。


:white_check_mark: 方案二:统一通过 CSR 配置文件 修改(推荐用于 openUBMC/iBMC)

sensor 组件在启动时会根据 CSR(Configuration Specification Resource)配置 注册 ThresholdSensorThresholdSensorDisplay

步骤 1:定位 CSR 配置文件

通常位于:

/usr/share/sensor/config/ThresholdSensor_<Name>.json

或设备树(Device Tree)中。

步骤 2:修改 Sensor 显示格式

在配置中指定 ReadingDisplay 表达式,例如:

{
  "Resource": "ThresholdSensor_ChipTemp_01",
  "Class": "bmc.kepler.Systems.ThresholdSensorDisplay",
  "Properties": {
    "ReadingDisplay": "expr($Reading * 1.1)",  // 应用缩放
    "UnitDisplay": "°C"
  }
}

:white_check_mark: 此配置影响 D-Bus 接口输出,进而影响 Web 展示。

步骤 3:同步更新 IPMI SDR 映射

确保该传感器在 IPMI 的 t_ipmi_sel_descsAllSensorItem 中有正确映射:

{
    .sensor_num = 0x0A,
    .entity_id = 0x0A, // Fan
    .sensor_type = 0x01, // Temperature
    .sdr_ptr = (void*)&sdr_temp_chip1, // 指向 SDR 记录
}

并在 SDR 中设置正确的 analog data formatscaling


:white_check_mark: 方案三:使用 ipmcset 修改传感器行为(适用于 iBMC)

# 清除 SEL 日志(影响事件判断)
ipmcset -d sel -v clear

# 设置传感器阈值(会影响 IPMI 读数状态)
ipmcset -t threshold -d set -v SensorName,UpperCritical,85

注意:ipmcset 仅能修改阈值或使能状态,不能修改读数本身。


:white_check_mark: 方案四:开发 Patch 修改 sensor 组件逻辑(高级)

如果需要在 数据采集层 修改读数(如校准、偏移),需修改 sensor 组件源码中 Scanner 的表达式:

例如:

expr: "($Scanner_Temp.Value + 0.5)"  // 增加 0.5°C 偏移

然后重新编译 sensor 组件和服务,确保:

  1. D-Bus 接口更新
  2. IPMI SDR 通过 SensorObjectManager 同步

:puzzle_piece: 附加建议:排查 ipmitool 与 Web 不一致的常见原因

可能原因 检查方式
IPMI 服务未同步最新 sensor 数据 重启 ipmid 服务:systemctl restart ipmid
sensor 组件未注册到 IPMI 桥接模块 检查 bmc.sensor.manager 是否发布 Sensor 到 IPMI
Web 缓存或前端未刷新 刷新页面或调用 redfish/v1/Chassis/1/ThresholdSensors 查看原始 API 输出
Scanner 读数异常(Status/ReadingStatus 非0) 检查 ThresholdSensorStatusReadingStatus 属性

:books: 参考知识库:ThresholdSensor 的显示受 StatusReadingStatus 控制,若为 Disabled 或非零码,将不显示。


:white_check_mark: 总结:如何实现“双生效”?

目标 实现方式
修改 Web 显示值 修改 CSR 中 ThresholdSensorDisplayReadingDisplay 表达式
修改 ipmitool 输出 修改 IPMI SDR 或 sensor 采集表达式
双端同步生效 从 sensor 数据源(Scanner 表达式或硬件采集逻辑)统一修改

:key: 根本原则:修改源头数据,而非展示层


:white_check_mark: 推荐操作流程

  1. 定位传感器名称:如 ThresholdSensor_ChipTemp_01
  2. 检查 CSR 配置文件 → 修改 ReadingDisplay
  3. 检查 IPMI SDR 配置 → 确保 SDR 映射正确
  4. 修改 scanner 表达式(如 expr($Value + offset))实现源头校正
  5. 重启 sensor 和 ipmi 服务
    systemctl restart sensor
    systemctl restart ipmid
    
  6. 验证
    • Web:查看传感器页面
    • CLI:ipmitool sensor list | grep ChipTemp
    • D-Bus:busctl get-property bmc.kepler.Systems.ThresholdSensorDisplay ReadingDisplay

如需进一步协助,请提供:

  • 传感器完整名称
  • CSR 配置片段
  • ipmitool sensor 当前输出
  • Web 显示截图

可为您精确设计配置方案。

我要实现传感器名称NVMe_F_Max_Temp ipmitool 展示和web 前端一致的问题。
最底层读值从NVMeMaxTemp_0 来,但是这个配置是没有配置。

{
“FormatVersion”: “3.00”,
“DataVersion”: “3.00”,
“Objects”: {
“DiscreteSensor_SysRestart”: {
“SensorName”: “SYS_Boot”
},
“EventDefinition_RiserOverTemp”: {
“EventName”: “RiserOverTemp”,
“ReportChannel”: 65535,
“DeassertFlag”: 1,
“EventKeyId”: “Riser.PCIeRiserOverTempMinor”,
“EventCode”: “0x0F000005”,
“ActionId”: 0,
“SeverityId”: 1,
“EventType”: 0,
“OldEventCode”: “”,
“LifeCycleId”: 1
},
“EventDescriptionEn_RiserOverTemp”: {
“EventKeyId”: “Riser.PCIeRiserOverTempMinor”,
“Suggestion”: “1. Check for fan alarms.@#AB;2. Check the equipment room temperature.@#AB;3. Check for air inlet or outlet blockage.@#AB;4. Replace the Pcie riser card.”,
“Description”: “PCIe riser card %1 temperature (%2 degrees C) exceeds the overtemperature threshold (%3 degrees C).”,
“Influence”: “”,
“Cause”: “”
},
“EventDescriptionZh_RiserOverTemp”: {
“EventKeyId”: “Riser.PCIeRiserOverTempMinor”,
“Suggestion”: “1、检查服务器是否存在风扇告警。@#AB;2、检查机房环境温度是否已超出服务器设备运行环境要求。@#AB;3、检查服务器进风口/出风口是否有异物堵塞。@#AB;4、更换PCIe Riser卡。”,
“Description”: “PCIe Riser卡%1当前温度(%2℃)高于告警门限温度(%3℃)。”,
“Influence”: “”,
“Cause”: “”
},
“NVMeMaxTemp_0”: {
“NVMeFrontBPMaxTemp”: “”,
“NVMeBackBPMaxTemp”: “”
},
“ThresholdSensor_NVMeFrontBPMaxTemp”: {
“EntityId”: “<=/Entity_MainBoard.Id”,
“EntityInstance”: “<=/Entity_MainBoard.Instance”,
“Initialization”: 127,
“Capabilities”: 232,
“SensorType”: 1,
“ReadingType”: 1,
“SensorName”: “NVMe_F_Max_Temp”,
“Unit”: 0,
“BaseUnit”: 1,
“NominalReading”: 25,
“MaximumReading”: 128,
“AssertMask”: 0,
“DeassertMask”: 0,
“ReadingMask”: 0,
“M”: 1,
“RBExp”: 0,
“Analog”: 1,
“Reading”: “<=/NVMeMaxTemp_0.NVMeFrontBPMaxTemp |> expr($1 > 128 ? 128 : $1)”,
“ReadingStatus”: “<=/NVMeMaxTemp_0.NVMeFrontBPMaxTemp |> expr($1 > 128 ? 2 : 0)”,
“SensorNumber”: 255
},
“ThresholdSensor_NVMeBackBPMaxTemp”: {
“EntityId”: “<=/Entity_MainBoard.Id”,
“EntityInstance”: “<=/Entity_MainBoard.Instance”,
“Initialization”: 127,
“Capabilities”: 232,
“SensorType”: 1,
“ReadingType”: 1,
“SensorName”: “NVMe_R_Max_Temp”,
“Unit”: 0,
“BaseUnit”: 1,
“NominalReading”: 0,
“MaximumReading”: 128,
“AssertMask”: 0,
“DeassertMask”: 0,
“ReadingMask”: 0,
“M”: 1,
“RBExp”: 0,
“Analog”: 1,
“Reading”: “<=/NVMeMaxTemp_0.NVMeBackBPMaxTemp |> expr($1 > 128 ? 128 : $1)”,
“ReadingStatus”: “<=/NVMeMaxTemp_0.NVMeBackBPMaxTemp |> expr($1 > 128 ? 2 : 0)”,
“SensorNumber”: 255
}
}
}

busctl --user introspect bmc.kepler.sensor /bmc/kepler/Systems/1/ThresholdSensors/ThresholdSensor_NVMeFrontBPMaxTemp_00 --no-pager
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
bmc.kepler.Object.Properties interface - - -
.GetAllWithContext method a{ss}s a{sv} -
.GetOptions method a{ss}ss a{ss} -
.GetPrivateProperties method a{ss} s -
.GetPropertiesByNames method a{ss}sas a{sv}a{sv} -
.GetPropertiesByOptions method a{ss}sa{ss} as -
.GetPropertyDetail method a{ss}ss s -
.GetWithContext method a{ss}ss v -
.SetWithContext method a{ss}ssv - -
.ClassName property s “ThresholdSensor” emits-change
.ObjectIdentifier property (ysss) 1 “1” “1” “00” emits-change
.ObjectName property s “ThresholdSensor_NVMeFrontBPMaxTemp_00” emits-change
.TraceSamplingRate property d 0 emits-change
bmc.kepler.Systems.ThresholdSensor interface - - -
.Capabilities property y 232 const
.EntityId property y 7 -
.EntityInstance property y 96 -
.LowerCritical property y 0 emits-change
.LowerNoncritical property y 0 emits-change
.LowerNonrecoverable property y 0 emits-change
.NegativeHysteresis property y 0 emits-change
.OriginalReading property d 0 -
.OwnerLun property y 0 emits-change
.PositiveHysteresis property y 0 emits-change
.Reading property y 0 emits-change
.ReadingMask property q 0 const
.ReadingStatus property y 0 -
.SensorIdentifier property s “” const
.SensorName property s “NVMe_F_Max_Temp” emits-change
.SensorNumber property y 2 emits-change
.SensorType property y 1 const
.UpperCritical property y 0 emits-change
.UpperNoncritical property y 0 emits-change
.UpperNonrecoverable property y 0 emits-change
bmc.kepler.Systems.ThresholdSensorDisplay interface - - -
.AssertStatus property q 0 -
.Health property s “OK” emits-change
.LowerCriticalDisplay property s “0.000” -
.LowerNoncriticalDisplay property s “0.000” -
.LowerNonrecoverableDisplay property s “0.000” -
.NegativeHysteresisDisplay property s “0.000” -
.PositiveHysteresisDisplay property s “0.000” -
.ReadingDisplay property s “0.000” writable
.Status property s “Enabled” emits-change
.UnitDisplay property s “degrees C” const
.UpperCriticalDisplay property s “0.000” -
.UpperNoncriticalDisplay property s “0.000” -
.UpperNonrecoverableDisplay property s “0.000” -
org.freedesktop.DBus.Introspectable interface - - -
.Introspect method - s -
org.freedesktop.DBus.ObjectManager interface - - -
.GetManagedObjects method - a{oa{sa{sv}}} -
org.freedesktop.DBus.Peer interface - - -
.GetMachineId method - s -
.Ping method - - -
org.freedesktop.DBus.Properties interface - - -
.Get method ss v -
.GetAll method s a{sv} -
.Set method ssv - -
.PropertiesChanged signal sa{sv}as - -
~ ~ $ busctl --user set-property bmc.kepler.sensor /bmc/kepler/Systems/1/ThresholdSensors/ThresholdSensor_NVMeFrontBPMaxTemp_00 bmc.kepler.Systems.ThresholdSensor Reading y 40 --no-pager
Failed to set property Reading on interface bmc.kepler.Systems.ThresholdSensor: {“format”:“Property Reading is read only”,“name”:“org.freedesktop.DBus.Error.PropertyReadOnly”}
~ ~ $ busctl --user set-property bmc.kepler.sensor /bmc/kepler/Systems/1/ThresholdSensors/ThresholdSensor_NVMeFrontBPMaxTemp_00 bmc.kepler.Systems.ThresholdSensorDisplay ReadingDisplay s 40.000 --no
-pager
~ ~ $

设置完ThresholdSensorDisplay ReadingDisplay 这个值web 可展示,但是ipmitool 还是0

如下:
ipmitool:

image

web:

这个怎么解决吗?

是调试场景吗?如果是调试场景,有两种方式修改:
1、使用 mdbctl 修改直接修改 Reading 属性
2、根据对象配置确认 Reading 属性关联的数据源属性,修改该数据源属性的值