monitor: Track fan health in the System object

To prepare for being able to power off the system based on missing fans
or nonfunctional fan sensors, put a global view of this health for all
fans in the System object.  This requires now keeping track of fan
presence.

This information is stored in a map based on the fan name.  It is done
this way, as opposed to just always calling present/functional APIs on
the Fan objects, so that the code that will be using this information
can be tested in isolation without the System or Fan objects.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: Ieb1d4003bd13cebc806fd06f0064c63ea8ac6180
diff --git a/monitor/system.cpp b/monitor/system.cpp
index 9b93999..41a5750 100644
--- a/monitor/system.cpp
+++ b/monitor/system.cpp
@@ -67,6 +67,7 @@
         setTrustMgr(trustGrps);
         // Clear/set configured fan definitions
         _fans.clear();
+        _fanHealth.clear();
         setFans(fanDefs);
         log<level::INFO>("Configuration reloaded successfully");
     }
@@ -117,7 +118,26 @@
         }
         _fans.emplace_back(
             std::make_unique<Fan>(_mode, _bus, _event, _trust, fanDef, *this));
+
+        updateFanHealth(*(_fans.back()));
     }
 }
 
+void System::updateFanHealth(const Fan& fan)
+{
+    std::vector<bool> sensorStatus;
+    for (const auto& sensor : fan.sensors())
+    {
+        sensorStatus.push_back(sensor->functional());
+    }
+
+    _fanHealth[fan.getName()] =
+        std::make_tuple(fan.present(), std::move(sensorStatus));
+}
+
+void System::fanStatusChange(const Fan& fan)
+{
+    updateFanHealth(fan);
+}
+
 } // namespace phosphor::fan::monitor