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.