control: Actions use list of groups set on base object

Remove the reference to a group given when running an action and instead
have each action iterate over the list of groups configured/set on the
base action object. The group configured/set on the base action object
is the only set of groups that the action should use based on its
configuration in an event.

Change-Id: Ia298d270e782ad729b5a29f9cdfe9b6c9ea4bc45
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/json/actions/action.hpp b/control/json/actions/action.hpp
index 0369ec9..9f642df 100644
--- a/control/json/actions/action.hpp
+++ b/control/json/actions/action.hpp
@@ -137,13 +137,11 @@
      * @brief Run the action
      *
      * 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.
+     * that performs a specific tasks on a zone configured by a user.
      *
      * @param[in] zone - Zone to run the action on
-     * @param[in] group - Group of dbus objects the action runs against
      */
-    virtual void run(Zone& zone, const Group& group) = 0;
+    virtual void run(Zone& zone) = 0;
 
     /**
      * @brief Trigger the action to run against all of its zones
@@ -153,9 +151,8 @@
      */
     void run()
     {
-        // TODO Remove passing a reference of a group to run the action
         std::for_each(_zones.begin(), _zones.end(),
-                      [this](Zone& zone) { this->run(zone, _groups.front()); });
+                      [this](Zone& zone) { this->run(zone); });
     }
 
   protected:
diff --git a/control/json/actions/count_state_target.cpp b/control/json/actions/count_state_target.cpp
index 3bbcd02..c2e3fcf 100644
--- a/control/json/actions/count_state_target.cpp
+++ b/control/json/actions/count_state_target.cpp
@@ -38,31 +38,34 @@
     setTarget(jsonObj);
 }
 
-void CountStateTarget::run(Zone& zone, const Group& group)
+void CountStateTarget::run(Zone& zone)
 {
     size_t numAtState = 0;
-    for (auto& member : group.getMembers())
+    for (const auto& group : _groups)
     {
-        try
+        for (auto& member : group.getMembers())
         {
-            if (Manager::getObjValueVariant(member, group.getInterface(),
-                                            group.getProperty()) == _state)
+            try
             {
-                numAtState++;
+                if (Manager::getObjValueVariant(member, group.getInterface(),
+                                                group.getProperty()) == _state)
+                {
+                    numAtState++;
+                }
+            }
+            catch (const std::out_of_range& oore)
+            {
+                // Default to property not equal when not found
+            }
+            if (numAtState >= _count)
+            {
+                zone.setTarget(_target);
+                break;
             }
         }
-        catch (const std::out_of_range& oore)
-        {
-            // Default to property not equal when not found
-        }
-        if (numAtState >= _count)
-        {
-            zone.setTarget(_target);
-            break;
-        }
+        // Update group's fan control active allowed based on action results
+        zone.setActiveAllow(group.getName(), !(numAtState >= _count));
     }
-    // Update group's fan control active allowed based on action results
-    zone.setActiveAllow(group.getName(), !(numAtState >= _count));
 }
 
 void CountStateTarget::setCount(const json& jsonObj)
diff --git a/control/json/actions/count_state_target.hpp b/control/json/actions/count_state_target.hpp
index 8493844..41ad179 100644
--- a/control/json/actions/count_state_target.hpp
+++ b/control/json/actions/count_state_target.hpp
@@ -67,9 +67,8 @@
      * state fall below the provided count.
      *
      * @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;
+    void run(Zone& zone) override;
 
   private:
     /* Number of group members */
diff --git a/control/json/actions/default_floor.cpp b/control/json/actions/default_floor.cpp
index 360cc17..5ca3c10 100644
--- a/control/json/actions/default_floor.cpp
+++ b/control/json/actions/default_floor.cpp
@@ -35,20 +35,23 @@
     // There are no JSON configuration parameters for this action
 }
 
-void DefaultFloor::run(Zone& zone, const Group& group)
+void DefaultFloor::run(Zone& zone)
 {
-    const auto& members = group.getMembers();
-    auto isMissingOwner =
-        std::any_of(members.begin(), members.end(),
-                    [&intf = group.getInterface()](const auto& member) {
-                        return !Manager::hasOwner(member, intf);
-                    });
-    if (isMissingOwner)
+    for (const auto& group : _groups)
     {
-        zone.setFloor(zone.getDefaultFloor());
+        const auto& members = group.getMembers();
+        auto isMissingOwner =
+            std::any_of(members.begin(), members.end(),
+                        [&intf = group.getInterface()](const auto& member) {
+                            return !Manager::hasOwner(member, intf);
+                        });
+        if (isMissingOwner)
+        {
+            zone.setFloor(zone.getDefaultFloor());
+        }
+        // Update fan control floor change allowed
+        zone.setFloorChangeAllow(group.getName(), !isMissingOwner);
     }
-    // Update fan control floor change allowed
-    zone.setFloorChangeAllow(group.getName(), !isMissingOwner);
 }
 
 } // namespace phosphor::fan::control::json
diff --git a/control/json/actions/default_floor.hpp b/control/json/actions/default_floor.hpp
index 3c84bcc..611ee8b 100644
--- a/control/json/actions/default_floor.hpp
+++ b/control/json/actions/default_floor.hpp
@@ -62,9 +62,8 @@
      * 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;
+    void run(Zone& zone) override;
 };
 
 } // namespace phosphor::fan::control::json
diff --git a/control/json/actions/missing_owner_target.cpp b/control/json/actions/missing_owner_target.cpp
index 4ba33ab..68f6614 100644
--- a/control/json/actions/missing_owner_target.cpp
+++ b/control/json/actions/missing_owner_target.cpp
@@ -39,20 +39,23 @@
     setTarget(jsonObj);
 }
 
-void MissingOwnerTarget::run(Zone& zone, const Group& group)
+void MissingOwnerTarget::run(Zone& zone)
 {
-    const auto& members = group.getMembers();
-    auto isMissingOwner =
-        std::any_of(members.begin(), members.end(),
-                    [&intf = group.getInterface()](const auto& member) {
-                        return !Manager::hasOwner(member, intf);
-                    });
-    if (isMissingOwner)
+    for (const auto& group : _groups)
     {
-        zone.setTarget(_target);
+        const auto& members = group.getMembers();
+        auto isMissingOwner =
+            std::any_of(members.begin(), members.end(),
+                        [&intf = group.getInterface()](const auto& member) {
+                            return !Manager::hasOwner(member, intf);
+                        });
+        if (isMissingOwner)
+        {
+            zone.setTarget(_target);
+        }
+        // Update group's fan control active allowed based on action results
+        zone.setActiveAllow(group.getName(), !isMissingOwner);
     }
-    // Update group's fan control active allowed based on action results
-    zone.setActiveAllow(group.getName(), !isMissingOwner);
 }
 
 void MissingOwnerTarget::setTarget(const json& jsonObj)
diff --git a/control/json/actions/missing_owner_target.hpp b/control/json/actions/missing_owner_target.hpp
index ccbdf9c..429f30e 100644
--- a/control/json/actions/missing_owner_target.hpp
+++ b/control/json/actions/missing_owner_target.hpp
@@ -64,9 +64,8 @@
      * resulting in the zone's target being set/held at the configured target.
      *
      * @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;
+    void run(Zone& zone) override;
 
   private:
     /* Target for this action */
diff --git a/control/json/actions/net_target_decrease.cpp b/control/json/actions/net_target_decrease.cpp
index 6fcd1e9..39e5521 100644
--- a/control/json/actions/net_target_decrease.cpp
+++ b/control/json/actions/net_target_decrease.cpp
@@ -42,90 +42,93 @@
     setDelta(jsonObj);
 }
 
-void NetTargetDecrease::run(Zone& zone, const Group& group)
+void NetTargetDecrease::run(Zone& zone)
 {
     auto netDelta = zone.getDecDelta();
-    for (const auto& member : group.getMembers())
+    for (const auto& group : _groups)
     {
-        try
+        for (const auto& member : group.getMembers())
         {
-            auto value = Manager::getObjValueVariant(
-                member, group.getInterface(), group.getProperty());
-            if (std::holds_alternative<int64_t>(value) ||
-                std::holds_alternative<double>(value))
+            try
             {
-                if (value >= _state)
+                auto value = Manager::getObjValueVariant(
+                    member, group.getInterface(), group.getProperty());
+                if (std::holds_alternative<int64_t>(value) ||
+                    std::holds_alternative<double>(value))
                 {
-                    // No decrease allowed for this group
-                    netDelta = 0;
-                    break;
+                    if (value >= _state)
+                    {
+                        // No decrease allowed for this group
+                        netDelta = 0;
+                        break;
+                    }
+                    else
+                    {
+                        // Decrease factor is the difference in configured state
+                        // to the current value's state
+                        uint64_t deltaFactor = 0;
+                        if (auto dblPtr = std::get_if<double>(&value))
+                        {
+                            deltaFactor = static_cast<uint64_t>(
+                                std::get<double>(_state) - *dblPtr);
+                        }
+                        else
+                        {
+                            deltaFactor = static_cast<uint64_t>(
+                                std::get<int64_t>(_state) -
+                                std::get<int64_t>(value));
+                        }
+
+                        // Multiply the decrease factor by the configured delta
+                        // to get the net decrease delta for the given group
+                        // member. The lowest net decrease delta of the entire
+                        // group is the decrease requested.
+                        if (netDelta == 0)
+                        {
+                            netDelta = deltaFactor * _delta;
+                        }
+                        else
+                        {
+                            netDelta = std::min(netDelta, deltaFactor * _delta);
+                        }
+                    }
+                }
+                else if (std::holds_alternative<bool>(value) ||
+                         std::holds_alternative<std::string>(value))
+                {
+                    // Where a group of booleans or strings equal the state
+                    // provided, request a decrease of the configured delta
+                    if (_state == value)
+                    {
+                        if (netDelta == 0)
+                        {
+                            netDelta = _delta;
+                        }
+                        else
+                        {
+                            netDelta = std::min(netDelta, _delta);
+                        }
+                    }
                 }
                 else
                 {
-                    // Decrease factor is the difference in configured state to
-                    // the current value's state
-                    uint64_t deltaFactor = 0;
-                    if (auto dblPtr = std::get_if<double>(&value))
-                    {
-                        deltaFactor = static_cast<uint64_t>(
-                            std::get<double>(_state) - *dblPtr);
-                    }
-                    else
-                    {
-                        deltaFactor =
-                            static_cast<uint64_t>(std::get<int64_t>(_state) -
-                                                  std::get<int64_t>(value));
-                    }
-
-                    // Multiply the decrease factor by the configured delta to
-                    // get the net decrease delta for the given group member.
-                    // The lowest net decrease delta of the entire group is the
-                    // decrease requested.
-                    if (netDelta == 0)
-                    {
-                        netDelta = deltaFactor * _delta;
-                    }
-                    else
-                    {
-                        netDelta = std::min(netDelta, deltaFactor * _delta);
-                    }
+                    // Unsupported group member type for this action
+                    log<level::ERR>(
+                        fmt::format("Action {}: Unsupported group member type "
+                                    "given. [object = {} : {} : {}]",
+                                    ActionBase::getName(), member,
+                                    group.getInterface(), group.getProperty())
+                            .c_str());
                 }
             }
-            else if (std::holds_alternative<bool>(value) ||
-                     std::holds_alternative<std::string>(value))
+            catch (const std::out_of_range& oore)
             {
-                // Where a group of booleans or strings equal the state
-                // provided, request a decrease of the configured delta
-                if (_state == value)
-                {
-                    if (netDelta == 0)
-                    {
-                        netDelta = _delta;
-                    }
-                    else
-                    {
-                        netDelta = std::min(netDelta, _delta);
-                    }
-                }
-            }
-            else
-            {
-                // Unsupported group member type for this action
-                log<level::ERR>(
-                    fmt::format("Action {}: Unsupported group member type "
-                                "given. [object = {} : {} : {}]",
-                                ActionBase::getName(), member,
-                                group.getInterface(), group.getProperty())
-                        .c_str());
+                // Property value not found, netDelta unchanged
             }
         }
-        catch (const std::out_of_range& oore)
-        {
-            // Property value not found, netDelta unchanged
-        }
+        // Update group's decrease allowed state
+        zone.setDecreaseAllow(group.getName(), !(netDelta == 0));
     }
-    // Update group's decrease allowed state
-    zone.setDecreaseAllow(group.getName(), !(netDelta == 0));
     // Request target decrease to occur on decrease interval
     zone.requestDecrease(netDelta);
 }
diff --git a/control/json/actions/net_target_decrease.hpp b/control/json/actions/net_target_decrease.hpp
index 0346cf2..293d68f 100644
--- a/control/json/actions/net_target_decrease.hpp
+++ b/control/json/actions/net_target_decrease.hpp
@@ -76,9 +76,8 @@
      * requested on the zone.
      *
      * @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;
+    void run(Zone& zone) override;
 
   private:
     /* State the members must be at to decrease the target */
diff --git a/control/json/actions/net_target_increase.cpp b/control/json/actions/net_target_increase.cpp
index 2240121..4387a4c 100644
--- a/control/json/actions/net_target_increase.cpp
+++ b/control/json/actions/net_target_increase.cpp
@@ -42,81 +42,87 @@
     setDelta(jsonObj);
 }
 
-void NetTargetIncrease::run(Zone& zone, const Group& group)
+void NetTargetIncrease::run(Zone& zone)
 {
     auto netDelta = zone.getIncDelta();
-    const auto& members = group.getMembers();
-    std::for_each(
-        members.begin(), members.end(),
-        [this, &zone, &group, &netDelta](const auto& member) {
-            try
-            {
-                auto value = Manager::getObjValueVariant(
-                    member, group.getInterface(), group.getProperty());
-                if (std::holds_alternative<int64_t>(value) ||
-                    std::holds_alternative<double>(value))
+    for (const auto& group : _groups)
+    {
+        const auto& members = group.getMembers();
+        std::for_each(
+            members.begin(), members.end(),
+            [this, &zone, &group, &netDelta](const auto& member) {
+                try
                 {
-                    // Where a group of int/doubles are greater than or equal
-                    // to the state(some value) provided, request an increase
-                    // of the configured delta times the difference between
-                    // the group member's value and configured state value.
-                    if (value >= _state)
+                    auto value = Manager::getObjValueVariant(
+                        member, group.getInterface(), group.getProperty());
+                    if (std::holds_alternative<int64_t>(value) ||
+                        std::holds_alternative<double>(value))
                     {
-                        uint64_t incDelta = 0;
-                        if (auto dblPtr = std::get_if<double>(&value))
+                        // Where a group of int/doubles are greater than or
+                        // equal to the state(some value) provided, request an
+                        // increase of the configured delta times the difference
+                        // between the group member's value and configured state
+                        // value.
+                        if (value >= _state)
                         {
-                            incDelta = static_cast<uint64_t>(
-                                (*dblPtr - std::get<double>(_state)) * _delta);
+                            uint64_t incDelta = 0;
+                            if (auto dblPtr = std::get_if<double>(&value))
+                            {
+                                incDelta = static_cast<uint64_t>(
+                                    (*dblPtr - std::get<double>(_state)) *
+                                    _delta);
+                            }
+                            else
+                            {
+                                // Increase by at least a single delta
+                                // to attempt bringing under provided 'state'
+                                auto deltaFactor =
+                                    std::max((std::get<int64_t>(value) -
+                                              std::get<int64_t>(_state)),
+                                             1ll);
+                                incDelta =
+                                    static_cast<uint64_t>(deltaFactor * _delta);
+                            }
+                            netDelta = std::max(netDelta, incDelta);
                         }
-                        else
+                    }
+                    else if (std::holds_alternative<bool>(value))
+                    {
+                        // Where a group of booleans equal the state(`true` or
+                        // `false`) provided, request an increase of the
+                        // configured delta
+                        if (_state == value)
                         {
-                            // Increase by at least a single delta
-                            // to attempt bringing under provided 'state'
-                            auto deltaFactor =
-                                std::max((std::get<int64_t>(value) -
-                                          std::get<int64_t>(_state)),
-                                         1ll);
-                            incDelta =
-                                static_cast<uint64_t>(deltaFactor * _delta);
+                            netDelta = std::max(netDelta, _delta);
                         }
-                        netDelta = std::max(netDelta, incDelta);
                     }
-                }
-                else if (std::holds_alternative<bool>(value))
-                {
-                    // Where a group of booleans equal the state(`true` or
-                    // `false`) provided, request an increase of the configured
-                    // delta
-                    if (_state == value)
+                    else if (std::holds_alternative<std::string>(value))
                     {
-                        netDelta = std::max(netDelta, _delta);
+                        // Where a group of strings equal the state(some string)
+                        // provided, request an increase of the configured delta
+                        if (_state == value)
+                        {
+                            netDelta = std::max(netDelta, _delta);
+                        }
                     }
-                }
-                else if (std::holds_alternative<std::string>(value))
-                {
-                    // Where a group of strings equal the state(some string)
-                    // provided, request an increase of the configured delta
-                    if (_state == value)
+                    else
                     {
-                        netDelta = std::max(netDelta, _delta);
+                        // Unsupported group member type for this action
+                        log<level::ERR>(
+                            fmt::format(
+                                "Action {}: Unsupported group member type "
+                                "given. [object = {} : {} : {}]",
+                                ActionBase::getName(), member,
+                                group.getInterface(), group.getProperty())
+                                .c_str());
                     }
                 }
-                else
+                catch (const std::out_of_range& oore)
                 {
-                    // Unsupported group member type for this action
-                    log<level::ERR>(
-                        fmt::format("Action {}: Unsupported group member type "
-                                    "given. [object = {} : {} : {}]",
-                                    ActionBase::getName(), member,
-                                    group.getInterface(), group.getProperty())
-                            .c_str());
+                    // Property value not found, netDelta unchanged
                 }
-            }
-            catch (const std::out_of_range& oore)
-            {
-                // Property value not found, netDelta unchanged
-            }
-        });
+            });
+    }
     // Request increase to target
     zone.requestIncrease(netDelta);
 }
diff --git a/control/json/actions/net_target_increase.hpp b/control/json/actions/net_target_increase.hpp
index 7992695..b0d77e6 100644
--- a/control/json/actions/net_target_increase.hpp
+++ b/control/json/actions/net_target_increase.hpp
@@ -76,9 +76,8 @@
      * requested on the zone.
      *
      * @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;
+    void run(Zone& zone) override;
 
   private:
     /* State the members must be at to increase the rarget */
diff --git a/control/json/actions/request_target_base.cpp b/control/json/actions/request_target_base.cpp
index 5000ea8..4bcaabb 100644
--- a/control/json/actions/request_target_base.cpp
+++ b/control/json/actions/request_target_base.cpp
@@ -39,51 +39,54 @@
     // There are no JSON configuration parameters for this action
 }
 
-void RequestTargetBase::run(Zone& zone, const Group& group)
+void RequestTargetBase::run(Zone& zone)
 {
     uint64_t base = 0;
-    for (const auto& member : group.getMembers())
+    for (const auto& group : _groups)
     {
-        try
+        for (const auto& member : group.getMembers())
         {
-            auto value = Manager::getObjValueVariant(
-                member, group.getInterface(), group.getProperty());
-            if (auto intPtr = std::get_if<int64_t>(&value))
+            try
             {
-                // Throw out any negative values as those are not valid
-                // to use as a fan target base
-                if (*intPtr < 0)
+                auto value = Manager::getObjValueVariant(
+                    member, group.getInterface(), group.getProperty());
+                if (auto intPtr = std::get_if<int64_t>(&value))
                 {
-                    continue;
+                    // Throw out any negative values as those are not valid
+                    // to use as a fan target base
+                    if (*intPtr < 0)
+                    {
+                        continue;
+                    }
+                    base = std::max(base, static_cast<uint64_t>(*intPtr));
                 }
-                base = std::max(base, static_cast<uint64_t>(*intPtr));
-            }
-            else if (auto dblPtr = std::get_if<double>(&value))
-            {
-                // Throw out any negative values as those are not valid
-                // to use as a fan target base
-                if (*dblPtr < 0)
+                else if (auto dblPtr = std::get_if<double>(&value))
                 {
-                    continue;
+                    // Throw out any negative values as those are not valid
+                    // to use as a fan target base
+                    if (*dblPtr < 0)
+                    {
+                        continue;
+                    }
+                    // Precision of a double not a concern with fan targets
+                    base = std::max(base, static_cast<uint64_t>(*dblPtr));
                 }
-                // Precision of a double not a concern with fan targets
-                base = std::max(base, static_cast<uint64_t>(*dblPtr));
+                else
+                {
+                    // Unsupported group member type for this action
+                    log<level::ERR>(
+                        fmt::format("Action {}: Unsupported group member type "
+                                    "given. [object = {} : {} : {}]",
+                                    getName(), member, group.getInterface(),
+                                    group.getProperty())
+                            .c_str());
+                }
             }
-            else
+            catch (const std::out_of_range& oore)
             {
-                // Unsupported group member type for this action
-                log<level::ERR>(
-                    fmt::format("Action {}: Unsupported group member type "
-                                "given. [object = {} : {} : {}]",
-                                getName(), member, group.getInterface(),
-                                group.getProperty())
-                        .c_str());
+                // Property value not found, base request target unchanged
             }
         }
-        catch (const std::out_of_range& oore)
-        {
-            // Property value not found, base request target unchanged
-        }
     }
 
     // A request target base of 0 defaults to the current target
diff --git a/control/json/actions/request_target_base.hpp b/control/json/actions/request_target_base.hpp
index 289afdc..e5a3469 100644
--- a/control/json/actions/request_target_base.hpp
+++ b/control/json/actions/request_target_base.hpp
@@ -68,9 +68,8 @@
      * valid types for a fan target to be based off of.
      *
      * @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;
+    void run(Zone& zone) override;
 };
 
 } // namespace phosphor::fan::control::json