control: Update JSON action objects to run the action

A change in design direction for the JSON configuration path of fan
control is to have it separate than the YAML configuration
functionality. This means that the JSON based action objects will run
the action function directly instead of returning the action function
which is done for YAML based configurations.

Update the default floor action to reflect this change in direction.

Change-Id: I75ade1c7e2e9698573c5ed2495c2f3b7e9cf52f0
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/json/actions/action.hpp b/control/json/actions/action.hpp
index 7307e7f..cfee7af 100644
--- a/control/json/actions/action.hpp
+++ b/control/json/actions/action.hpp
@@ -16,6 +16,7 @@
 #pragma once
 
 #include "types.hpp"
+#include "zone.hpp"
 
 #include <fmt/format.h>
 
@@ -61,19 +62,29 @@
     ActionBase& operator=(const ActionBase&) = delete;
     ActionBase& operator=(ActionBase&&) = delete;
     virtual ~ActionBase() = default;
+
+    /**
+     * @brief Base action object
+     *
+     * All actions derived from this base action object must be given a name
+     * that uniquely identifies the action.
+     *
+     * @param[in] name - Unique name of the action
+     */
     explicit ActionBase(const std::string& name) : _name(name)
     {}
 
     /**
-     * @brief Get the action function to perform
+     * @brief Run the action
      *
-     * An action function is a function associated to the derived action object
-     * that performs a specific task against fan control that's configured by
-     * a user.
+     * Run the action function associated to the derived action object
+     * that performs a specific task against a group of dbus objects on a zone
+     * configured by a user.
      *
-     * @return Action function
+     * @param[in] zone - Zone to run the action on
+     * @param[in] group - Group of dbus objects the action runs against
      */
-    virtual const Action getAction() = 0;
+    virtual void run(Zone& zone, const Group& group) = 0;
 
     /**
      * @brief Get the action's name
diff --git a/control/json/actions/default_floor.cpp b/control/json/actions/default_floor.cpp
index 6f30bf3..5970ae2 100644
--- a/control/json/actions/default_floor.cpp
+++ b/control/json/actions/default_floor.cpp
@@ -1,5 +1,5 @@
 /**
- * Copyright © 2020 IBM Corporation
+ * Copyright © 2021 IBM Corporation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,12 +15,14 @@
  */
 #include "default_floor.hpp"
 
-#include "actions.hpp"
-#include "functor.hpp"
 #include "types.hpp"
+#include "zone.hpp"
 
 #include <nlohmann/json.hpp>
 
+#include <algorithm>
+#include <tuple>
+
 namespace phosphor::fan::control::json
 {
 
@@ -28,12 +30,23 @@
 
 DefaultFloor::DefaultFloor(const json&) : ActionBase(DefaultFloor::name)
 {
-    // There are no additional JSON configuration parameters for this action
+    // There are no JSON configuration parameters for this action
 }
 
-const Action DefaultFloor::getAction()
+void DefaultFloor::run(Zone& zone, const Group& group)
 {
-    return make_action(action::default_floor_on_missing_owner);
+    // Set/update the services of the group
+    zone.setServices(&group);
+    auto services = zone.getGroupServices(&group);
+    auto defFloor =
+        std::any_of(services.begin(), services.end(),
+                    [](const auto& s) { return !std::get<hasOwnerPos>(s); });
+    if (defFloor)
+    {
+        zone.setFloor(zone.getDefFloor());
+    }
+    // Update fan control floor change allowed
+    zone.setFloorChangeAllow(&group, !defFloor);
 }
 
 } // namespace phosphor::fan::control::json
diff --git a/control/json/actions/default_floor.hpp b/control/json/actions/default_floor.hpp
index 804ce18..5aa4182 100644
--- a/control/json/actions/default_floor.hpp
+++ b/control/json/actions/default_floor.hpp
@@ -1,5 +1,5 @@
 /**
- * Copyright © 2020 IBM Corporation
+ * Copyright © 2021 IBM Corporation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
 
 #include "action.hpp"
 #include "types.hpp"
+#include "zone.hpp"
 
 #include <nlohmann/json.hpp>
 
@@ -46,9 +47,24 @@
     DefaultFloor& operator=(DefaultFloor&&) = delete;
     ~DefaultFloor() = default;
 
+    /**
+     * @brief Default the fan floor speed
+     *
+     * No JSON configuration parameters required
+     */
     explicit DefaultFloor(const json&);
 
-    const Action getAction() override;
+    /**
+     * @brief Run the action
+     *
+     * Updates the services of the group, then determines if any of the
+     * services hosting the members of the group are not owned on dbus
+     * resulting in the zone's floor being set/held at the default floor.
+     *
+     * @param[in] zone - Zone to run the action on
+     * @param[in] group - Group of dbus objects the action runs against
+     */
+    void run(Zone& zone, const Group& group) override;
 };
 
 } // namespace phosphor::fan::control::json