control: mapped_floor: Add conditions

Add the concept of a condition to the mapped_floor action such that it
will only run if the condition is met.  If the condition isn't met, the
run() function will just exit immediately.

A condition is created by placing the following in the JSON:

* condition_group
  - The name of the group that has the property the condition
    will use.  For now, it must be a single member group.
* condition_value
  - The value the property has to be to meet the condition.
* condition_op
  - Either 'equal' or 'not_equal', where the property has to
    either be equal to or not equal to the condition value.

For example, the following says the single member of the 'cpu 0' group
must have its Model property be equal to "1234" for the action to run:

{
    "groups": [{
        "name": "cpu 0",
        "interface": "xyz.openbmc_project.Inventory.Decorator.Asset",
        "property": { "name": "Model" }
      }
      ...
    ],
    ...
    "name": "mapped_floor",
    "key_group": "ambient temp",
    "condition_group": "cpu 0",
    "condition_value": "1234",
    "condition_op": "equal",
    ...
}

If a condition is present but isn't met, the action will remove its
floor hold if it has one to support the case of the condition property
changing values.

Change-Id: I3ede20efd334e2c5292a441c089534420959c7bc
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/control/json/actions/mapped_floor.hpp b/control/json/actions/mapped_floor.hpp
index 9c8a937..75cc7b2 100644
--- a/control/json/actions/mapped_floor.hpp
+++ b/control/json/actions/mapped_floor.hpp
@@ -101,6 +101,17 @@
  *   3. The default floor in the zone config
  *     - Chosen when when 2. would be used, but it wasn't supplied
  *
+ * This action can also have a condition specified where a group property
+ * must either match or not match a given value to determine if the
+ * action should run or not.  This requires the following in the JSON:
+ *    "condition_group": The group name
+ *       - As of now, group must just have a single member.
+ *    "condition_op": Either "equal" or "not_equal"
+ *    "condition_value": The value to check against
+ *
+ * This allows completely separate mapped_floor actions to run based on
+ * the value of a D-bus property - i.e. it allows multiple floor tables.
+ *
  * Other notes:
  *  - If a group has multiple members, they must be numeric or else
  *    the code will throw an exception.
@@ -113,7 +124,6 @@
  *    it can be:
  *            "parameter": "some_parameter"
  */
-
 class MappedFloor : public ActionBase, public ActionRegister<MappedFloor>
 {
   public:
@@ -165,6 +175,13 @@
     void setFloorTable(const json& jsonObj);
 
     /**
+     * @brief Parse and set the conditions
+     *
+     * @param jsonObj - JSON object for the action
+     */
+    void setCondition(const json& jsonObj);
+
+    /**
      * @brief Applies the offset in offsetParameter to the
      *        value passed in.
      *
@@ -207,9 +224,26 @@
      */
     const Group* getGroup(const std::string& name);
 
+    /**
+     * @brief Checks if the condition is met, if there is one.
+     *
+     * @return bool - False if there is a condition and it
+     *                isn't met, true otherwise.
+     */
+    bool meetsCondition();
+
     /* Key group pointer */
     const Group* _keyGroup;
 
+    /* condition group pointer */
+    const Group* _conditionGroup = nullptr;
+
+    /* Condition value */
+    PropertyVariantType _conditionValue;
+
+    /* Condition operation */
+    std::string _conditionOp;
+
     /* Optional default floor value for the action */
     std::optional<uint64_t> _defaultFloor;