Support optional conditions on creating fans

This adds the functional infrastructure to optionally attach a condition
function to a fan definition. When a condition is defined on a fan, it
must be true for a fan's associated functional properties to be created.
When the given condition fails, that fan's functional properties will
not be created by fan monitor. A fan without a defined condition will
have all of its associated functional properties created.

Example of generated condition (generation commit to follow):

make_condition(condition::propertiesMatch(
    std::vector<PropertyState>{
        PropertyState{
            PropertyIdentity{
                "/xyz/openbmc_project/inventory/system/chassis",
                "xyz.openbmc_project.Inventory.Decorator.CoolingType",
                "WaterCooled"
            },
            static_cast<bool>(false)
        }
    }
)),

Tested:
    Fan functional properties are not created when a condition fails
    Fan functional properties are created when condition passes
    Fan functional properties are created when no condition exists

Change-Id: I9ced2e520d2f97e6655c9417970b3e976d78fef4
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/monitor/conditions.cpp b/monitor/conditions.cpp
new file mode 100644
index 0000000..c046f0c
--- /dev/null
+++ b/monitor/conditions.cpp
@@ -0,0 +1,35 @@
+#include <algorithm>
+#include "conditions.hpp"
+#include "sdbusplus.hpp"
+
+namespace phosphor
+{
+namespace fan
+{
+namespace monitor
+{
+namespace condition
+{
+
+Condition propertiesMatch(std::vector<PropertyState>&& propStates)
+{
+    return [pStates = std::move(propStates)](sdbusplus::bus::bus& bus)
+    {
+        return std::all_of(
+            pStates.begin(),
+            pStates.end(),
+            [&bus](const auto& p)
+        {
+            return util::SDBusPlus::getPropertyVariant<PropertyValue>(
+                bus,
+                std::get<propObj>(p.first),
+                std::get<propIface>(p.first),
+                std::get<propName>(p.first)) == p.second;
+        });
+    };
+}
+
+} // namespace condition
+} // namespace monitor
+} // namespace fan
+} // namespace phosphor