Add LED Support to Fan Sensor
This allows the fan sensor to trip an LED when a critical
threshold is crossed.
Tested: Saw LED d-bus object in Group manager get set
using sensor override
Change-Id: Iab5a69ded20de6e3ac99e9ac687c60605d5763d1
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/include/TachSensor.hpp b/include/TachSensor.hpp
index af39d0c..1e5347f 100644
--- a/include/TachSensor.hpp
+++ b/include/TachSensor.hpp
@@ -73,7 +73,8 @@
std::vector<thresholds::Threshold>&& thresholds,
const std::string& sensorConfiguration,
const std::pair<size_t, size_t>& limits,
- const PowerState& powerState = PowerState::on);
+ const PowerState& powerState,
+ const std::optional<std::string>& led);
~TachSensor();
private:
@@ -86,6 +87,8 @@
boost::asio::deadline_timer waitTimer;
boost::asio::streambuf readBuf;
std::string path;
+ std::optional<std::string> led;
+ bool ledState = false;
size_t errCount;
void setupRead(void);
void handleResponse(const boost::system::error_code& err);
diff --git a/include/Utils.hpp b/include/Utils.hpp
index 2c6ce9e..7f529e1 100644
--- a/include/Utils.hpp
+++ b/include/Utils.hpp
@@ -81,6 +81,7 @@
{
constexpr const char* interface = "org.freedesktop.DBus.Properties";
constexpr const char* get = "Get";
+constexpr const char* set = "Set";
} // namespace properties
namespace power
@@ -152,6 +153,22 @@
}
}
+inline void setLed(std::shared_ptr<sdbusplus::asio::connection> conn,
+ const std::string& name, bool on)
+{
+ conn->async_method_call(
+ [name](const boost::system::error_code ec) {
+ if (ec)
+ {
+ std::cerr << "Failed to set LED " << name << "\n";
+ }
+ },
+ "xyz.openbmc_project.LED.GroupManager",
+ "/xyz/openbmc_project/led/groups/" + name, properties::interface,
+ properties::set, "xyz.openbmc_project.Led.Group", "Asserted",
+ std::variant<bool>(on));
+}
+
void createInventoryAssoc(
std::shared_ptr<sdbusplus::asio::connection> conn,
std::shared_ptr<sdbusplus::asio::dbus_interface> association,
diff --git a/src/FanMain.cpp b/src/FanMain.cpp
index 0454706..232144f 100644
--- a/src/FanMain.cpp
+++ b/src/FanMain.cpp
@@ -366,40 +366,63 @@
auto limits =
std::make_pair(defaultMinReading, defaultMaxReading);
+ auto connector =
+ sensorData->find(baseType + std::string(".Connector"));
+
+ std::optional<std::string> led;
+
+ if (connector != sensorData->end())
+ {
+ auto findPwm = connector->second.find("Pwm");
+ if (findPwm != connector->second.end())
+ {
+
+ size_t pwm = std::visit(VariantToUnsignedIntVisitor(),
+ findPwm->second);
+ /* use pwm name override if found in configuration else
+ * use default */
+ auto findOverride = connector->second.find("PwmName");
+ std::string pwmName;
+ if (findOverride != connector->second.end())
+ {
+ pwmName = std::visit(VariantToStringVisitor(),
+ findOverride->second);
+ }
+ else
+ {
+ pwmName = "Pwm_" + std::to_string(pwm + 1);
+ }
+ pwmNumbers.emplace_back(pwm, *interfacePath, pwmName);
+ }
+ else
+ {
+ std::cerr << "Connector for " << sensorName
+ << " missing pwm!\n";
+ }
+
+ auto findLED = connector->second.find("LED");
+ if (findLED != connector->second.end())
+ {
+ auto ledName =
+ std::get_if<std::string>(&(findLED->second));
+ if (ledName == nullptr)
+ {
+ std::cerr << "Wrong format for LED of "
+ << sensorName << "\n";
+ }
+ else
+ {
+ led = *ledName;
+ }
+ }
+ }
+
findLimits(limits, baseConfiguration);
tachSensors[sensorName] = std::make_unique<TachSensor>(
path.string(), baseType, objectServer, dbusConnection,
std::move(presenceSensor), redundancy, io, sensorName,
std::move(sensorThresholds), *interfacePath, limits,
- powerState);
-
- auto connector =
- sensorData->find(baseType + std::string(".Connector"));
- if (connector != sensorData->end())
- {
- auto findPwm = connector->second.find("Pwm");
- if (findPwm == connector->second.end())
- {
- std::cerr << "Connector Missing PWM!\n";
- continue;
- }
- size_t pwm = std::visit(VariantToUnsignedIntVisitor(),
- findPwm->second);
- /* use pwm name override if found in configuration else use
- * default */
- auto findOverride = connector->second.find("PwmName");
- std::string pwmName;
- if (findOverride != connector->second.end())
- {
- pwmName = std::visit(VariantToStringVisitor(),
- findOverride->second);
- }
- else
- {
- pwmName = "Pwm_" + std::to_string(pwm + 1);
- }
- pwmNumbers.emplace_back(pwm, *interfacePath, pwmName);
- }
+ powerState, led);
}
createRedundancySensor(tachSensors, dbusConnection, objectServer);
std::vector<fs::path> pwms;
diff --git a/src/TachSensor.cpp b/src/TachSensor.cpp
index d39e92c..0490135 100644
--- a/src/TachSensor.cpp
+++ b/src/TachSensor.cpp
@@ -51,13 +51,15 @@
std::vector<thresholds::Threshold>&& _thresholds,
const std::string& sensorConfiguration,
const std::pair<size_t, size_t>& limits,
- const PowerState& powerState) :
+ const PowerState& powerState,
+ const std::optional<std::string>& ledIn) :
Sensor(boost::replace_all_copy(fanName, " ", "_"), std::move(_thresholds),
sensorConfiguration, objectType, limits.second, limits.first, conn,
powerState),
objServer(objectServer), redundancy(redundancy),
presence(std::move(presenceSensor)),
- inputDev(io, open(path.c_str(), O_RDONLY)), waitTimer(io), path(path)
+ inputDev(io, open(path.c_str(), O_RDONLY)), waitTimer(io), path(path),
+ led(ledIn)
{
sensorInterface = objectServer.add_interface(
"/xyz/openbmc_project/sensors/fan_tach/" + name,
@@ -192,6 +194,13 @@
(*redundancy)
->update("/xyz/openbmc_project/sensors/fan_tach/" + name, !status);
}
+
+ bool curLed = !status;
+ if (led && ledState != curLed)
+ {
+ ledState = curLed;
+ setLed(dbusConnection, *led, curLed);
+ }
}
PresenceSensor::PresenceSensor(const std::string& gpioName, bool inverted,