monitor: Update YAML parser to handle trust groups

It creates a list of group creator lambdas based on
the information in the monitor YAML file.

These lambdas are called by the manager class to create
the trust group instances.

A real life example is:

const std::vector<CreateGroupFunction> trustGroups
{
    {
        []()
        {
            std::vector<std::string> names{
                "fan0_1",
                "fan1_1",
                "fan2_1",
                "fan3_1",
            };
            return std::make_unique<NonzeroSpeed>(names);
        }
    },
};

Change-Id: Ia883df35efb86242aae2f8ed7d1714e94e65a6e6
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/monitor/gen-fan-monitor-defs.py b/monitor/gen-fan-monitor-defs.py
index 4e49787..1590484 100755
--- a/monitor/gen-fan-monitor-defs.py
+++ b/monitor/gen-fan-monitor-defs.py
@@ -19,12 +19,14 @@
 tmpl = '''/* This is a generated file. */
 #include "fan_defs.hpp"
 #include "types.hpp"
+#include "groups.hpp"
 
 using namespace phosphor::fan::monitor;
+using namespace phosphor::fan::trust;
 
 const std::vector<FanDefinition> fanDefinitions
 {
-%for fan_data in data:
+%for fan_data in data.get('fans', {}):
     FanDefinition{"${fan_data['inventory']}",
                   ${fan_data['allowed_out_of_range_time']},
                   ${fan_data['deviation']},
@@ -41,6 +43,29 @@
     },
 %endfor
 };
+
+##Function to generate the group creation lambda.
+##If a group were to ever need a different constructor,
+##it could be handled here.
+<%def name="get_lambda_contents(group)">
+            std::vector<std::string> names{
+            %for sensor in group['sensors']:
+                "${sensor['name']}",
+            %endfor
+            };
+            return std::make_unique<${group['class']}>(names);
+</%def>
+const std::vector<CreateGroupFunction> trustGroups
+{
+%for group in data.get('sensor_trust_groups', {}):
+    {
+        []()
+        {\
+${get_lambda_contents(group)}\
+        }
+    },
+%endfor
+};
 '''
 
 
@@ -64,7 +89,7 @@
         monitor_data = yaml.safe_load(monitor_input) or {}
 
     #Do some minor input validation
-    for fan in monitor_data:
+    for fan in monitor_data.get('fans', {}):
         if ((fan['deviation'] < 0) or (fan['deviation'] > 100)):
             sys.exit("Invalid deviation value " + str(fan['deviation']))