Add missing owner services precondition

Change-Id: Iccd29359ff46084d96df655e0761c86ecfabd567
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/preconditions.cpp b/control/preconditions.cpp
index b2bd420..cd404d1 100644
--- a/control/preconditions.cpp
+++ b/control/preconditions.cpp
@@ -75,6 +75,46 @@
     };
 }
 
+Action services_missing_owner(std::vector<SetSpeedEvent>&& sse)
+{
+    return [sse = std::move(sse)](auto& zone, auto& group)
+    {
+        // Set/update the services of the group
+        zone.setServices(&group);
+        const auto& services = zone.getGroupServices(&group);
+        auto precondState = std::any_of(
+            services.begin(),
+            services.end(),
+            [](const auto& s)
+            {
+                return !std::get<hasOwnerPos>(s);
+            });
+
+        if (precondState)
+        {
+            // Init the events when all the precondition(s) are true
+            std::for_each(
+                sse.begin(),
+                sse.end(),
+                [&zone](auto const& entry)
+                {
+                    zone.initEvent(entry);
+                });
+        }
+        else
+        {
+            // Unsubscribe the events' signals when any precondition is false
+            std::for_each(
+                sse.begin(),
+                sse.end(),
+                [&zone](auto const& entry)
+                {
+                    zone.removeEvent(entry);
+                });
+        }
+    };
+}
+
 } // namespace precondition
 } // namespace control
 } // namespace fan
diff --git a/control/preconditions.hpp b/control/preconditions.hpp
index 1ee3cf6..c756047 100644
--- a/control/preconditions.hpp
+++ b/control/preconditions.hpp
@@ -32,6 +32,22 @@
 Action property_states_match(std::vector<PrecondGroup>&& pg,
                              std::vector<SetSpeedEvent>&& sse);
 
+/**
+ * @brief A precondition to determine if there are any missing owners
+ * of the services for the group to init/remove a set speed event
+ * @details Checks each service associated with a group has an owner and
+ * if any of the services are missing an owner, the precondition passes
+ * and the events are initialized. Once all services associated with a
+ * group have an owner, the events are removed from being active.
+ *
+ * @param[in] sse - Set speed event definitions
+ *
+ * @return Lambda function
+ *     A lambda function precondition to check for group member services
+ *     that are not owned to either initialize or remove set speed events.
+ */
+Action services_missing_owner(std::vector<SetSpeedEvent>&& sse);
+
 } // namespace precondition
 } // namespace control
 } // namespace fan