monitor: Allow missing D-Bus sensors on startup

Now that phosphor-fan-monitor is starting at the multi-user target, it
may be starting before the fan sensor hwmon daemon is able to put the
tach reading sensors on D-Bus.  This was causing the TachSensor class
objects to not get created so even if the hwmon tach sensor values did
show up later on D-Bus fan monitor wouldn't notice them.

To fix this, still create the TachSensor objects if the corresponding
hwmon D-Bus objects aren't there, and still set them to functional in
the inventory so that any other monitoring code, such as
phosphor-dbus-monitor, won't shut down the system before the hwmon tach
sensors get a chance to show up on D-Bus, which was happening on
witherspoon when a reboot was done with the power on.

When the monitor delay timer expires to kick off monitoring, a D-Bus
read is forced, and if the hwmon sensors still aren't on D-Bus then the
corresponding TachSensor objects will be set to nonfunctional to start
down the error paths.

Also, when the power state changes to on, instead of blindly setting all
TachSensor objects to functional, again check if their hwmon sensor
values are on D-Bus before doing so.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I3e62727296630bf68602b0472328f4613e1a78e3
diff --git a/monitor/tach_sensor.cpp b/monitor/tach_sensor.cpp
index 95d52b2..96fc06b 100644
--- a/monitor/tach_sensor.cpp
+++ b/monitor/tach_sensor.cpp
@@ -92,25 +92,12 @@
 #endif
         try
         {
-            // Use getProperty directly to allow a missing sensor object
-            // to abort construction.
-            _tachInput = util::SDBusPlus::getProperty<decltype(_tachInput)>(
-                _bus, _name, FAN_SENSOR_VALUE_INTF, FAN_VALUE_PROPERTY);
+            updateTachAndTarget();
         }
-        catch (std::exception& e)
+        catch (const std::exception& e)
         {
-            log<level::ERR>(
-                fmt::format("Failed to retrieve tach sensor {}", _name)
-                    .c_str());
-            // Mark tach sensor as nonfunctional
-            setFunctional(false);
-            throw InvalidSensorError();
-        }
-
-        if (_hasTarget)
-        {
-            readProperty(_interface, FAN_TARGET_PROPERTY, _name, _bus,
-                         _tachTarget);
+            // Until the parent Fan's monitor-ready timer expires, the
+            // object can be functional with a missing D-bus sensor.
         }
 
         auto match = getMatchString(FAN_SENSOR_VALUE_INTF);
@@ -140,6 +127,17 @@
 #endif
 }
 
+void TachSensor::updateTachAndTarget()
+{
+    _tachInput = util::SDBusPlus::getProperty<decltype(_tachInput)>(
+        _bus, _name, FAN_SENSOR_VALUE_INTF, FAN_VALUE_PROPERTY);
+
+    if (_hasTarget)
+    {
+        readProperty(_interface, FAN_TARGET_PROPERTY, _name, _bus, _tachTarget);
+    }
+}
+
 std::string TachSensor::getMatchString(const std::string& interface)
 {
     return sdbusplus::bus::match::rules::propertiesChanged(_name, interface);