control: Associate identifier with target holds

Create a zone method that associates a unique identifier to a target
hold so that if more than one hold exists, the highest target is always
used between all actions that could have set a target hold on the zone.

Change-Id: I7699769a2e271c8a63a0a0a05aef6b0888ce180a
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/json/zone.cpp b/control/json/zone.cpp
index 6d2744f..d59fe26 100644
--- a/control/json/zone.cpp
+++ b/control/json/zone.cpp
@@ -143,6 +143,36 @@
     }
 }
 
+void Zone::setTargetHold(const std::string& ident, uint64_t target, bool hold)
+{
+    if (!hold)
+    {
+        _holds.erase(ident);
+    }
+    else
+    {
+        _holds[ident] = target;
+        _isActive = false;
+    }
+
+    auto itHoldMax = std::max_element(_holds.begin(), _holds.end(),
+                                      [](const auto& aHold, const auto& bHold) {
+                                          return aHold.second < bHold.second;
+                                      });
+    if (itHoldMax == _holds.end())
+    {
+        _isActive = true;
+    }
+    else
+    {
+        _target = itHoldMax->second;
+        for (auto& fan : _fans)
+        {
+            fan->setTarget(_target);
+        }
+    }
+}
+
 void Zone::setActiveAllow(const std::string& ident, bool isActiveAllow)
 {
     _active[ident] = isActiveAllow;