inventory: write sensor yaml parser

Write python-based parser for sensor.yaml. The parser generates
sensor-gen.cpp,which is having a map of sensorid(key) and
sensorinfo(value).

Change-Id: I5aa2d2bc871ced06e5e4c164a67eeb5974031d5d
Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
diff --git a/scripts/sensor_gen.py b/scripts/sensor_gen.py
new file mode 100755
index 0000000..822a00a
--- /dev/null
+++ b/scripts/sensor_gen.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import yaml
+import argparse
+from mako.template import Template
+
+
+def generate_cpp(sensor_yaml, output_dir):
+    with open(os.path.join(script_dir, sensor_yaml), 'r') as f:
+        ifile = yaml.safe_load(f)
+        if not isinstance(ifile, dict):
+            ifile = {}
+
+        # Render the mako template
+
+        t = Template(filename=os.path.join(
+                     script_dir,
+                     "writesensor.mako.cpp"))
+
+        output_cpp = os.path.join(output_dir, "sensor-gen.cpp")
+        with open(output_cpp, 'w') as fd:
+            fd.write(t.render(sensorDict=ifile))
+
+
+def main():
+
+    valid_commands = {
+        'generate-cpp': generate_cpp
+    }
+    parser = argparse.ArgumentParser(
+        description="IPMI Sensor parser and code generator")
+
+    parser.add_argument(
+        '-i', '--sensor_yaml', dest='sensor_yaml',
+        default='example.yaml', help='input sensor yaml file to parse')
+
+    parser.add_argument(
+        "-o", "--output-dir", dest="outputdir",
+        default=".",
+        help="output directory")
+
+    parser.add_argument(
+        'command', metavar='COMMAND', type=str,
+        choices=valid_commands.keys(),
+        help='Command to run.')
+
+    args = parser.parse_args()
+
+    if (not (os.path.isfile(os.path.join(script_dir, args.sensor_yaml)))):
+        sys.exit("Can not find input yaml file " + args.sensor_yaml)
+
+    function = valid_commands[args.command]
+    function(args.sensor_yaml, args.outputdir)
+
+
+if __name__ == '__main__':
+    script_dir = os.path.dirname(os.path.realpath(__file__))
+    main()
diff --git a/scripts/writesensor.mako.cpp b/scripts/writesensor.mako.cpp
new file mode 100644
index 0000000..0b8d5f1
--- /dev/null
+++ b/scripts/writesensor.mako.cpp
@@ -0,0 +1,54 @@
+## This file is a template.  The comment below is emitted
+## into the rendered file; feel free to edit this file.
+
+// !!! WARNING: This is a GENERATED Code..Please do NOT Edit !!!
+
+#include "types.hpp"
+using namespace ipmi::sensor;
+
+extern const IdInfoMap sensors = {
+% for key in sensorDict.iterkeys():
+   % if key:
+{${key},{
+<%
+       sensor = sensorDict[key]
+       interfaces = sensor["interfaces"]
+       path = sensor["path"]
+       sensorType = sensor["sensorType"]
+       readingType = sensor["sensorReadingType"]
+%>
+        ${sensorType},"${path}",${readingType},{
+    % for interface,properties in interfaces.iteritems():
+            {"${interface}",{
+            % for dbus_property,property_value in properties.iteritems():
+                {"${dbus_property}",{
+                % for offset,values in property_value.iteritems():
+                    { ${offset},{
+<%
+                        valueType = values["type"]
+%>
+                     % for name,value in values.iteritems():
+                        % if name == "type":
+<%
+                              continue
+%>
+                        % endif
+                        % if valueType == "string":
+                           std::string("${value}"),
+                        % else:
+                           ${value},
+                        % endif
+                     % endfor
+                        }
+                    },
+                % endfor
+                }},
+            % endfor
+            }},
+    % endfor
+     }
+}},
+   % endif
+% endfor
+};
+
diff --git a/types.hpp b/types.hpp
new file mode 100644
index 0000000..d8a1386
--- /dev/null
+++ b/types.hpp
@@ -0,0 +1,48 @@
+#pragma once
+
+#include <stdint.h>
+
+#include <map>
+#include <string>
+
+#include <sdbusplus/server.hpp>
+
+namespace ipmi
+{
+namespace sensor
+{
+
+using Offset = uint8_t;
+using Value = sdbusplus::message::variant<bool, int64_t, std::string>;
+
+struct Values
+{
+   Value assert;
+   Value deassert;
+};
+
+using OffsetValueMap = std::map<Offset,Values>;
+
+using DbusProperty = std::string;
+using DbusPropertyMap = std::map<DbusProperty,OffsetValueMap>;
+
+using DbusInterface = std::string;
+using DbusInterfaceMap = std::map<DbusInterface,DbusPropertyMap>;
+
+using InstancePath = std::string;
+using Type = uint8_t;
+using ReadingType = uint8_t;
+
+struct Info
+{
+   Type sensorType;
+   InstancePath sensorPath;
+   ReadingType sensorReadingType;
+   DbusInterfaceMap sensorInterfaces;
+};
+
+using Id = uint8_t;
+using IdInfoMap = std::map<Id,Info>;
+
+}//namespce sensor
+}//namespace ipmi