Change power control match to use host state
Lower level signals were removed, use host state instead.
Also fix bug that was introduced, std::abs(nan, number)
returns nan, so checkThresholds wasn't being called.
Tested: Put in prints and saw power/post state change to on
Change-Id: I98df270237900c3a0b01c03ec7905851bc47e3b3
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/include/IpmbSensor.hpp b/include/IpmbSensor.hpp
index 1775c13..56e8b2f 100644
--- a/include/IpmbSensor.hpp
+++ b/include/IpmbSensor.hpp
@@ -41,7 +41,7 @@
std::vector<uint8_t> initData;
// to date all ipmb sensors are power on only
- PowerState readState = PowerState::on;
+ PowerState readState;
private:
sdbusplus::asio::object_server& objectServer;
diff --git a/include/Utils.hpp b/include/Utils.hpp
index f3abc7f..4f595c9 100644
--- a/include/Utils.hpp
+++ b/include/Utils.hpp
@@ -78,6 +78,23 @@
constexpr const char* get = "Get";
} // namespace properties
+namespace power
+{
+const static constexpr char* busname = "xyz.openbmc_project.State.Host";
+const static constexpr char* interface = "xyz.openbmc_project.State.Host";
+const static constexpr char* path = "/xyz/openbmc_project/state/host0";
+const static constexpr char* property = "CurrentHostState";
+} // namespace power
+namespace post
+{
+const static constexpr char* busname =
+ "xyz.openbmc_project.State.OperatingSystem";
+const static constexpr char* interface =
+ "xyz.openbmc_project.State.OperatingSystem.Status";
+const static constexpr char* path = "/xyz/openbmc_project/state/os";
+const static constexpr char* property = "OperatingSystemState";
+} // namespace post
+
template <typename T>
inline T loadVariant(
const boost::container::flat_map<std::string, BasicVariantType>& data,
@@ -103,7 +120,7 @@
}
else
{
- static_assert("Type Not Implemented");
+ static_assert(!std::is_same_v<T, T>, "Type Not Implemented");
}
}
diff --git a/include/sensor.hpp b/include/sensor.hpp
index 3ff37f7..57b9987 100644
--- a/include/sensor.hpp
+++ b/include/sensor.hpp
@@ -146,7 +146,8 @@
internalSet = true;
sensorInterface->set_property("Value", newValue);
internalSet = false;
- if (std::abs(value - newValue) > hysteresis)
+ double diff = std::abs(value - newValue);
+ if (std::isnan(diff) || diff > hysteresis)
{
value = newValue;
checkThresholds();
diff --git a/src/IpmbSensor.cpp b/src/IpmbSensor.cpp
index 5c76e8b..738ef57 100644
--- a/src/IpmbSensor.cpp
+++ b/src/IpmbSensor.cpp
@@ -61,7 +61,7 @@
"xyz.openbmc_project.Configuration.ExitAirTemp", ipmbMaxReading,
ipmbMinReading),
objectServer(objectServer), dbusConnection(conn), waitTimer(io),
- deviceAddress(deviceAddress)
+ deviceAddress(deviceAddress), readState(PowerState::on)
{
sensorInterface = objectServer.add_interface(
"/xyz/openbmc_project/sensors/temperature/" + name,
@@ -195,7 +195,7 @@
{
return; // we're being canceled
}
- if (!isPowerOn() && readState == PowerState::on)
+ if (!isPowerOn() && readState != PowerState::always)
{
updateValue(0);
read();
@@ -218,7 +218,7 @@
read();
return;
}
- if (!isPowerOn() && readState == PowerState::on)
+ if (!isPowerOn() && readState != PowerState::always)
{
updateValue(0);
read();
@@ -384,13 +384,14 @@
{
constexpr const size_t reinitWaitSeconds = 2;
std::string objectName;
- boost::container::flat_map<std::string, std::variant<int32_t>> values;
+ boost::container::flat_map<std::string, std::variant<std::string>> values;
message.read(objectName, values);
- auto findPgood = values.find("pgood");
- if (findPgood != values.end())
+ auto findStatus = values.find(power::property);
+ if (findStatus != values.end())
{
- int32_t powerStatus = std::get<int32_t>(findPgood->second);
+ bool powerStatus = boost::ends_with(
+ std::get<std::string>(findStatus->second), "Running");
if (powerStatus)
{
if (!initCmdTimer)
@@ -461,9 +462,9 @@
sdbusplus::bus::match::match powerChangeMatch(
static_cast<sdbusplus::bus::bus&>(*systemBus),
- "type='signal',interface='org.freedesktop.DBus.Properties',path_"
- "namespace='/xyz/openbmc_project/Chassis/Control/"
- "Power0',arg0='xyz.openbmc_project.Chassis.Control.Power'",
+ "type='signal',interface='" + std::string(properties::interface) +
+ "',path='" + std::string(power::path) + "',arg0='" +
+ std::string(power::interface) + "'",
reinitSensors);
io.run();
diff --git a/src/Utils.cpp b/src/Utils.cpp
index d90813d..e43d90e 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -24,15 +24,12 @@
#include <sdbusplus/bus/match.hpp>
namespace fs = std::filesystem;
-const static constexpr char* powerInterfaceName =
- "xyz.openbmc_project.Chassis.Control.Power";
-const static constexpr char* powerObjectName =
- "/xyz/openbmc_project/Chassis/Control/Power0";
static bool powerStatusOn = false;
static bool biosHasPost = false;
static std::unique_ptr<sdbusplus::bus::match::match> powerMatch = nullptr;
+static std::unique_ptr<sdbusplus::bus::match::match> postMatch = nullptr;
bool getSensorConfiguration(
const std::string& type,
@@ -122,9 +119,9 @@
bool hasBiosPost(void)
{
- if (!powerMatch)
+ if (!postMatch)
{
- throw std::runtime_error("Power Match Not Created");
+ throw std::runtime_error("Post Match Not Created");
}
return biosHasPost;
}
@@ -133,57 +130,75 @@
{
// create a match for powergood changes, first time do a method call to
// cache the correct value
- std::function<void(sdbusplus::message::message & message)> eventHandler =
- [](sdbusplus::message::message& message) {
- std::string objectName;
- boost::container::flat_map<std::string, std::variant<int32_t, bool>>
- values;
- message.read(objectName, values);
- auto findPgood = values.find("pgood");
- if (findPgood != values.end())
- {
- powerStatusOn = std::get<int32_t>(findPgood->second);
- }
- auto findPostComplete = values.find("post_complete");
- if (findPostComplete != values.end())
- {
- biosHasPost = std::get<bool>(findPostComplete->second);
- }
- };
+ if (powerMatch)
+ {
+ return;
+ }
powerMatch = std::make_unique<sdbusplus::bus::match::match>(
static_cast<sdbusplus::bus::bus&>(*conn),
- "type='signal',interface='org.freedesktop.DBus.Properties',path_"
- "namespace='/xyz/openbmc_project/Chassis/Control/"
- "Power0',arg0='xyz.openbmc_project.Chassis.Control.Power'",
- eventHandler);
-
- conn->async_method_call(
- [](boost::system::error_code ec, const std::variant<int32_t>& pgood) {
- if (ec)
+ "type='signal',interface='" + std::string(properties::interface) +
+ "',path='" + std::string(power::path) + "',arg0='" +
+ std::string(power::interface) + "'",
+ [](sdbusplus::message::message& message) {
+ std::string objectName;
+ boost::container::flat_map<std::string, std::variant<std::string>>
+ values;
+ message.read(objectName, values);
+ auto findState = values.find(power::property);
+ if (findState != values.end())
{
- // we commonly come up before power control, we'll capture the
- // property change later
- return;
+ powerStatusOn = boost::ends_with(
+ std::get<std::string>(findState->second), "Running");
}
- powerStatusOn = std::get<int32_t>(pgood);
- },
- powerInterfaceName, powerObjectName, "org.freedesktop.DBus.Properties",
- "Get", powerInterfaceName, "pgood");
+ });
+
+ postMatch = std::make_unique<sdbusplus::bus::match::match>(
+ static_cast<sdbusplus::bus::bus&>(*conn),
+ "type='signal',interface='" + std::string(properties::interface) +
+ "',path='" + std::string(post::path) + "',arg0='" +
+ std::string(post::interface) + "'",
+ [](sdbusplus::message::message& message) {
+ std::string objectName;
+ boost::container::flat_map<std::string, std::variant<std::string>>
+ values;
+ message.read(objectName, values);
+ auto findState = values.find(post::property);
+ if (findState != values.end())
+ {
+ biosHasPost =
+ std::get<std::string>(findState->second) != "Inactive";
+ }
+ });
conn->async_method_call(
[](boost::system::error_code ec,
- const std::variant<int32_t>& postComplete) {
+ const std::variant<std::string>& state) {
if (ec)
{
// we commonly come up before power control, we'll capture the
// property change later
return;
}
- biosHasPost = std::get<int32_t>(postComplete);
+ powerStatusOn =
+ boost::ends_with(std::get<std::string>(state), "Running");
},
- powerInterfaceName, powerObjectName, "org.freedesktop.DBus.Properties",
- "Get", powerInterfaceName, "post_complete");
+ power::busname, power::path, properties::interface, properties::get,
+ power::interface, power::property);
+
+ conn->async_method_call(
+ [](boost::system::error_code ec,
+ const std::variant<std::string>& state) {
+ if (ec)
+ {
+ // we commonly come up before power control, we'll capture the
+ // property change later
+ return;
+ }
+ biosHasPost = std::get<std::string>(state) != "Inactive";
+ },
+ post::busname, post::path, properties::interface, properties::get,
+ post::interface, post::property);
}
// replaces limits if MinReading and MaxReading are found.