monitor: Add delay for host control

Some OpenBMC platforms use dbus-sensor and entity-manager to create
the fan sensors. In those systems, phosphor-fan-monitor starts before
the fan sensors are created during BMC boot up. phosphor-fan-monitor
is designed to shutdown the host when there is no fan tach sensors which
is not desirable in this case. This patch supports a package
configuration option delay-host-control to add a desired delay before
phosphor-fan-monitor turns off host. This can be configured to match
with each system timing.

Signed-off-by: Chau Ly <chaul@amperecomputing.com>
Change-Id: I63cd85eb5e6cb04069ce7b4c21c2f4621d243502
diff --git a/meson.build b/meson.build
index 0307a1f..7ede5c5 100644
--- a/meson.build
+++ b/meson.build
@@ -95,6 +95,7 @@
     'NUM_MONITOR_LOG_ENTRIES', get_option('num-monitor-log-entries'))
 conf.set_quoted(
     'FAN_MONITOR_YAML_FILE', get_option('fan-monitor-yaml-file'))
+conf.set('DELAY_HOST_CONTROL', get_option('delay-host-control'))
 
 # JSON-or-YAML (all programs)
 if get_option('json-config').enabled()
diff --git a/meson_options.txt b/meson_options.txt
index 718ca7f..93681c8 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -67,6 +67,11 @@
     description: 'Maximum number of entries in the monitor log.'
 )
 
+option(
+    'delay-host-control', value : '0', type: 'integer',
+    description: 'Delay host control when the power is on and the fan sensors are offline.'
+)
+
 # Presence
 
 option(
diff --git a/monitor/system.cpp b/monitor/system.cpp
index bcd9e33..6408ef4 100644
--- a/monitor/system.cpp
+++ b/monitor/system.cpp
@@ -377,8 +377,23 @@
                 return fan->numSensorsOnDBusAtPowerOn() == 0;
             }))
         {
+#if DELAY_HOST_CONTROL > 0
+            sleep(DELAY_HOST_CONTROL);
+            std::for_each(_fans.begin(), _fans.end(),
+                          [powerStateOn](auto& fan) {
+                              fan->powerStateChanged(powerStateOn);
+                          });
+            if (std::all_of(_fans.begin(), _fans.end(), [](const auto& fan) {
+                    return fan->numSensorsOnDBusAtPowerOn() == 0;
+                }))
+            {
+                handleOfflineFanController();
+                return;
+            }
+#else
             handleOfflineFanController();
             return;
+#endif
         }
 
         if (_sensorMatch.empty())