Auto determine failsafe duty according sensor fail

- Auto determine the failsafe duty when sensor failed

example:
If PID config as follows, when "Die CPU0" sensor failed, fans in zone 0
will be set to 80%, when "DIMM0" sensor failed, since there is no
"FailSafePercent" setting in config, so set to zone's FailSafePercent
100%.
```
{
    "Class": "temp",
    ...
    ...
    ...
    "Inputs": [
        "Die CPU0"
    ],
    "Name": "CPU0 PID",
    "FailSafePercent": 80.0,
    ...
    ...
    ...
    "Type": "Pid",
    "Zones": [
        "Zone 0"
    ]
},
{
    "Class": "temp",
    ...
    ...
    ...
    "Inputs": [
        "DIMM[0-9]",
        "DIMM1[0-5]"
    ],
    "Name": "DIMM CPU0 PID",
    ...
    ...
    ...
    "Type": "Pid",
    "Zones": [
        "Zone 0"
    ]
},
{
    "FailSafePercent": 100.0,
    "MinThermalOutput": 0.0,
    "Name": "Zone 0",
    "Type": "Pid.Zone",
    "ZoneIndex": 0
},
```

Tested:
If zone1 and zone2 into failsafe duty 40% =>
fan0_pwm         | 1Dh | ok  | 29.0 | 24.70 unspecifi
fan1_pwm         | 1Eh | ok  | 29.1 | 24.70 unspecifi
fan2_pwm         | 1Fh | ok  | 29.2 | 39.98 unspecifi
fan3_pwm         | 20h | ok  | 29.3 | 39.98 unspecifi
fan4_pwm         | 21h | ok  | 29.4 | 39.98 unspecifi
fan5_pwm         | 22h | ok  | 29.5 | 39.98 unspecifi

cpu0_nbm         | 48h | ok  |  7.79 | 36 degrees C

Let cpu0_nbm(zone0 and zone2) into failsafe which set failsafe duty as
100% =>
fan0_pwm         | 1Dh | ok  | 29.0 | 99.96 unspecifi
fan1_pwm         | 1Eh | ok  | 29.1 | 99.96 unspecifi
fan2_pwm         | 1Fh | ok  | 29.2 | 39.98 unspecifi
fan3_pwm         | 20h | ok  | 29.3 | 39.98 unspecifi
fan4_pwm         | 21h | ok  | 29.4 | 99.96 unspecifi
fan5_pwm         | 22h | ok  | 29.5 | 99.96 unspecifi

cpu0_nbm         | 48h | ns  |  7.79 | No Reading

Signed-off-by: Harvey Wu <Harvey.Wu@quantatw.com>
Change-Id: Iaf5ffd1853e5cd110a1ef66c7a1fd073bc894dda
diff --git a/pid/zone.cpp b/pid/zone.cpp
index 39ddc6d..901905d 100644
--- a/pid/zone.cpp
+++ b/pid/zone.cpp
@@ -104,7 +104,19 @@
         return;
     }
 
-    _failSafeSensors.emplace(name);
+    if (_sensorFailSafePercent[name] == 0)
+    {
+        _failSafeSensors[name] = _zoneFailSafePercent;
+    }
+    else
+    {
+        _failSafeSensors[name] = _sensorFailSafePercent[name];
+    }
+
+    if (debugEnabled)
+    {
+        std::cerr << "Sensor " << name << " marked missing\n";
+    }
 }
 
 int64_t DbusPidZone::getZoneID(void) const
@@ -166,9 +178,27 @@
     _maximumSetPointName.clear();
 }
 
-double DbusPidZone::getFailSafePercent(void) const
+double DbusPidZone::getFailSafePercent(void)
 {
-    return _failSafePercent;
+    std::map<std::string, double>::iterator maxData = std::max_element(
+        _failSafeSensors.begin(), _failSafeSensors.end(),
+        [](const std::pair<std::string, double> firstData,
+           const std::pair<std::string, double> secondData) {
+            return firstData.second < secondData.second;
+        });
+
+    // In dbus/dbusconfiguration.cpp, the default sensor failsafepercent is 0 if
+    // there is no setting in json.
+    // Therfore, if the max failsafe duty in _failSafeSensors is 0, set final
+    // failsafe duty to _zoneFailSafePercent.
+    if ((*maxData).second == 0)
+    {
+        return _zoneFailSafePercent;
+    }
+    else
+    {
+        return (*maxData).second;
+    }
 }
 
 double DbusPidZone::getMinThermalSetPoint(void) const
@@ -355,9 +385,9 @@
                   << _maximumSetPointName;
         for (const auto& sensor : _failSafeSensors)
         {
-            if (sensor.find("Fan") == std::string::npos)
+            if (sensor.first.find("Fan") == std::string::npos)
             {
-                std::cerr << " " << sensor;
+                std::cerr << " " << sensor.first;
             }
         }
         std::cerr << "\n";
@@ -482,8 +512,6 @@
         // Start all sensors in fail-safe mode.
         markSensorMissing(t);
     }
-    // Initialize Pid FailSafePercent
-    initPidFailSafePercent();
 }
 
 void DbusPidZone::dumpCache(void)
@@ -582,34 +610,33 @@
     return _pidsControlProcess[name]->enabled();
 }
 
-void DbusPidZone::initPidFailSafePercent(void)
+void DbusPidZone::addPidFailSafePercent(std::vector<std::string> inputs,
+                                        double percent)
 {
-    // Currently, find the max failsafe percent pwm settings from zone and
-    // controller, and assign it to zone failsafe percent.
-
-    _failSafePercent = _zoneFailSafePercent;
-    std::cerr << "zone: Zone" << _zoneId
-              << " zoneFailSafePercent: " << _zoneFailSafePercent << "\n";
-
-    for (const auto& [name, value] : _pidsFailSafePercent)
+    for (const auto& sensorName : inputs)
     {
-        _failSafePercent = std::max(_failSafePercent, value);
-        std::cerr << "pid: " << name << " failSafePercent: " << value << "\n";
+        if (_sensorFailSafePercent.find(sensorName) !=
+            _sensorFailSafePercent.end())
+        {
+            _sensorFailSafePercent[sensorName] =
+                std::max(_sensorFailSafePercent[sensorName], percent);
+            if (debugEnabled)
+            {
+                std::cerr << "Sensor " << sensorName
+                          << " failsafe percent updated to "
+                          << _sensorFailSafePercent[sensorName] << "\n";
+            }
+        }
+        else
+        {
+            _sensorFailSafePercent[sensorName] = percent;
+            if (debugEnabled)
+            {
+                std::cerr << "Sensor " << sensorName
+                          << " failsafe percent set to " << percent << "\n";
+            }
+        }
     }
-
-    // when the final failsafe percent is zero , it indicate no failsafe
-    // percent is configured  , set it to 100% as the default setting.
-    if (_failSafePercent == 0)
-    {
-        _failSafePercent = 100;
-    }
-    std::cerr << "Final zone" << _zoneId
-              << " failSafePercent: " << _failSafePercent << "\n";
-}
-
-void DbusPidZone::addPidFailSafePercent(std::string name, double percent)
-{
-    _pidsFailSafePercent[name] = percent;
 }
 
 std::string DbusPidZone::leader() const