Add StandbyOffline to Redfish sensor getState

Currently in Redfish a sensor's state will only be "Absent" or
"Enabled".  In the case where a sensor is marked as not available on
D-Bus it would be more accurate and informative to have the state as
"StandbyOffline".  A sensor's availability will be published on its
xyz.openbmc_project.State.Decorator.Availability interface.

Tested on Intel system.  Put sensors into an unavailable state by
putting CPU into S5 power state, and verified that Redfish state is
"StandbyOffline".  Then when sensors are back in an available state
their Redfish state is back to "Enabled".

Change-Id: I4b846b678a0f90f60d182ac38f1becd21265cdd2
Signed-off-by: Matt Simmering <matthew.simmering@intel.com>
diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp
index 1935adc..fbc89a0 100644
--- a/redfish-core/lib/sensors.hpp
+++ b/redfish-core/lib/sensors.hpp
@@ -18,6 +18,7 @@
 #include "app.hpp"
 #include "dbus_singleton.hpp"
 #include "dbus_utility.hpp"
+#include "generated/enums/resource.hpp"
 #include "generated/enums/sensor.hpp"
 #include "query.hpp"
 #include "registries/privilege_registry.hpp"
@@ -591,16 +592,24 @@
 /**
  * @brief Returns the Redfish State value for the specified inventory item.
  * @param inventoryItem D-Bus inventory item associated with a sensor.
+ * @param sensorAvailable Boolean representing if D-Bus sensor is marked as
+ * available.
  * @return State value for inventory item.
  */
-inline std::string getState(const InventoryItem* inventoryItem)
+inline resource::State getState(const InventoryItem* inventoryItem,
+                                const bool sensorAvailable)
 {
     if ((inventoryItem != nullptr) && !(inventoryItem->isPresent))
     {
-        return "Absent";
+        return resource::State::Absent;
     }
 
-    return "Enabled";
+    if (!sensorAvailable)
+    {
+        return resource::State::UnavailableOffline;
+    }
+
+    return resource::State::Enabled;
 }
 
 /**
@@ -753,7 +762,21 @@
         sensorJson["Name"] = std::move(sensorNameEs);
     }
 
-    sensorJson["Status"]["State"] = getState(inventoryItem);
+    const bool* checkAvailable = nullptr;
+    bool available = true;
+    const bool success = sdbusplus::unpackPropertiesNoThrow(
+        dbus_utils::UnpackErrorPrinter(), propertiesDict, "Available",
+        checkAvailable);
+    if (!success)
+    {
+        messages::internalError();
+    }
+    if (checkAvailable != nullptr)
+    {
+        available = *checkAvailable;
+    }
+
+    sensorJson["Status"]["State"] = getState(inventoryItem, available);
     sensorJson["Status"]["Health"] = getHealth(sensorJson, propertiesDict,
                                                inventoryItem);
 
@@ -2228,7 +2251,7 @@
             inventoryItem.powerSupplyEfficiencyPercent;
     }
 
-    powerSupply["Status"]["State"] = getState(&inventoryItem);
+    powerSupply["Status"]["State"] = getState(&inventoryItem, true);
     const char* health = inventoryItem.isFunctional ? "OK" : "Critical";
     powerSupply["Status"]["Health"] = health;