monitor: Support target_path option in configuration file
The target path containing the interface
xyz.openbmc_project.control.FanPwm or
xyz.openbmc_project.control.FanSpeed can be different between
phosphor-hwmon and dbus-sensor.
In phosphor-hwmon, it is "/xyz/openbmc_project/sensors/fan_tach/".
In dbus-sensor, it is "/xyz/openbmc_project/control/fanpwm/".
This commit supports making this path configurable via "target_path"
as a full object path.
By default, it is the same as the fan tach object path.
Signed-off-by: Chau Ly <chaul@amperecomputing.com>
Change-Id: I2658a462dd49a98ad77d684f2927e6ccae21cd15
diff --git a/docs/monitor/sensors.md b/docs/monitor/sensors.md
index 99c6a75..b6555ee 100644
--- a/docs/monitor/sensors.md
+++ b/docs/monitor/sensors.md
@@ -17,6 +17,8 @@
* Whether this sensor D-Bus object contains the `Target` property or not.
* `target_interface` - string (Optional)
* The D-Bus interface containing the `Target` property. This defaults to `xyz.openbmc_project.Control.FanSpeed` for RPM controlled fans or can be set to `xyz.openbmc_project.Control.FanPwm` for PWM controlled fans.
+* `target_path` - string (Optional)
+ * The D-Bus full object path containing the `Target` property. This defaults to `/xyz/openbmc_project/sensors/fan_tach`+`name`.
* `factor` - double (Optional)
* A value to multiply the current target by to adjust the monitoring of this sensor due to how the hardware works. This sensor attribute is optional and defaults to 1.0.
* `offset` - integer (Optional)
@@ -39,7 +41,8 @@
{
"name": "fan0_0",
"has_target": true,
- "target_interface": "xyz.openbmc_project.Control.FanPwm"
+ "target_interface": "xyz.openbmc_project.Control.FanPwm",
+ "target_path": "/xyz/openbmc_project/control/fanpwm/PWM0"
},
{
"name": "fan0_1",
diff --git a/monitor/example/monitor.yaml b/monitor/example/monitor.yaml
index 8d70c4f..14fce2c 100644
--- a/monitor/example/monitor.yaml
+++ b/monitor/example/monitor.yaml
@@ -28,6 +28,10 @@
# setting a fan speed (otherwise just for reads)]
# target_interface [The fan target interface used by the sensor.
# Default is "xyz.openbmc_project.Control.FanSpeed"]
+# target_path [The full target path, which implements
+# xyz.openbmc_project.Control.FanSpeed or
+# xyz.openbmc_project.Control.FanPwm interface.
+# Default is /xyz/openbmc_project/sensors/fan_tach/*"]
# factor [The factor to multiply with target to calculate the expected
# fan speed. Default is 1 for fan speed target;
# Customized value for pwm target]
diff --git a/monitor/fan.cpp b/monitor/fan.cpp
index 910d975..94bfcf8 100644
--- a/monitor/fan.cpp
+++ b/monitor/fan.cpp
@@ -69,10 +69,10 @@
_sensors.emplace_back(std::make_shared<TachSensor>(
mode, bus, *this, std::get<sensorNameField>(s),
std::get<hasTargetField>(s), std::get<funcDelay>(def),
- std::get<targetInterfaceField>(s), std::get<factorField>(s),
- std::get<offsetField>(s), std::get<methodField>(def),
- std::get<thresholdField>(s), std::get<ignoreAboveMaxField>(s),
- std::get<timeoutField>(def),
+ std::get<targetInterfaceField>(s), std::get<targetPathField>(s),
+ std::get<factorField>(s), std::get<offsetField>(s),
+ std::get<methodField>(def), std::get<thresholdField>(s),
+ std::get<ignoreAboveMaxField>(s), std::get<timeoutField>(def),
std::get<nonfuncRotorErrDelayField>(def),
std::get<countIntervalField>(def), event));
diff --git a/monitor/gen-fan-monitor-defs.py b/monitor/gen-fan-monitor-defs.py
index c771109..1118e83 100755
--- a/monitor/gen-fan-monitor-defs.py
+++ b/monitor/gen-fan-monitor-defs.py
@@ -67,6 +67,9 @@
target_interface = sensor.get(
'target_interface',
'xyz.openbmc_project.Control.FanSpeed')
+ target_path = sensor.get(
+ 'target_path',
+ '')
factor = sensor.get('factor', 1)
offset = sensor.get('offset', 0)
threshold = sensor.get('threshold', 1)
@@ -76,6 +79,7 @@
SensorDefinition{"${sensor['name']}",
${has_target},
"${target_interface}",
+ "${target_path}",
${factor},
${offset},
${threshold},
diff --git a/monitor/json_parser.cpp b/monitor/json_parser.cpp
index 1144998..e3d23d9 100644
--- a/monitor/json_parser.cpp
+++ b/monitor/json_parser.cpp
@@ -146,6 +146,12 @@
{
targetIntf = sensor["target_interface"].get<std::string>();
}
+ // Target path is optional
+ std::string targetPath;
+ if (sensor.contains("target_path"))
+ {
+ targetPath = sensor["target_path"].get<std::string>();
+ }
// Factor is optional and defaults to 1
auto factor = 1.0;
if (sensor.contains("factor"))
@@ -173,7 +179,7 @@
sensorDefs.emplace_back(std::tuple(
sensor["name"].get<std::string>(), sensor["has_target"].get<bool>(),
- targetIntf, factor, offset, threshold, ignoreAboveMax));
+ targetIntf, targetPath, factor, offset, threshold, ignoreAboveMax));
}
return sensorDefs;
diff --git a/monitor/tach_sensor.cpp b/monitor/tach_sensor.cpp
index 825faac..f5a7238 100644
--- a/monitor/tach_sensor.cpp
+++ b/monitor/tach_sensor.cpp
@@ -73,14 +73,14 @@
TachSensor::TachSensor([[maybe_unused]] Mode mode, sdbusplus::bus_t& bus,
Fan& fan, const std::string& id, bool hasTarget,
size_t funcDelay, const std::string& interface,
- double factor, int64_t offset, size_t method,
- size_t threshold, bool ignoreAboveMax, size_t timeout,
- const std::optional<size_t>& errorDelay,
+ const std::string& path, double factor, int64_t offset,
+ size_t method, size_t threshold, bool ignoreAboveMax,
+ size_t timeout, const std::optional<size_t>& errorDelay,
size_t countInterval, const sdeventplus::Event& event) :
_bus(bus),
_fan(fan), _name(FAN_SENSOR_PATH + id),
_invName(fs::path(fan.getName()) / id), _hasTarget(hasTarget),
- _funcDelay(funcDelay), _interface(interface), _factor(factor),
+ _funcDelay(funcDelay), _interface(interface), _path(path), _factor(factor),
_offset(offset), _method(method), _threshold(threshold),
_ignoreAboveMax(ignoreAboveMax), _timeout(timeout),
_timerMode(TimerMode::func),
@@ -111,7 +111,7 @@
// object can be functional with a missing D-bus sensor.
}
- auto match = getMatchString(util::FAN_SENSOR_VALUE_INTF);
+ auto match = getMatchString(std::nullopt, util::FAN_SENSOR_VALUE_INTF);
tachSignal = std::make_unique<sdbusplus::bus::match_t>(
_bus, match.c_str(),
@@ -119,8 +119,14 @@
if (_hasTarget)
{
- match = getMatchString(_interface);
-
+ if (_path.empty())
+ {
+ match = getMatchString(std::nullopt, _interface);
+ }
+ else
+ {
+ match = getMatchString(_path, _interface);
+ }
targetSignal = std::make_unique<sdbusplus::bus::match_t>(
_bus, match.c_str(),
[this](auto& msg) { this->handleTargetChange(msg); });
@@ -153,7 +159,17 @@
if (_hasTarget)
{
- readProperty(_interface, FAN_TARGET_PROPERTY, _name, _bus, _tachTarget);
+ if (_path.empty())
+ {
+ // Target path is optional
+ readProperty(_interface, FAN_TARGET_PROPERTY, _name, _bus,
+ _tachTarget);
+ }
+ else
+ {
+ readProperty(_interface, FAN_TARGET_PROPERTY, _path, _bus,
+ _tachTarget);
+ }
// record previous target value
if (_prevTargets.front() != _tachTarget)
@@ -170,8 +186,14 @@
_prevTachs.pop_back();
}
-std::string TachSensor::getMatchString(const std::string& interface)
+std::string TachSensor::getMatchString(const std::optional<std::string> path,
+ const std::string& interface)
{
+ if (path)
+ {
+ return sdbusplus::bus::match::rules::propertiesChanged(path.value(),
+ interface);
+ }
return sdbusplus::bus::match::rules::propertiesChanged(_name, interface);
}
diff --git a/monitor/tach_sensor.hpp b/monitor/tach_sensor.hpp
index 30e9129..875c578 100644
--- a/monitor/tach_sensor.hpp
+++ b/monitor/tach_sensor.hpp
@@ -93,6 +93,7 @@
* setting the speed
* @param[in] funcDelay - Delay to mark functional
* @param[in] interface - the interface of the target
+ * @param[in] path - the object path of the sensor target
* @param[in] factor - the factor of the sensor target
* @param[in] offset - the offset of the sensor target
* @param[in] method - the method of out of range
@@ -107,10 +108,11 @@
*/
TachSensor(Mode mode, sdbusplus::bus_t& bus, Fan& fan,
const std::string& id, bool hasTarget, size_t funcDelay,
- const std::string& interface, double factor, int64_t offset,
- size_t method, size_t threshold, bool ignoreAboveMax,
- size_t timeout, const std::optional<size_t>& errorDelay,
- size_t countInterval, const sdeventplus::Event& event);
+ const std::string& interface, const std::string& path,
+ double factor, int64_t offset, size_t method, size_t threshold,
+ bool ignoreAboveMax, size_t timeout,
+ const std::optional<size_t>& errorDelay, size_t countInterval,
+ const sdeventplus::Event& event);
/**
* @brief Reads a property from the input message and stores it in value.
@@ -386,7 +388,8 @@
* @brief Returns the match string to use for matching
* on a properties changed signal.
*/
- std::string getMatchString(const std::string& interface);
+ std::string getMatchString(const std::optional<std::string> path,
+ const std::string& interface);
/**
* @brief Reads the Target property and stores in _tachTarget.
@@ -462,6 +465,11 @@
const std::string _interface;
/**
+ * @brief The object path to set sensor's target
+ */
+ const std::string _path;
+
+ /**
* @brief The factor of target to get fan rpm
*/
const double _factor;
diff --git a/monitor/types.hpp b/monitor/types.hpp
index 9c0d57f..740f069 100644
--- a/monitor/types.hpp
+++ b/monitor/types.hpp
@@ -105,13 +105,14 @@
constexpr auto sensorNameField = 0;
constexpr auto hasTargetField = 1;
constexpr auto targetInterfaceField = 2;
-constexpr auto factorField = 3;
-constexpr auto offsetField = 4;
-constexpr auto thresholdField = 5;
-constexpr auto ignoreAboveMaxField = 6;
+constexpr auto targetPathField = 3;
+constexpr auto factorField = 4;
+constexpr auto offsetField = 5;
+constexpr auto thresholdField = 6;
+constexpr auto ignoreAboveMaxField = 7;
-using SensorDefinition =
- std::tuple<std::string, bool, std::string, double, int64_t, size_t, bool>;
+using SensorDefinition = std::tuple<std::string, bool, std::string, std::string,
+ double, int64_t, size_t, bool>;
constexpr auto fanNameField = 0;
constexpr auto methodField = 1;