Move components from proving-ground

Move all needed components from proving ground to this
repo. Some clean up was done in json files to fix probes
as well as some slight modification to readme.

Change-Id: I05b7f6459704640c4850420a4573d157500d0aff
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..b946b9b
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,90 @@
+---
+Language:        Cpp
+# BasedOnStyle:  LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: false
+AlignOperands:   true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+  AfterClass:      true
+  AfterControlStatement: true
+  AfterEnum:       true
+  AfterFunction:   true
+  AfterNamespace:  false
+  AfterObjCDeclaration: true
+  AfterStruct:     true
+  AfterUnion:      true
+  BeforeCatch:     true
+  BeforeElse:      true
+  IndentBraces:    false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+ColumnLimit:     80
+CommentPragmas:  '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat:   false
+ExperimentalAutoDetectBinPacking: false
+ForEachMacros:   [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IncludeCategories:
+  - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
+    Priority:        2
+  - Regex:           '^(<|"(gtest|isl|json)/)'
+    Priority:        3
+  - Regex:           '.*'
+    Priority:        1
+IndentCaseLabels: false
+IndentWidth:     4
+IndentWrappedFunctionNames: false
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Right
+ReflowComments:  true
+SortIncludes:    false
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles:  false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard:        Cpp11
+TabWidth:        4
+UseTab:          Never
+...
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a007fea
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+build/*
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755
index 0000000..638854f
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,101 @@
+cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
+SET(BUILD_SHARED_LIBRARIES OFF)
+include(ExternalProject)
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lstdc++fs")
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
+
+option(HUNTER_ENABLED "Enable hunter package pulling" OFF)
+include("cmake/HunterGate.cmake")
+
+HunterGate(
+    URL "https://github.com/ruslo/hunter/archive/v0.18.64.tar.gz"
+    SHA1 "baf9c8cc4f65306f0e442b5419967b4c4c04589a"
+)
+
+project(enitity-manager)
+
+hunter_add_package(Boost)
+find_package(Boost REQUIRED)
+include_directories(${Boost_INCLUDE_DIRS})
+
+add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY)
+add_definitions(-DBOOST_SYSTEM_NO_DEPRECATED)
+add_definitions(-DBOOST_ALL_NO_LIB)
+add_definitions(-DBOOST_NO_RTTI)
+add_definitions(-DBOOST_NO_TYPEID)
+
+hunter_add_package(dbus)
+find_package(dbus REQUIRED) # Include functions provided by PkgConfig module.
+include_directories(${DBUS_INCLUDE_DIRS})
+
+find_package(Threads REQUIRED)
+
+option(YOCTO "Enable Building in Yocto" OFF)
+
+if(NOT YOCTO)
+    ExternalProject_Add(boost-dbus
+        PREFIX ${CMAKE_CURRENT_BINARY_DIR}/boost-dbus
+        GIT_REPOSITORY ssh://git-amr-2.devtools.intel.com:29418/openbmc-boost-dbus
+        GIT_TAG fee38731bccba22b4157cc47afbf6434fec1eb6d
+        CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${EXTERNAL_INSTALL_LOCATION} -DBOOST_ROOT=${BOOST_ROOT}
+        CONFIGURE_COMMAND ""
+        BUILD_COMMAND ""
+        INSTALL_COMMAND ""
+        LOG_DOWNLOAD ON
+    )
+    ExternalProject_Get_Property(boost-dbus install_dir)
+    include_directories(${install_dir}/src/boost-dbus/include)
+
+    include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/non-yocto)
+
+    ExternalProject_Add(nlohmann-json
+        PREFIX ${CMAKE_CURRENT_BINARY_DIR}/nlohmann-json
+        GIT_REPOSITORY https://github.com/nlohmann/json.git
+        GIT_TAG afebb6a3bbc8751e834a5472e5c53cb2b5bbd750
+        CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${EXTERNAL_INSTALL_LOCATION}
+        CONFIGURE_COMMAND ""
+        BUILD_COMMAND mkdir -p
+            ${CMAKE_CURRENT_BINARY_DIR}/nlohmann-json/src/nlohmann-json/src/nlohmann &&
+                cp ${CMAKE_CURRENT_BINARY_DIR}/nlohmann-json/src/nlohmann-json/src/json.hpp
+                ${CMAKE_CURRENT_BINARY_DIR}/nlohmann-json/src/nlohmann-json/src/nlohmann/json.hpp
+        INSTALL_COMMAND ""
+        LOG_DOWNLOAD ON
+    )
+
+    ExternalProject_Get_Property(nlohmann-json install_dir)
+    include_directories(${install_dir}/src/nlohmann-json/src)
+
+    option(ENABLE_TEST "Enable Google Test" OFF)
+    if(ENABLE_TEST)
+        hunter_add_package(GTest)
+        find_package(GTest CONFIG REQUIRED)
+        enable_testing()
+    endif()
+endif()
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+link_directories(${EXTERNAL_INSTALL_LOCATION}/lib)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+add_executable(fru-device src/FruDevice.cpp src/Utils.cpp)
+add_dependencies(fru-device boost-dbus)
+
+#add_dependencies(entity-manager nlohmann-json)
+target_link_libraries(fru-device  ${DBUS_LIBRARIES})
+target_link_libraries(fru-device pthread)
+target_link_libraries(fru-device stdc++fs)
+target_link_libraries(fru-device ${Boost_LIBRARIES})
+
+add_executable(entity-manager src/EntityManager.cpp src/Utils.cpp)
+add_dependencies(entity-manager boost-dbus)
+
+add_dependencies(entity-manager nlohmann-json)
+target_link_libraries(entity-manager  ${DBUS_LIBRARIES})
+target_link_libraries(entity-manager pthread)
+target_link_libraries(entity-manager stdc++fs)
+target_link_libraries(entity-manager ${Boost_LIBRARIES})
+
+install (TARGETS fru-device entity-manager DESTINATION bin)
diff --git a/CMakeLists.txt.orig b/CMakeLists.txt.orig
new file mode 100755
index 0000000..bd10a73
--- /dev/null
+++ b/CMakeLists.txt.orig
@@ -0,0 +1,105 @@
+cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
+SET(BUILD_SHARED_LIBRARIES OFF)
+include(ExternalProject)
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lstdc++fs")
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
+
+option(HUNTER_ENABLED "Enable hunter package pulling" OFF)
+include("cmake/HunterGate.cmake")
+
+HunterGate(
+    URL "https://github.com/ruslo/hunter/archive/v0.18.64.tar.gz"
+    SHA1 "baf9c8cc4f65306f0e442b5419967b4c4c04589a"
+)
+
+project(enitity-manager)
+
+hunter_add_package(Boost)
+find_package(Boost REQUIRED)
+include_directories(${Boost_INCLUDE_DIRS})
+
+add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY)
+add_definitions(-DBOOST_SYSTEM_NO_DEPRECATED)
+add_definitions(-DBOOST_ALL_NO_LIB)
+add_definitions(-DBOOST_NO_RTTI)
+add_definitions(-DBOOST_NO_TYPEID)
+
+hunter_add_package(dbus)
+find_package(dbus REQUIRED) # Include functions provided by PkgConfig module.
+include_directories(${DBUS_INCLUDE_DIRS})
+
+find_package(Threads REQUIRED)
+
+option(YOCTO "Enable Building in Yocto" OFF)
+
+if(NOT YOCTO)
+    ExternalProject_Add(boost-dbus
+        PREFIX ${CMAKE_CURRENT_BINARY_DIR}/boost-dbus
+        GIT_REPOSITORY ssh://git-amr-2.devtools.intel.com:29418/openbmc-boost-dbus
+        GIT_TAG fee38731bccba22b4157cc47afbf6434fec1eb6d
+        CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${EXTERNAL_INSTALL_LOCATION} -DBOOST_ROOT=${BOOST_ROOT}
+        CONFIGURE_COMMAND ""
+        BUILD_COMMAND ""
+        INSTALL_COMMAND ""
+        LOG_DOWNLOAD ON
+    )
+    ExternalProject_Get_Property(boost-dbus install_dir)
+    include_directories(${install_dir}/src/boost-dbus/include)
+
+    include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/non-yocto)
+
+    ExternalProject_Add(nlohmann-json
+        PREFIX ${CMAKE_CURRENT_BINARY_DIR}/nlohmann-json
+        GIT_REPOSITORY https://github.com/nlohmann/json.git
+        GIT_TAG afebb6a3bbc8751e834a5472e5c53cb2b5bbd750
+        CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${EXTERNAL_INSTALL_LOCATION}
+        CONFIGURE_COMMAND ""
+        BUILD_COMMAND mkdir -p
+            ${CMAKE_CURRENT_BINARY_DIR}/nlohmann-json/src/nlohmann-json/src/nlohmann &&
+                cp ${CMAKE_CURRENT_BINARY_DIR}/nlohmann-json/src/nlohmann-json/src/json.hpp
+                ${CMAKE_CURRENT_BINARY_DIR}/nlohmann-json/src/nlohmann-json/src/nlohmann/json.hpp
+        INSTALL_COMMAND ""
+        LOG_DOWNLOAD ON
+    )
+
+    ExternalProject_Get_Property(nlohmann-json install_dir)
+    include_directories(${install_dir}/src/nlohmann-json/src)
+
+    option(ENABLE_TEST "Enable Google Test" OFF)
+    if(ENABLE_TEST)
+        hunter_add_package(GTest)
+        find_package(GTest CONFIG REQUIRED)
+<<<<<<< HEAD
+=======
+
+>>>>>>> da00f8f... Add CPP EntityManager Stage 1
+        enable_testing()
+    endif()
+endif()
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+link_directories(${EXTERNAL_INSTALL_LOCATION}/lib)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+add_executable(fru-device src/FruDevice.cpp src/Utils.cpp)
+add_dependencies(fru-device boost-dbus)
+
+#add_dependencies(entity-manager nlohmann-json)
+target_link_libraries(fru-device  ${DBUS_LIBRARIES})
+target_link_libraries(fru-device pthread)
+target_link_libraries(fru-device stdc++fs)
+target_link_libraries(fru-device ${Boost_LIBRARIES})
+
+add_executable(entity-manager src/EntityManager.cpp src/Utils.cpp)
+add_dependencies(entity-manager boost-dbus)
+
+add_dependencies(entity-manager nlohmann-json)
+target_link_libraries(entity-manager  ${DBUS_LIBRARIES})
+target_link_libraries(entity-manager pthread)
+target_link_libraries(entity-manager stdc++fs)
+target_link_libraries(entity-manager ${Boost_LIBRARIES})
+
+install (TARGETS fru-device entity-manager DESTINATION bin)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..fe4e02c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,204 @@
+#Entity Manager#
+
+Entity manager is a runtime configuration application which parses configuration
+files (in JSON format) and attempts to detect the devices described by the
+configuration files. It also can, based on the configuration, attempt to load
+device tree overlays to add sensors to the device tree. The output is also a
+JSON file which includes all devices in the system such as fans and temperature
+sensors.
+
+## Configuration Syntax ##
+
+In most cases a server system is built with multiple hardware modules (circuit
+boards) such as baseboard, risers, and hot-swap backplanes. While it is
+perfectly legal to combine the JSON configuration information for all the
+hardware modules into a single file if desired, it is also possible to divide
+them into multilple configuration files. For example, there may be a baseboard
+JSON file (describes all devices on the baseboard) and a chassis JSON file
+(describes devices attached to the chassis). When one of the hardware modules
+needs to be upgraded (e.g., a new temperature sensor), only such JSON
+configuration file needs to be be updated.
+
+Within a configuration file, there is a JSON object which consists of
+multiple "string : value" pairs. This Entity Manager defines the following
+strings.
+
+| String    | Example Value                            | Description                              |
+| :-------- | ---------------------------------------- | ---------------------------------------- |
+| "name"    | "X1000 1U Chassis"                       | Human readable name used for identification and sorting. |
+| "probe"   | "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME':'FFPANEL'})" | Statement which attempts to read from the hardware. The result determines if a configuration record should be applied. The value for probe can be set to “TRUE” in the case the record should always be applied, or set to more complex lookups, for instance a field in a FRU file. |
+| "exposes" | [{"name" : "CPU fan"}, ...]              | An array of JSON objects which are valid if the probe result is successful. These objects describe the devices BMC can interact. |
+| "status"  | "disabled"                               | An indicator that allows for some records to be disabled by default. |
+| "bind_*"  | "2U System Fan connector 1"              | The record isn't complete and needs to be combined with another to be functional. The value is a unique reference to a record elsewhere. |
+
+Template strings in the form of "$identifier" may be used in configuration
+files. The following table describes the template strings currently defined.
+
+| Template String | Description                              |
+| :-------------- | :--------------------------------------- |
+| "$bus"          | During a I2C bus scan and when the "probe" command is successful, this template string is substituted with the bus number to which the device is connected. |
+| "$address"   | When the "probe" is successful, this template string is substituted with the (7-bit) I2C address of the FRU device. |
+| "$index"        | A run-tim enumeration. This template string is substituted with a unique index value when the "probe" command is successful. This allows multiple identical devices (e.g., HSBPs) to exist in a system but each with a unique name. |
+
+
+
+## Configuration Records - Baseboard Example##
+
+Required fields are name, probe and exposes.
+
+The configuration JSON files attempt to model after actual hardware modules
+which made up a complete system. An example baseboard JSON file shown below
+defines two fan connectors and two temperature sensors of TMP75 type. These
+objects are considered valid by BMC when the probe command (reads and
+compares the product name in FRU) is successful and this baseboard is named
+as "WFP baseboard".
+
+```
+{
+    "exposes": [
+        {
+            "name": "1U System Fan connector 1",
+            "pwm": 1,
+            "status": "disabled",
+            "tachs": [
+                1,
+                2
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "name": "2U System Fan connector 1",
+            "pwm": 1,
+            "status": "disabled",
+            "tachs": [
+                1
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "address": "0x49",
+            "bus": 6,
+            "name": "Left Rear Temp",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 115
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 5
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0
+                    }
+                ]
+            ],
+            "type": "TMP75"
+        },
+        {
+            "address": "0x48",
+            "bus": 6,
+            "name": "Voltage Regulator 1 Temp",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 115
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 5
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0
+                    }
+                ]
+            ],
+            "type": "TMP75"
+        }
+    ],
+    "name": "WFP Baseboard",
+    "probe": "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME' : '.*WFT'})"
+}
+```
+
+####Configuration Records - Chassis Example ####
+
+Although fan connectors are considered a part of a baseboard, the physical
+fans themselves are considered as a part of a chassis. In order for a fan to
+be matched with a fan connector, the keyword "bind_connector" is used. The
+example below shows how a chassis fan named "Fan 1" is connected to the
+connector named "1U System Fan connector 1". When the probe command finds the
+correct product name in baseboard FRU, the fan and the connector are
+considered as being joined together.
+
+```
+{
+    "exposes": [
+        {
+            "bind_connector": "1U System Fan connector 1",
+            "name": "Fan 1",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1750
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 2000
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        }
+    ]
+}
+```
+
+## Enabling Sensors ##
+
+As demons can trigger off of shared types, sometimes some handshaking will be
+needed to enable sensors. Using the TMP75 sensor as an example, when the
+sensor object is enabled, the device tree must be updated before scanning may
+begin. The device tree overlay generator has the ability to key off of
+different types and create device tree overlays for specific offsets. Once
+this is done, the baseboard temperature sensor demon can scan the sensors.
+
+## Run Unit Tests ##
+
+The following environment variables need to be set to run unit tests:
+
+* TEST: 1, this disables the fru parser from scanning on init and changes the
+work directories.
diff --git a/cmake/Finddbus.cmake b/cmake/Finddbus.cmake
new file mode 100644
index 0000000..2d8eea2
--- /dev/null
+++ b/cmake/Finddbus.cmake
@@ -0,0 +1,61 @@
+# - Try to find DBus
+# Once done, this will define
+#
+#  DBUS_FOUND - system has DBus
+#  DBUS_INCLUDE_DIRS - the DBus include directories
+#  DBUS_LIBRARIES - link these to use DBus
+#
+# Copyright (C) 2012 Raphael Kubo da Costa <rakuco@webkit.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS
+# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+FIND_PACKAGE(PkgConfig)
+PKG_CHECK_MODULES(PC_DBUS QUIET dbus-1)
+
+FIND_LIBRARY(DBUS_LIBRARIES
+    NAMES dbus-1
+    HINTS ${PC_DBUS_LIBDIR}
+          ${PC_DBUS_LIBRARY_DIRS}
+)
+
+message("DBUS_LIBRARIES = ${DBUS_LIBRARIES}")
+
+FIND_PATH(DBUS_INCLUDE_DIR
+    NAMES dbus/dbus.h
+    HINTS ${PC_DBUS_INCLUDEDIR}
+          ${PC_DBUS_INCLUDE_DIRS}
+)
+
+GET_FILENAME_COMPONENT(_DBUS_LIBRARY_DIR ${DBUS_LIBRARIES} PATH)
+FIND_PATH(DBUS_ARCH_INCLUDE_DIR
+    NAMES dbus/dbus-arch-deps.h
+    HINTS ${PC_DBUS_INCLUDEDIR}
+          ${PC_DBUS_INCLUDE_DIRS}
+          ${_DBUS_LIBRARY_DIR}
+          ${DBUS_INCLUDE_DIR}
+    PATH_SUFFIXES include
+)
+
+SET(DBUS_INCLUDE_DIRS ${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR})
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(DBUS REQUIRED_VARS DBUS_INCLUDE_DIRS DBUS_LIBRARIES)
diff --git a/cmake/HunterGate.cmake b/cmake/HunterGate.cmake
new file mode 100644
index 0000000..97f69cc
--- /dev/null
+++ b/cmake/HunterGate.cmake
@@ -0,0 +1,514 @@
+# Copyright (c) 2013-2015, Ruslan Baratov
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This is a gate file to Hunter package manager.
+# Include this file using `include` command and add package you need, example:
+#
+#     cmake_minimum_required(VERSION 3.0)
+#
+#     include("cmake/HunterGate.cmake")
+#     HunterGate(
+#         URL "https://github.com/path/to/hunter/archive.tar.gz"
+#         SHA1 "798501e983f14b28b10cda16afa4de69eee1da1d"
+#     )
+#
+#     project(MyProject)
+#
+#     hunter_add_package(Foo)
+#     hunter_add_package(Boo COMPONENTS Bar Baz)
+#
+# Projects:
+#     * https://github.com/hunter-packages/gate/
+#     * https://github.com/ruslo/hunter
+
+option(HUNTER_ENABLED "Enable Hunter package manager support" ON)
+if(HUNTER_ENABLED)
+  if(CMAKE_VERSION VERSION_LESS "3.0")
+    message(FATAL_ERROR "At least CMake version 3.0 required for hunter dependency management."
+      " Update CMake or set HUNTER_ENABLED to OFF.")
+  endif()
+endif()
+
+include(CMakeParseArguments) # cmake_parse_arguments
+
+option(HUNTER_STATUS_PRINT "Print working status" ON)
+option(HUNTER_STATUS_DEBUG "Print a lot info" OFF)
+
+set(HUNTER_WIKI "https://github.com/ruslo/hunter/wiki")
+
+function(hunter_gate_status_print)
+  foreach(print_message ${ARGV})
+    if(HUNTER_STATUS_PRINT OR HUNTER_STATUS_DEBUG)
+      message(STATUS "[hunter] ${print_message}")
+    endif()
+  endforeach()
+endfunction()
+
+function(hunter_gate_status_debug)
+  foreach(print_message ${ARGV})
+    if(HUNTER_STATUS_DEBUG)
+      string(TIMESTAMP timestamp)
+      message(STATUS "[hunter *** DEBUG *** ${timestamp}] ${print_message}")
+    endif()
+  endforeach()
+endfunction()
+
+function(hunter_gate_wiki wiki_page)
+  message("------------------------------ WIKI -------------------------------")
+  message("    ${HUNTER_WIKI}/${wiki_page}")
+  message("-------------------------------------------------------------------")
+  message("")
+  message(FATAL_ERROR "")
+endfunction()
+
+function(hunter_gate_internal_error)
+  message("")
+  foreach(print_message ${ARGV})
+    message("[hunter ** INTERNAL **] ${print_message}")
+  endforeach()
+  message("[hunter ** INTERNAL **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
+  message("")
+  hunter_gate_wiki("error.internal")
+endfunction()
+
+function(hunter_gate_fatal_error)
+  cmake_parse_arguments(hunter "" "WIKI" "" "${ARGV}")
+  string(COMPARE EQUAL "${hunter_WIKI}" "" have_no_wiki)
+  if(have_no_wiki)
+    hunter_gate_internal_error("Expected wiki")
+  endif()
+  message("")
+  foreach(x ${hunter_UNPARSED_ARGUMENTS})
+    message("[hunter ** FATAL ERROR **] ${x}")
+  endforeach()
+  message("[hunter ** FATAL ERROR **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
+  message("")
+  hunter_gate_wiki("${hunter_WIKI}")
+endfunction()
+
+function(hunter_gate_user_error)
+  hunter_gate_fatal_error(${ARGV} WIKI "error.incorrect.input.data")
+endfunction()
+
+function(hunter_gate_self root version sha1 result)
+  string(COMPARE EQUAL "${root}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("root is empty")
+  endif()
+
+  string(COMPARE EQUAL "${version}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("version is empty")
+  endif()
+
+  string(COMPARE EQUAL "${sha1}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("sha1 is empty")
+  endif()
+
+  string(SUBSTRING "${sha1}" 0 7 archive_id)
+
+  if(EXISTS "${root}/cmake/Hunter")
+    set(hunter_self "${root}")
+  else()
+    set(
+        hunter_self
+        "${root}/_Base/Download/Hunter/${version}/${archive_id}/Unpacked"
+    )
+  endif()
+
+  set("${result}" "${hunter_self}" PARENT_SCOPE)
+endfunction()
+
+# Set HUNTER_GATE_ROOT cmake variable to suitable value.
+function(hunter_gate_detect_root)
+  # Check CMake variable
+  string(COMPARE NOTEQUAL "${HUNTER_ROOT}" "" not_empty)
+  if(not_empty)
+    set(HUNTER_GATE_ROOT "${HUNTER_ROOT}" PARENT_SCOPE)
+    hunter_gate_status_debug("HUNTER_ROOT detected by cmake variable")
+    return()
+  endif()
+
+  # Check environment variable
+  string(COMPARE NOTEQUAL "$ENV{HUNTER_ROOT}" "" not_empty)
+  if(not_empty)
+    set(HUNTER_GATE_ROOT "$ENV{HUNTER_ROOT}" PARENT_SCOPE)
+    hunter_gate_status_debug("HUNTER_ROOT detected by environment variable")
+    return()
+  endif()
+
+  # Check HOME environment variable
+  string(COMPARE NOTEQUAL "$ENV{HOME}" "" result)
+  if(result)
+    set(HUNTER_GATE_ROOT "$ENV{HOME}/.hunter" PARENT_SCOPE)
+    hunter_gate_status_debug("HUNTER_ROOT set using HOME environment variable")
+    return()
+  endif()
+
+  # Check SYSTEMDRIVE and USERPROFILE environment variable (windows only)
+  if(WIN32)
+    string(COMPARE NOTEQUAL "$ENV{SYSTEMDRIVE}" "" result)
+    if(result)
+      set(HUNTER_GATE_ROOT "$ENV{SYSTEMDRIVE}/.hunter" PARENT_SCOPE)
+      hunter_gate_status_debug(
+          "HUNTER_ROOT set using SYSTEMDRIVE environment variable"
+      )
+      return()
+    endif()
+
+    string(COMPARE NOTEQUAL "$ENV{USERPROFILE}" "" result)
+    if(result)
+      set(HUNTER_GATE_ROOT "$ENV{USERPROFILE}/.hunter" PARENT_SCOPE)
+      hunter_gate_status_debug(
+          "HUNTER_ROOT set using USERPROFILE environment variable"
+      )
+      return()
+    endif()
+  endif()
+
+  hunter_gate_fatal_error(
+      "Can't detect HUNTER_ROOT"
+      WIKI "error.detect.hunter.root"
+  )
+endfunction()
+
+macro(hunter_gate_lock dir)
+  if(NOT HUNTER_SKIP_LOCK)
+    if("${CMAKE_VERSION}" VERSION_LESS "3.2")
+      hunter_gate_fatal_error(
+          "Can't lock, upgrade to CMake 3.2 or use HUNTER_SKIP_LOCK"
+          WIKI "error.can.not.lock"
+      )
+    endif()
+    hunter_gate_status_debug("Locking directory: ${dir}")
+    file(LOCK "${dir}" DIRECTORY GUARD FUNCTION)
+    hunter_gate_status_debug("Lock done")
+  endif()
+endmacro()
+
+function(hunter_gate_download dir)
+  string(
+      COMPARE
+      NOTEQUAL
+      "$ENV{HUNTER_DISABLE_AUTOINSTALL}"
+      ""
+      disable_autoinstall
+  )
+  if(disable_autoinstall AND NOT HUNTER_RUN_INSTALL)
+    hunter_gate_fatal_error(
+        "Hunter not found in '${dir}'"
+        "Set HUNTER_RUN_INSTALL=ON to auto-install it from '${HUNTER_GATE_URL}'"
+        "Settings:"
+        "  HUNTER_ROOT: ${HUNTER_GATE_ROOT}"
+        "  HUNTER_SHA1: ${HUNTER_GATE_SHA1}"
+        WIKI "error.run.install"
+    )
+  endif()
+  string(COMPARE EQUAL "${dir}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("Empty 'dir' argument")
+  endif()
+
+  string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("HUNTER_GATE_SHA1 empty")
+  endif()
+
+  string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("HUNTER_GATE_URL empty")
+  endif()
+
+  set(done_location "${dir}/DONE")
+  set(sha1_location "${dir}/SHA1")
+
+  set(build_dir "${dir}/Build")
+  set(cmakelists "${dir}/CMakeLists.txt")
+
+  hunter_gate_lock("${dir}")
+  if(EXISTS "${done_location}")
+    # while waiting for lock other instance can do all the job
+    hunter_gate_status_debug("File '${done_location}' found, skip install")
+    return()
+  endif()
+
+  file(REMOVE_RECURSE "${build_dir}")
+  file(REMOVE_RECURSE "${cmakelists}")
+
+  file(MAKE_DIRECTORY "${build_dir}") # check directory permissions
+
+  # Disabling languages speeds up a little bit, reduces noise in the output
+  # and avoids path too long windows error
+  file(
+      WRITE
+      "${cmakelists}"
+      "cmake_minimum_required(VERSION 3.0)\n"
+      "project(HunterDownload LANGUAGES NONE)\n"
+      "include(ExternalProject)\n"
+      "ExternalProject_Add(\n"
+      "    Hunter\n"
+      "    URL\n"
+      "    \"${HUNTER_GATE_URL}\"\n"
+      "    URL_HASH\n"
+      "    SHA1=${HUNTER_GATE_SHA1}\n"
+      "    DOWNLOAD_DIR\n"
+      "    \"${dir}\"\n"
+      "    SOURCE_DIR\n"
+      "    \"${dir}/Unpacked\"\n"
+      "    CONFIGURE_COMMAND\n"
+      "    \"\"\n"
+      "    BUILD_COMMAND\n"
+      "    \"\"\n"
+      "    INSTALL_COMMAND\n"
+      "    \"\"\n"
+      ")\n"
+  )
+
+  if(HUNTER_STATUS_DEBUG)
+    set(logging_params "")
+  else()
+    set(logging_params OUTPUT_QUIET)
+  endif()
+
+  hunter_gate_status_debug("Run generate")
+
+  # Need to add toolchain file too.
+  # Otherwise on Visual Studio + MDD this will fail with error:
+  # "Could not find an appropriate version of the Windows 10 SDK installed on this machine"
+  if(EXISTS "${CMAKE_TOOLCHAIN_FILE}")
+    set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}")
+  else()
+    # 'toolchain_arg' can't be empty
+    set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=")
+  endif()
+
+  execute_process(
+      COMMAND "${CMAKE_COMMAND}" "-H${dir}" "-B${build_dir}" "-G${CMAKE_GENERATOR}" "${toolchain_arg}"
+      WORKING_DIRECTORY "${dir}"
+      RESULT_VARIABLE download_result
+      ${logging_params}
+  )
+
+  if(NOT download_result EQUAL 0)
+    hunter_gate_internal_error("Configure project failed")
+  endif()
+
+  hunter_gate_status_print(
+      "Initializing Hunter workspace (${HUNTER_GATE_SHA1})"
+      "  ${HUNTER_GATE_URL}"
+      "  -> ${dir}"
+  )
+  execute_process(
+      COMMAND "${CMAKE_COMMAND}" --build "${build_dir}"
+      WORKING_DIRECTORY "${dir}"
+      RESULT_VARIABLE download_result
+      ${logging_params}
+  )
+
+  if(NOT download_result EQUAL 0)
+    hunter_gate_internal_error("Build project failed")
+  endif()
+
+  file(REMOVE_RECURSE "${build_dir}")
+  file(REMOVE_RECURSE "${cmakelists}")
+
+  file(WRITE "${sha1_location}" "${HUNTER_GATE_SHA1}")
+  file(WRITE "${done_location}" "DONE")
+
+  hunter_gate_status_debug("Finished")
+endfunction()
+
+# Must be a macro so master file 'cmake/Hunter' can
+# apply all variables easily just by 'include' command
+# (otherwise PARENT_SCOPE magic needed)
+macro(HunterGate)
+  if(HUNTER_GATE_DONE)
+    # variable HUNTER_GATE_DONE set explicitly for external project
+    # (see `hunter_download`)
+    set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
+  endif()
+
+  # First HunterGate command will init Hunter, others will be ignored
+  get_property(_hunter_gate_done GLOBAL PROPERTY HUNTER_GATE_DONE SET)
+
+  if(NOT HUNTER_ENABLED)
+    # Empty function to avoid error "unknown function"
+    function(hunter_add_package)
+    endfunction()
+  elseif(_hunter_gate_done)
+    hunter_gate_status_debug("Secondary HunterGate (use old settings)")
+    hunter_gate_self(
+        "${HUNTER_CACHED_ROOT}"
+        "${HUNTER_VERSION}"
+        "${HUNTER_SHA1}"
+        _hunter_self
+    )
+    include("${_hunter_self}/cmake/Hunter")
+  else()
+    set(HUNTER_GATE_LOCATION "${CMAKE_CURRENT_LIST_DIR}")
+
+    string(COMPARE NOTEQUAL "${PROJECT_NAME}" "" _have_project_name)
+    if(_have_project_name)
+      hunter_gate_fatal_error(
+          "Please set HunterGate *before* 'project' command. "
+          "Detected project: ${PROJECT_NAME}"
+          WIKI "error.huntergate.before.project"
+      )
+    endif()
+
+    cmake_parse_arguments(
+        HUNTER_GATE "LOCAL" "URL;SHA1;GLOBAL;FILEPATH" "" ${ARGV}
+    )
+
+    string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" _empty_sha1)
+    string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" _empty_url)
+    string(
+        COMPARE
+        NOTEQUAL
+        "${HUNTER_GATE_UNPARSED_ARGUMENTS}"
+        ""
+        _have_unparsed
+    )
+    string(COMPARE NOTEQUAL "${HUNTER_GATE_GLOBAL}" "" _have_global)
+    string(COMPARE NOTEQUAL "${HUNTER_GATE_FILEPATH}" "" _have_filepath)
+
+    if(_have_unparsed)
+      hunter_gate_user_error(
+          "HunterGate unparsed arguments: ${HUNTER_GATE_UNPARSED_ARGUMENTS}"
+      )
+    endif()
+    if(_empty_sha1)
+      hunter_gate_user_error("SHA1 suboption of HunterGate is mandatory")
+    endif()
+    if(_empty_url)
+      hunter_gate_user_error("URL suboption of HunterGate is mandatory")
+    endif()
+    if(_have_global)
+      if(HUNTER_GATE_LOCAL)
+        hunter_gate_user_error("Unexpected LOCAL (already has GLOBAL)")
+      endif()
+      if(_have_filepath)
+        hunter_gate_user_error("Unexpected FILEPATH (already has GLOBAL)")
+      endif()
+    endif()
+    if(HUNTER_GATE_LOCAL)
+      if(_have_global)
+        hunter_gate_user_error("Unexpected GLOBAL (already has LOCAL)")
+      endif()
+      if(_have_filepath)
+        hunter_gate_user_error("Unexpected FILEPATH (already has LOCAL)")
+      endif()
+    endif()
+    if(_have_filepath)
+      if(_have_global)
+        hunter_gate_user_error("Unexpected GLOBAL (already has FILEPATH)")
+      endif()
+      if(HUNTER_GATE_LOCAL)
+        hunter_gate_user_error("Unexpected LOCAL (already has FILEPATH)")
+      endif()
+    endif()
+
+    hunter_gate_detect_root() # set HUNTER_GATE_ROOT
+
+    # Beautify path, fix probable problems with windows path slashes
+    get_filename_component(
+        HUNTER_GATE_ROOT "${HUNTER_GATE_ROOT}" ABSOLUTE
+    )
+    hunter_gate_status_debug("HUNTER_ROOT: ${HUNTER_GATE_ROOT}")
+    if(NOT HUNTER_ALLOW_SPACES_IN_PATH)
+      string(FIND "${HUNTER_GATE_ROOT}" " " _contain_spaces)
+      if(NOT _contain_spaces EQUAL -1)
+        hunter_gate_fatal_error(
+            "HUNTER_ROOT (${HUNTER_GATE_ROOT}) contains spaces."
+            "Set HUNTER_ALLOW_SPACES_IN_PATH=ON to skip this error"
+            "(Use at your own risk!)"
+            WIKI "error.spaces.in.hunter.root"
+        )
+      endif()
+    endif()
+
+    string(
+        REGEX
+        MATCH
+        "[0-9]+\\.[0-9]+\\.[0-9]+[-_a-z0-9]*"
+        HUNTER_GATE_VERSION
+        "${HUNTER_GATE_URL}"
+    )
+    string(COMPARE EQUAL "${HUNTER_GATE_VERSION}" "" _is_empty)
+    if(_is_empty)
+      set(HUNTER_GATE_VERSION "unknown")
+    endif()
+
+    hunter_gate_self(
+        "${HUNTER_GATE_ROOT}"
+        "${HUNTER_GATE_VERSION}"
+        "${HUNTER_GATE_SHA1}"
+        _hunter_self
+    )
+
+    set(_master_location "${_hunter_self}/cmake/Hunter")
+    if(EXISTS "${HUNTER_GATE_ROOT}/cmake/Hunter")
+      # Hunter downloaded manually (e.g. by 'git clone')
+      set(_unused "xxxxxxxxxx")
+      set(HUNTER_GATE_SHA1 "${_unused}")
+      set(HUNTER_GATE_VERSION "${_unused}")
+    else()
+      get_filename_component(_archive_id_location "${_hunter_self}/.." ABSOLUTE)
+      set(_done_location "${_archive_id_location}/DONE")
+      set(_sha1_location "${_archive_id_location}/SHA1")
+
+      # Check Hunter already downloaded by HunterGate
+      if(NOT EXISTS "${_done_location}")
+        hunter_gate_download("${_archive_id_location}")
+      endif()
+
+      if(NOT EXISTS "${_done_location}")
+        hunter_gate_internal_error("hunter_gate_download failed")
+      endif()
+
+      if(NOT EXISTS "${_sha1_location}")
+        hunter_gate_internal_error("${_sha1_location} not found")
+      endif()
+      file(READ "${_sha1_location}" _sha1_value)
+      string(COMPARE EQUAL "${_sha1_value}" "${HUNTER_GATE_SHA1}" _is_equal)
+      if(NOT _is_equal)
+        hunter_gate_internal_error(
+            "Short SHA1 collision:"
+            "  ${_sha1_value} (from ${_sha1_location})"
+            "  ${HUNTER_GATE_SHA1} (HunterGate)"
+        )
+      endif()
+      if(NOT EXISTS "${_master_location}")
+        hunter_gate_user_error(
+            "Master file not found:"
+            "  ${_master_location}"
+            "try to update Hunter/HunterGate"
+        )
+      endif()
+    endif()
+    include("${_master_location}")
+    set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
+  endif()
+endmacro()
\ No newline at end of file
diff --git a/configurations/1Ux16 Riser.json b/configurations/1Ux16 Riser.json
new file mode 100755
index 0000000..294bea6
--- /dev/null
+++ b/configurations/1Ux16 Riser.json
@@ -0,0 +1,94 @@
+[
+    {
+        "exposes": [
+            {
+                "address": "0x48",
+                "bus": "$bus",
+                "name": "Riser 1 Temp",
+                "thresholds": [
+                    [
+                        {
+                            "direction": "greater than",
+                            "name": "upper critical",
+                            "severity": 1,
+                            "value": 80
+                        },
+                        {
+                            "direction": "greater than",
+                            "name": "upper non critical",
+                            "severity": 0,
+                            "value": 75
+                        },
+                        {
+                            "direction": "less than",
+                            "name": "lower non critical",
+                            "severity": 0,
+                            "value": 5
+                        },
+                        {
+                            "direction": "less than",
+                            "name": "lower critical",
+                            "severity": 1,
+                            "value": 0
+                        }
+                    ]
+                ],
+                "type": "TMP75"
+            },
+            {
+                "address": "$address",
+                "bus": "$bus",
+                "name": "Riser 1 Fru",
+                "type": "IntelFruDevice"
+            }
+        ],
+        "name": "1Ux16 Riser 1",
+        "probe": "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'F1UL16RISER\\d', 'ADDRESS' : '0x50'})"
+    },
+    {
+        "exposes": [
+            {
+                "address": "0x49",
+                "bus": "$bus",
+                "name": "Riser 2 Temp",
+                "thresholds": [
+                    [
+                        {
+                            "direction": "greater than",
+                            "name": "upper critical",
+                            "severity": 1,
+                            "value": 80
+                        },
+                        {
+                            "direction": "greater than",
+                            "name": "upper non critical",
+                            "severity": 0,
+                            "value": 75
+                        },
+                        {
+                            "direction": "less than",
+                            "name": "lower non critical",
+                            "severity": 0,
+                            "value": 5
+                        },
+                        {
+                            "direction": "less than",
+                            "name": "lower critical",
+                            "severity": 1,
+                            "value": 0
+                        }
+                    ]
+                ],
+                "type": "TMP75"
+            },
+            {
+                "address": "$address",
+                "bus": "$bus",
+                "name": "Riser 2 Fru",
+                "type": "IntelFruDevice"
+            }
+        ],
+        "name": "1Ux16 Riser 2",
+        "probe": "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'F1UL16RISER\\d', 'ADDRESS' : '0x51'})"
+    }
+]
diff --git a/configurations/2Ux8 Riser.json b/configurations/2Ux8 Riser.json
new file mode 100755
index 0000000..8824480
--- /dev/null
+++ b/configurations/2Ux8 Riser.json
@@ -0,0 +1,94 @@
+[
+    {
+        "exposes": [
+            {
+                "address": "0x48",
+                "bus": "$bus",
+                "name": "Riser 1 Temp",
+                "thresholds": [
+                    [
+                        {
+                            "direction": "greater than",
+                            "name": "upper critical",
+                            "severity": 1,
+                            "value": 80
+                        },
+                        {
+                            "direction": "greater than",
+                            "name": "upper non critical",
+                            "severity": 0,
+                            "value": 75
+                        },
+                        {
+                            "direction": "less than",
+                            "name": "lower non critical",
+                            "severity": 0,
+                            "value": 5
+                        },
+                        {
+                            "direction": "less than",
+                            "name": "lower critical",
+                            "severity": 1,
+                            "value": 0
+                        }
+                    ]
+                ],
+                "type": "TMP75"
+            },
+            {
+                "address": "$address",
+                "bus": "$bus",
+                "name": "Riser 1 Fru",
+                "type": "IntelFruDevice"
+            }
+        ],
+        "name": "2Ux8 Riser 1",
+        "probe": "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'A2UL8RISER1', 'ADDRESS': '0x50'})"
+    },
+    {
+        "exposes": [
+            {
+                "address": "0x49",
+                "bus": "$bus",
+                "name": "Riser 2 Temp",
+                "thresholds": [
+                    [
+                        {
+                            "direction": "greater than",
+                            "name": "upper critical",
+                            "severity": 1,
+                            "value": 80
+                        },
+                        {
+                            "direction": "greater than",
+                            "name": "upper non critical",
+                            "severity": 0,
+                            "value": 75
+                        },
+                        {
+                            "direction": "less than",
+                            "name": "lower non critical",
+                            "severity": 0,
+                            "value": 5
+                        },
+                        {
+                            "direction": "less than",
+                            "name": "lower critical",
+                            "severity": 1,
+                            "value": 0
+                        }
+                    ]
+                ],
+                "type": "TMP75"
+            },
+            {
+                "address": "$address",
+                "bus": "$bus",
+                "name": "Riser 2 Fru",
+                "type": "IntelFruDevice"
+            }
+        ],
+        "name": "2Ux8 Riser 2",
+        "probe": "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'A2UL8RISER2', 'ADDRESS': '0x50'})"
+    }
+]
diff --git a/configurations/8X25 HSBP.json b/configurations/8X25 HSBP.json
new file mode 100755
index 0000000..590c058
--- /dev/null
+++ b/configurations/8X25 HSBP.json
@@ -0,0 +1,19 @@
+{
+    "exposes": [
+        {
+            "address": "0xEB",
+            "name": "HSBP $index Drive Mux",
+            "type": "GenericSMBusMux"
+        },
+        {
+            "name": "HSBP $index FRU",
+            "type": "IntelHsbpFruDevice"
+        },
+        {
+            "name": "HSBP $index Temperature",
+            "type": "IntelHsbpTempSensor"
+        }
+    ],
+    "name": "1U_HSBP",
+    "probe": "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME':'F1U8X25S3PHSBP'})"
+}
\ No newline at end of file
diff --git a/configurations/F2U12X35S3P_riser.json b/configurations/F2U12X35S3P_riser.json
new file mode 100755
index 0000000..e4c34f5
--- /dev/null
+++ b/configurations/F2U12X35S3P_riser.json
@@ -0,0 +1,94 @@
+[
+    {
+        "exposes": [
+            {
+                "address": "0x48",
+                "bus": "$bus",
+                "name": "Riser1 Temp",
+                "thresholds": [
+                    [
+                        {
+                            "direction": "greater than",
+                            "name": "upper critical",
+                            "severity": 1,
+                            "value": 80
+                        },
+                        {
+                            "direction": "greater than",
+                            "name": "upper non critical",
+                            "severity": 0,
+                            "value": 75
+                        },
+                        {
+                            "direction": "less than",
+                            "name": "lower non critical",
+                            "severity": 0,
+                            "value": 5
+                        },
+                        {
+                            "direction": "less than",
+                            "name": "lower critical",
+                            "severity": 1,
+                            "value": 0
+                        }
+                    ]
+                ],
+                "type": "TMP75"
+            },
+            {
+                "address": "$address",
+                "bus": "$bus",
+                "name": "Riser 1 Fru",
+                "type": "IntelFruDevice"
+            }
+        ],
+        "name": "2U12x35 Riser1",
+        "probe": "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'A2UL16RISER\\d', 'ADDRESS' : '0x50'})"
+    },
+    {
+        "exposes": [
+            {
+                "address": "0x49",
+                "bus": "$bus",
+                "name": "Riser2 Temp",
+                "thresholds": [
+                    [
+                        {
+                            "direction": "greater than",
+                            "name": "upper critical",
+                            "severity": 1,
+                            "value": 80
+                        },
+                        {
+                            "direction": "greater than",
+                            "name": "upper non critical",
+                            "severity": 0,
+                            "value": 75
+                        },
+                        {
+                            "direction": "less than",
+                            "name": "lower non critical",
+                            "severity": 0,
+                            "value": 5
+                        },
+                        {
+                            "direction": "less than",
+                            "name": "lower critical",
+                            "severity": 1,
+                            "value": 0
+                        }
+                    ]
+                ],
+                "type": "TMP75"
+            },
+            {
+                "address": "$address",
+                "bus": "$bus",
+                "name": "Riser 2 Fru",
+                "type": "IntelFruDevice"
+            }
+        ],
+        "name": "2U12x35 Riser2",
+        "probe": "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'A2UL16RISER\\d', 'ADDRESS' : '0x51'})"
+    }
+]
diff --git a/configurations/Intel Front Panel.json b/configurations/Intel Front Panel.json
new file mode 100755
index 0000000..c9734c5
--- /dev/null
+++ b/configurations/Intel Front Panel.json
@@ -0,0 +1,46 @@
+{
+    "exposes": [
+        {
+            "address": "$address",
+            "bus": "$bus",
+            "name": "Front Panel FRU",
+            "type": "IntelFruDevice"
+        },
+        {
+            "address": "0x4D",
+            "bus": "$bus",
+            "name": "Front Panel Temp",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 55
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 50
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 5
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0
+                    }
+                ]
+            ],
+            "type": "TMP75"
+        }
+    ],
+    "name": "Intel Front Panel",
+    "probe": ["xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'FFPANEL'})", "OR", "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'F2USTOPANEL'})"]
+}
diff --git a/configurations/R1000 Chassis.json b/configurations/R1000 Chassis.json
new file mode 100755
index 0000000..52ff90f
--- /dev/null
+++ b/configurations/R1000 Chassis.json
@@ -0,0 +1,216 @@
+{
+    "exposes": [
+        {
+            "bind_connector": "1U System Fan connector 1",
+            "name": "Fan 1",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1080
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1260
+                    }
+                ],
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1295
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        },
+        {
+            "bind_connector": "1U System Fan connector 2",
+            "name": "Fan 2",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1080
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1260
+                    }
+                ],
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1295
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        },
+        {
+            "bind_connector": "1U System Fan connector 3",
+            "name": "Fan 3",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1080
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1260
+                    }
+                ],
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1295
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        },
+        {
+            "bind_connector": "1U System Fan connector 4",
+            "name": "Fan 4",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1080
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1260
+                    }
+                ],
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1295
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        },
+        {
+            "bind_connector": "1U System Fan connector 5",
+            "name": "Fan 5",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1080
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1260
+                    }
+                ],
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1295
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        },
+        {
+            "bind_connector": "1U System Fan connector 6",
+            "name": "Fan 6",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1080
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1260
+                    }
+                ],
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1295
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        }
+    ],
+    "name": "R1000 Chassis",
+    "probe": ["FOUND('WFP Baseboard')", "AND", "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'F1UL16RISER1'})"]
+}
diff --git a/configurations/R2000 Chassis.json b/configurations/R2000 Chassis.json
new file mode 100755
index 0000000..b4c6ab0
--- /dev/null
+++ b/configurations/R2000 Chassis.json
@@ -0,0 +1,132 @@
+{
+    "exposes": [
+        {
+            "bind_connector": "2U System Fan connector 1",
+            "name": "Fan 1",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1750
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 2000
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        },
+        {
+            "bind_connector": "2U System Fan connector 2",
+            "name": "Fan 2",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1750
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 2000
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        },
+        {
+            "bind_connector": "2U System Fan connector 3",
+            "name": "Fan 3",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1750
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 2000
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        },
+        {
+            "bind_connector": "2U System Fan connector 4",
+            "name": "Fan 4",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1750
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 2000
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        },
+        {
+            "bind_connector": "2U System Fan connector 5",
+            "name": "Fan 5",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1750
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 2000
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        },
+        {
+            "bind_connector": "2U System Fan connector 6",
+            "name": "Fan 6",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1750
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 2000
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        }
+    ],
+    "name": "R2000 Chassis",
+    "probe": ["FOUND('WFP Baseboard')", "AND", "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'A2UL16RISER1'})"]
+}
diff --git a/configurations/SAS Module.json b/configurations/SAS Module.json
new file mode 100755
index 0000000..7555799
--- /dev/null
+++ b/configurations/SAS Module.json
@@ -0,0 +1,17 @@
+{
+    "exposes": [
+        {
+            "bus": "$bus",
+            "name": "SAS Module FRU",
+            "type": "IntelFruDevice"
+        },
+        {
+            "address": "0x98",
+            "bus": "$bus",
+            "name": "SAS Module Temperature",
+            "type": "TMP75"
+        }
+    ],
+    "name": "SAS Module",
+    "probe": "FALSE"
+}
diff --git a/configurations/STP Baseboard.json b/configurations/STP Baseboard.json
new file mode 100755
index 0000000..d0affc9
--- /dev/null
+++ b/configurations/STP Baseboard.json
@@ -0,0 +1,864 @@
+{
+    "exposes": [
+        {
+            "fault_led": 0,
+            "name": "4U System Fan connector 1",
+            "present": 0,
+            "pwm": 1,
+            "status": "disabled",
+            "tachs": [
+                1
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "fault_led": 1,
+            "name": "4U System Fan connector 2",
+            "present": 1,
+            "pwm": 2,
+            "status": "disabled",
+            "tachs": [
+                2
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "fault_led": 2,
+            "name": "4U System Fan connector 3",
+            "present": 2,
+            "pwm": 3,
+            "status": "disabled",
+            "tachs": [
+                3
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "fault_led": 3,
+            "name": "4U System Fan connector 4",
+            "present": 3,
+            "pwm": 4,
+            "status": "disabled",
+            "tachs": [
+                4
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "fault_led": 4,
+            "name": "4U System Fan connector 5",
+            "present": 4,
+            "pwm": 5,
+            "status": "disabled",
+            "tachs": [
+                5
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "fault_led": 5,
+            "name": "4U System Fan connector 6",
+            "present": 5,
+            "pwm": 6,
+            "status": "disabled",
+            "tachs": [
+                6
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "fault_led": 6,
+            "name": "4U CPU 0 fan connector",
+            "pwm": 7,
+            "status": "disabled",
+            "tachs": [
+                7
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "fault_led": 7,
+            "name": "4U CPU 1 fan connector",
+            "pwm": 8,
+            "status": "disabled",
+            "tachs": [
+                8
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "name": "4U System Fan connector 7",
+            "pwm": 9,
+            "status": "disabled",
+            "tachs": [
+                9
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "address": "0x48",
+            "bus": 6,
+            "name": "M dot 2 Temp",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 115
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 5
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0
+                    }
+                ]
+            ],
+            "type": "TMP75"
+        },
+        {
+            "address": "0x4F",
+            "bus": 6,
+            "name": "Memory VRM Temp",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 115
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 5
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0
+                    }
+                ]
+            ],
+            "type": "TMP75"
+        },
+        {
+            "address": "0x4E",
+            "bus": 6,
+            "name": "LR Memory Board Temp",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 115
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 5
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0
+                    }
+                ]
+            ],
+            "type": "TMP75"
+        },
+        {
+            "address": "0x4C",
+            "bus": 6,
+            "name": "BMC Temp",
+            "name1": "TMP421 Internal Temp",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 115
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 5
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0
+                    }
+                ]
+            ],
+            "type": "TMP421"
+        },
+        {
+            "address": "0x49",
+            "bus": 6,
+            "name": "CPU VR Temp",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 115
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 5
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0
+                    }
+                ]
+            ],
+            "type": "TMP75"
+        },
+        {
+            "address": "0x4D",
+            "bus": 6,
+            "name": "Ambient Temp",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 115
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 5
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0
+                    }
+                ]
+            ],
+            "type": "TMP75"
+        },
+        {
+            "index": 0,
+            "name": "PSU 12 Volt",
+            "scale_factor": 0.1124,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 13.494
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 13.101
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 10.945
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 10.616
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 1,
+            "name": "P3V3",
+            "scale_factor": 0.4107,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 3.647
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 3.066
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 3.066
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 2.974
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 2,
+            "name": "PVNN_PCH_AUX",
+            "scale_factor": 1.0,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.081
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.049
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 0.807
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0.783
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 3,
+            "name": "P1V05_PCH_AUX",
+            "scale_factor": 1.0,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.139
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.106
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 0.995
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0.966
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 4,
+            "name": "P0V83_LAN_AUX",
+            "scale_factor": 1.0,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 0.901
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 0.875
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 0.786
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0.763
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 5,
+            "name": "P5V_STBY",
+            "scale_factor": 0.2717,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 13.494
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 13.101
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 10.945
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 10.616
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 6,
+            "name": "P1V8_PCH_AUX",
+            "scale_factor": 0.7505,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.961
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.904
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1.699
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1.648
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 7,
+            "name": "P3V_BAT",
+            "scale_factor": 0.3333,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 3.296
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 3.263
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 2.457
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 2.138
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 8,
+            "name": "PVCCIN_CPU0",
+            "scale_factor": 0.7505,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 2.151
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 2.088
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1.418
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1.376
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 9,
+            "name": "PVCCIN_CPU1",
+            "scale_factor": 0.7505,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 2.151
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 2.088
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1.418
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1.376
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 10,
+            "name": "PVDDQ_ABC_CPU0",
+            "scale_factor": 1.0,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.301
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.263
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1.138
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1.104
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 11,
+            "name": "PVDDQ_DEF_CPU0",
+            "scale_factor": 1.0,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.301
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.263
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1.138
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1.104
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 12,
+            "name": "PVDDQ_ABC_CPU1",
+            "scale_factor": 1.0,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.301
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.263
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1.138
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1.104
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 13,
+            "name": "PVDDQ_DEF_CPU1",
+            "scale_factor": 1.0,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.301
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.263
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1.138
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1.104
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 14,
+            "name": "PVCCIO_CPU0",
+            "scale_factor": 1.0,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.19
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.155
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 0.752
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0.729
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 15,
+            "name": "PVCCIO_CPU1",
+            "scale_factor": 1.0,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.19
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.155
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 0.752
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0.729
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "cpu_id": 0,
+            "dimm_nums": 12,
+            "name": "Skylake CPU 0",
+            "show_core": 1,
+            "type": "SkylakeCPU"
+        },
+        {
+            "cpu_id": 1,
+            "dimm_nums": 12,
+            "name": "Skylake CPU 1",
+            "show_core": 1,
+            "type": "SkylakeCPU"
+        }
+    ],
+    "name": "STP Baseboard",
+    "probe": "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': '.*STB'})"
+}
diff --git a/configurations/STP P4000 Chassis.json b/configurations/STP P4000 Chassis.json
new file mode 100644
index 0000000..bc462ea
--- /dev/null
+++ b/configurations/STP P4000 Chassis.json
@@ -0,0 +1,132 @@
+{
+    "exposes": [
+        {
+            "bind_connector": "4U System Fan connector 1",
+            "name": "Fan 1",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1750
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 2000
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        },
+        {
+            "bind_connector": "4U System Fan connector 2",
+            "name": "Fan 2",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1750
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 2000
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        },
+        {
+            "bind_connector": "4U System Fan connector 3",
+            "name": "Fan 3",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1750
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 2000
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        },
+        {
+            "bind_connector": "4U System Fan connector 4",
+            "name": "Fan 4",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1750
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 2000
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        },
+        {
+            "bind_connector": "4U System Fan connector 5",
+            "name": "Fan 5",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1750
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 2000
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        },
+        {
+            "bind_connector": "4U System Fan connector 6",
+            "name": "Fan 6",
+            "thresholds": [
+                [
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1750
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 2000
+                    }
+                ]
+            ],
+            "type": "AspeedFan"
+        }
+    ],
+    "name": "P4000 Chassis",
+    "probe": ["FOUND('STP Baseboard')", "AND", "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'FFPANEL'})"]
+}
diff --git a/configurations/WFT Baseboard.json b/configurations/WFT Baseboard.json
new file mode 100755
index 0000000..d69ebd7
--- /dev/null
+++ b/configurations/WFT Baseboard.json
@@ -0,0 +1,857 @@
+{
+    "exposes": [
+        {
+            "name": "1U System Fan connector 1",
+            "pwm": 0,
+            "status": "disabled",
+            "tachs": [
+                0,
+                1
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "name": "1U System Fan connector 2",
+            "pwm": 1,
+            "status": "disabled",
+            "tachs": [
+                2,
+                3
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "name": "1U System Fan connector 3",
+            "pwm": 2,
+            "status": "disabled",
+            "tachs": [
+                4,
+                5
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "name": "1U System Fan connector 4",
+            "pwm": 3,
+            "status": "disabled",
+            "tachs": [
+                6,
+                7
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "name": "1U System Fan connector 5",
+            "pwm": 4,
+            "status": "disabled",
+            "tachs": [
+                8,
+                9
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "name": "1U System Fan connector 6",
+            "pwm": 5,
+            "status": "disabled",
+            "tachs": [
+                10,
+                11
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "name": "2U System Fan connector 1",
+            "pwm": 0,
+            "status": "disabled",
+            "tachs": [
+                0
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "name": "2U System Fan connector 2",
+            "pwm": 1,
+            "status": "disabled",
+            "tachs": [
+                2
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "name": "2U System Fan connector 3",
+            "pwm": 2,
+            "status": "disabled",
+            "tachs": [
+                4
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "name": "2U System Fan connector 4",
+            "pwm": 3,
+            "status": "disabled",
+            "tachs": [
+                6
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "name": "2U System Fan connector 5",
+            "pwm": 4,
+            "status": "disabled",
+            "tachs": [
+                8
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "name": "2U System Fan connector 6",
+            "pwm": 5,
+            "status": "disabled",
+            "tachs": [
+                10
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "address": "0x4A",
+            "bus": 6,
+            "name": "BMC Temp",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 115
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 5
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0
+                    }
+                ]
+            ],
+            "type": "TMP75"
+        },
+        {
+            "index": 0,
+            "name": "Baseboard 12 Volt",
+            "scale_factor": 0.1124,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 13.494
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 13.101
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 10.945
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 10.616
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "name": "CPU 1 Fan Connector",
+            "pwm": 7,
+            "status": "disabled",
+            "tachs": [
+                13
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "name": "CPU 2 Fan Connector",
+            "pwm": 8,
+            "status": "disabled",
+            "tachs": [
+                14
+            ],
+            "type": "IntelFanConnector"
+        },
+        {
+            "address": "0x49",
+            "bus": 6,
+            "name": "Left Rear Temp",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 115
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 5
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0
+                    }
+                ]
+            ],
+            "type": "TMP75"
+        },
+        {
+            "index": 4,
+            "name": "P0V83_LAN_AUX",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 0.901
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 0.875
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 0.786
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0.763
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 3,
+            "name": "P105_PCH_AUX",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.139
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.106
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 0.995
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0.966
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 5,
+            "name": "P12V_AUX",
+            "scale_factor": 0.2717,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 13.494
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 13.101
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 10.945
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 10.616
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 6,
+            "name": "P1V8_PCH",
+            "scale_factor": 0.7505,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.961
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.904
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1.699
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1.648
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 1,
+            "name": "P3V3",
+            "scale_factor": 0.4107,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 3.647
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 3.066
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 3.066
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 2.974
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 7,
+            "name": "P3VBAT",
+            "scale_factor": 0.3333,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 3.296
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 3.263
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 2.457
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 2.138
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 8,
+            "name": "PVCCIN_CPU0",
+            "scale_factor": 0.7505,
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 2.151
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 2.088
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1.418
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1.376
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 9,
+            "name": "PVCCIN_CPU1",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 2.151
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 2.088
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1.418
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1.376
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 14,
+            "name": "PVCCIO_CPU0",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.19
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.155
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 0.752
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0.729
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 15,
+            "name": "PVCCIO_CPU1",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.19
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.155
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 0.752
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0.729
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 10,
+            "name": "PVDQ_ABC_CPU0",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.301
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.263
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1.138
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1.104
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 12,
+            "name": "PVDQ_ABC_CPU1",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.301
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.263
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1.138
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1.104
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 11,
+            "name": "PVDQ_DEF_CPU0",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.301
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.263
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1.138
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1.104
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 13,
+            "name": "PVDQ_DEF_CPU1",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.301
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.263
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 1.138
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 1.104
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "index": 2,
+            "name": "PVNN_PCH_AUX",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 1.081
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 1.049
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 0.807
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0.783
+                    }
+                ]
+            ],
+            "type": "ADC"
+        },
+        {
+            "address": "0x4D",
+            "bus": 6,
+            "name": "Right Rear Board Temp",
+            "name1": "Right Rear TMP421 Internal Temp",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 115
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 5
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0
+                    }
+                ]
+            ],
+            "type": "TMP421"
+        },
+        {
+            "address": "0x48",
+            "bus": 6,
+            "name": "Voltage Regulator 1 Temp",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 115
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 5
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0
+                    }
+                ]
+            ],
+            "type": "TMP75"
+        },
+        {
+            "address": "0x4B",
+            "bus": 6,
+            "name": "Voltage Regulator 2 Temp",
+            "thresholds": [
+                [
+                    {
+                        "direction": "greater than",
+                        "name": "upper critical",
+                        "severity": 1,
+                        "value": 115
+                    },
+                    {
+                        "direction": "greater than",
+                        "name": "upper non critical",
+                        "severity": 0,
+                        "value": 110
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower non critical",
+                        "severity": 0,
+                        "value": 5
+                    },
+                    {
+                        "direction": "less than",
+                        "name": "lower critical",
+                        "severity": 1,
+                        "value": 0
+                    }
+                ]
+            ],
+            "type": "TMP75"
+        },
+        {
+            "cpu_id": 0,
+            "dimm_nums": 12,
+            "name": "Skylake CPU 0",
+            "show_core": 1,
+            "type": "SkylakeCPU"
+        },
+        {
+            "cpu_id": 1,
+            "dimm_nums": 12,
+            "name": "Skylake CPU 1",
+            "show_core": 1,
+            "type": "SkylakeCPU"
+        }
+    ],
+    "name": "WFP Baseboard",
+    "probe": "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': '.*WFT'})"
+}
\ No newline at end of file
diff --git a/docs/EntityManagerDbusAPI.md b/docs/EntityManagerDbusAPI.md
new file mode 100644
index 0000000..dc4f47e
--- /dev/null
+++ b/docs/EntityManagerDbusAPI.md
@@ -0,0 +1,133 @@
+# Entity Manager DBus API
+
+The Entity Manager is in charge of inventory management by scanning JSON files
+and representing the data on DBus in a meaningful way. For more information on
+the internal structure of the Entity Manager, please refer to the README of the
+Entity Manager. This file documents a consumers usage of the entity manager, and
+is not a description of the internal workings.
+
+## DBus Object
+
+### Object Paths:
+
+####Entities:  /xyz/openbmc_project/Inventory/Item/{Entity Type}/{Entity Name}
+
+Entities are top level json objects that describe a piece of hardware. They are
+groups of configurations with few properties of their own, they are a container
+type for most pratical purposes.
+
+####Devices : /xyz/openbmc_project/Inventory/Item/{Entity Type}/{Entity Name}/{Configuration}
+
+Configurations are components that are exposed when an entity is added to the
+"global" system configuration. An example would be a TMP75 sensor that is
+exposed when the front panel is detected.
+
+__Example__:
+
+```
+/xyz/openbmc_project/Inventory/Item/Board/Intel_Front_Panel/Front_Panel_Temp
+```
+
+###Interfaces :
+
+####xyz.openbmc_project.{InventoryType}
+
+[see upstream types](https://github.com/openbmc/phosphor-dbus-interfaces/
+tree/master/xyz/openbmc_project/Inventory/Item)
+
+* BMC
+* Board
+* Chassis
+* CPU
+* ...
+
+These types closely align with Redfish types.
+
+Entity objects describe pieces of physical hardware.
+
+#####Properties:
+
+unsigned int: num_children: Number of configurations under this entity.
+
+std::string name: name of the inventory item
+
+
+####xyz.openbmc_project.Configuration
+
+Configuration objects describe components owned by the Entity.
+
+#####Properties:
+
+Properties will contain all non-objects (simple types) exposed by the JSON.
+
+ __Example__:
+
+```
+path: /xyz/openbmc_project/Inventory/Item/Board/Intel_Front_Panel/Front_Panel_Temp
+Interface: xyz.openbmc_project.Configuration
+    string name = "front panel temp"
+    string address = "0x4D"
+    string "bus" = "1"
+```
+
+####xyz.openbmc_project.Device.{Object}.{index}
+
+{Object}s are members of the parent device that were originally described as
+dictionaries. This allows for creating more complex types, while still being
+able to get a picture of the entire system when doing a get managed objects
+method call. Array objects will be indexed zero based.
+
+#####Properties:
+
+All members of the dictonary.
+
+__Example__:
+
+```
+path: /xyz/openbmc_project/Inventory/Item/Board/Intel_Front_Panel/Front_Panel_Temp
+Interface: xyz.openbmc_project.Device.threshold.0
+    string direction = "greater than"
+    int value = 55
+```
+
+##JSON Requirements
+
+###JSON syntax requirements:
+
+Based on the above DBus object, there is an implicit requirment that device
+objects may not have more than one level deep of dictionary or list of
+dictionary. It is possible to extend in the future to allow nearly infinite
+levels deep of dictonary with extending the
+__xyz.openbmc_project.Device.{Object}__ to allow
+__xyz.openbmc_project.Device.{Object}.{SubObject}.{SubObject}__ but that
+complexity will be avoided until proven needed.
+
+__Example__:
+
+Legal:
+
+```
+exposes :
+[
+    {
+        "name" : "front panel temp",
+        "property": {"key: "value"}
+    }
+]
+```
+
+Not Legal:
+
+```
+exposes :
+[
+    {
+        "name" : "front panel temp",
+        "property": {
+            "key: {
+                "key2": "value"
+            }
+    }
+]
+
+```
diff --git a/include/Utils.hpp b/include/Utils.hpp
new file mode 100644
index 0000000..d991f0d
--- /dev/null
+++ b/include/Utils.hpp
@@ -0,0 +1,23 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#pragma once
+#include <experimental/filesystem>
+
+bool find_files(const std::experimental::filesystem::path &dir_path,
+                const std::string &match_string,
+                std::vector<std::experimental::filesystem::path> &found_paths,
+                unsigned int symlink_depth = 1);
diff --git a/include/VariantVisitors.hpp b/include/VariantVisitors.hpp
new file mode 100644
index 0000000..41997a6
--- /dev/null
+++ b/include/VariantVisitors.hpp
@@ -0,0 +1,60 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#pragma once
+#include <boost/variant.hpp>
+
+struct VariantToFloatVisitor : public boost::static_visitor<float>
+{
+    template <typename T> float operator()(const T &t) const
+    {
+        return static_cast<float>(t);
+    }
+};
+template <>
+inline float VariantToFloatVisitor::
+operator()<std::string>(const std::string &s) const
+{
+    throw std::invalid_argument("Cannot translate string to float");
+}
+
+struct VariantToIntVisitor : public boost::static_visitor<int>
+{
+    template <typename T> int operator()(const T &t) const
+    {
+        return static_cast<int>(t);
+    }
+};
+template <>
+inline int VariantToIntVisitor::
+operator()<std::string>(const std::string &s) const
+{
+    throw std::invalid_argument("Cannot translate string to int");
+}
+
+struct VariantToUnsignedIntVisitor : public boost::static_visitor<unsigned int>
+{
+    template <typename T> unsigned int operator()(const T &t) const
+    {
+        return static_cast<int>(t);
+    }
+};
+template <>
+inline unsigned int VariantToUnsignedIntVisitor::
+operator()<std::string>(const std::string &s) const
+{
+    throw std::invalid_argument("Cannot translate string to unsigned int");
+}
diff --git a/include/non-yocto/i2c-dev-user.h b/include/non-yocto/i2c-dev-user.h
new file mode 100644
index 0000000..dc4632b
--- /dev/null
+++ b/include/non-yocto/i2c-dev-user.h
@@ -0,0 +1,336 @@
+/*
+    i2c-dev.h - i2c-bus driver, char device interface
+
+    Copyright (C) 1995-97 Simon G. Vogl
+    Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+    MA 02110-1301 USA.
+*/
+
+/* $Id: i2c-dev.h 5894 2010-12-12 13:22:29Z khali $ */
+
+#ifndef LIB_I2CDEV_H
+#define LIB_I2CDEV_H
+
+#include <linux/types.h>
+#include <sys/ioctl.h>
+#include <stddef.h>
+
+
+/* -- i2c.h -- */
+
+
+/*
+ * I2C Message - used for pure i2c transaction, also from /dev interface
+ */
+struct i2c_msg {
+	__u16 addr;	/* slave address			*/
+	unsigned short flags;		
+#define I2C_M_TEN	0x10	/* we have a ten bit chip address	*/
+#define I2C_M_RD	0x01
+#define I2C_M_NOSTART	0x4000
+#define I2C_M_REV_DIR_ADDR	0x2000
+#define I2C_M_IGNORE_NAK	0x1000
+#define I2C_M_NO_RD_ACK		0x0800
+	short len;		/* msg length				*/
+	char *buf;		/* pointer to msg data			*/
+};
+
+/* To determine what functionality is present */
+
+#define I2C_FUNC_I2C			0x00000001
+#define I2C_FUNC_10BIT_ADDR		0x00000002
+#define I2C_FUNC_PROTOCOL_MANGLING	0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */
+#define I2C_FUNC_SMBUS_PEC		0x00000008
+#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL	0x00008000 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_QUICK		0x00010000 
+#define I2C_FUNC_SMBUS_READ_BYTE	0x00020000 
+#define I2C_FUNC_SMBUS_WRITE_BYTE	0x00040000 
+#define I2C_FUNC_SMBUS_READ_BYTE_DATA	0x00080000 
+#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA	0x00100000 
+#define I2C_FUNC_SMBUS_READ_WORD_DATA	0x00200000 
+#define I2C_FUNC_SMBUS_WRITE_WORD_DATA	0x00400000 
+#define I2C_FUNC_SMBUS_PROC_CALL	0x00800000 
+#define I2C_FUNC_SMBUS_READ_BLOCK_DATA	0x01000000 
+#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 
+#define I2C_FUNC_SMBUS_READ_I2C_BLOCK	0x04000000 /* I2C-like block xfer  */
+#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK	0x08000000 /* w/ 1-byte reg. addr. */
+
+#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
+                             I2C_FUNC_SMBUS_WRITE_BYTE)
+#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \
+                                  I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
+#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \
+                                  I2C_FUNC_SMBUS_WRITE_WORD_DATA)
+#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
+                                   I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
+#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
+                                  I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
+
+/* Old name, for compatibility */
+#define I2C_FUNC_SMBUS_HWPEC_CALC	I2C_FUNC_SMBUS_PEC
+
+/* 
+ * Data for SMBus Messages 
+ */
+#define I2C_SMBUS_BLOCK_MAX	32	/* As specified in SMBus standard */	
+#define I2C_SMBUS_I2C_BLOCK_MAX	32	/* Not specified but we use same structure */
+union i2c_smbus_data {
+	__u8 byte;
+	__u16 word;
+	__u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
+	                                            /* and one more for PEC */
+};
+
+/* smbus_access read or write markers */
+#define I2C_SMBUS_READ	1
+#define I2C_SMBUS_WRITE	0
+
+/* SMBus transaction types (size parameter in the above functions) 
+   Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
+#define I2C_SMBUS_QUICK		    0
+#define I2C_SMBUS_BYTE		    1
+#define I2C_SMBUS_BYTE_DATA	    2 
+#define I2C_SMBUS_WORD_DATA	    3
+#define I2C_SMBUS_PROC_CALL	    4
+#define I2C_SMBUS_BLOCK_DATA	    5
+#define I2C_SMBUS_I2C_BLOCK_BROKEN  6
+#define I2C_SMBUS_BLOCK_PROC_CALL   7		/* SMBus 2.0 */
+#define I2C_SMBUS_I2C_BLOCK_DATA    8
+
+
+/* ----- commands for the ioctl like i2c_command call:
+ * note that additional calls are defined in the algorithm and hw 
+ *	dependent layers - these can be listed here, or see the 
+ *	corresponding header files.
+ */
+				/* -> bit-adapter specific ioctls	*/
+#define I2C_RETRIES	0x0701	/* number of times a device address      */
+				/* should be polled when not            */
+                                /* acknowledging 			*/
+#define I2C_TIMEOUT	0x0702	/* set timeout - call with int 		*/
+
+
+/* this is for i2c-dev.c	*/
+#define I2C_SLAVE	0x0703	/* Change slave address			*/
+				/* Attn.: Slave address is 7 or 10 bits */
+#define I2C_SLAVE_FORCE	0x0706	/* Change slave address			*/
+				/* Attn.: Slave address is 7 or 10 bits */
+				/* This changes the address, even if it */
+				/* is already taken!			*/
+#define I2C_TENBIT	0x0704	/* 0 for 7 bit addrs, != 0 for 10 bit	*/
+
+#define I2C_FUNCS	0x0705	/* Get the adapter functionality */
+#define I2C_RDWR	0x0707	/* Combined R/W transfer (one stop only)*/
+#define I2C_PEC		0x0708	/* != 0 for SMBus PEC                   */
+
+#define I2C_SMBUS	0x0720	/* SMBus-level access */
+
+/* -- i2c.h -- */
+
+
+/* Note: 10-bit addresses are NOT supported! */
+
+/* This is the structure as used in the I2C_SMBUS ioctl call */
+struct i2c_smbus_ioctl_data {
+	char read_write;
+	__u8 command;
+	int size;
+	union i2c_smbus_data *data;
+};
+
+/* This is the structure as used in the I2C_RDWR ioctl call */
+struct i2c_rdwr_ioctl_data {
+	struct i2c_msg *msgs;	/* pointers to i2c_msgs */
+	int nmsgs;		/* number of i2c_msgs */
+};
+
+
+static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command, 
+                                     int size, union i2c_smbus_data *data)
+{
+	struct i2c_smbus_ioctl_data args;
+
+	args.read_write = read_write;
+	args.command = command;
+	args.size = size;
+	args.data = data;
+	return ioctl(file,I2C_SMBUS,&args);
+}
+
+
+static inline __s32 i2c_smbus_write_quick(int file, __u8 value)
+{
+	return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL);
+}
+	
+static inline __s32 i2c_smbus_read_byte(int file)
+{
+	union i2c_smbus_data data;
+	if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data))
+		return -1;
+	else
+		return 0x0FF & data.byte;
+}
+
+static inline __s32 i2c_smbus_write_byte(int file, __u8 value)
+{
+	return i2c_smbus_access(file,I2C_SMBUS_WRITE,value,
+	                        I2C_SMBUS_BYTE,NULL);
+}
+
+static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command)
+{
+	union i2c_smbus_data data;
+	if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
+	                     I2C_SMBUS_BYTE_DATA,&data))
+		return -1;
+	else
+		return 0x0FF & data.byte;
+}
+
+static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command, 
+                                              __u8 value)
+{
+	union i2c_smbus_data data;
+	data.byte = value;
+	return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+	                        I2C_SMBUS_BYTE_DATA, &data);
+}
+
+static inline __s32 i2c_smbus_read_word_data(int file, __u8 command)
+{
+	union i2c_smbus_data data;
+	if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
+	                     I2C_SMBUS_WORD_DATA,&data))
+		return -1;
+	else
+		return 0x0FFFF & data.word;
+}
+
+static inline __s32 i2c_smbus_write_word_data(int file, __u8 command, 
+                                              __u16 value)
+{
+	union i2c_smbus_data data;
+	data.word = value;
+	return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+	                        I2C_SMBUS_WORD_DATA, &data);
+}
+
+static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
+{
+	union i2c_smbus_data data;
+	data.word = value;
+	if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+	                     I2C_SMBUS_PROC_CALL,&data))
+		return -1;
+	else
+		return 0x0FFFF & data.word;
+}
+
+
+/* Returns the number of read bytes */
+static inline __s32 i2c_smbus_read_block_data(int file, __u8 command, 
+                                              __u8 *values)
+{
+	union i2c_smbus_data data;
+	int i;
+	if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
+	                     I2C_SMBUS_BLOCK_DATA,&data))
+		return -1;
+	else {
+		for (i = 1; i <= data.block[0]; i++)
+			values[i-1] = data.block[i];
+		return data.block[0];
+	}
+}
+
+static inline __s32 i2c_smbus_write_block_data(int file, __u8 command, 
+                                               __u8 length, const __u8 *values)
+{
+	union i2c_smbus_data data;
+	int i;
+	if (length > 32)
+		length = 32;
+	for (i = 1; i <= length; i++)
+		data.block[i] = values[i-1];
+	data.block[0] = length;
+	return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+	                        I2C_SMBUS_BLOCK_DATA, &data);
+}
+
+/* Returns the number of read bytes */
+/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
+   ask for less than 32 bytes, your code will only work with kernels
+   2.6.23 and later. */
+static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command,
+                                                  __u8 length, __u8 *values)
+{
+	union i2c_smbus_data data;
+	int i;
+
+	if (length > 32)
+		length = 32;
+	data.block[0] = length;
+	if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
+	                     length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN :
+	                      I2C_SMBUS_I2C_BLOCK_DATA,&data))
+		return -1;
+	else {
+		for (i = 1; i <= data.block[0]; i++)
+			values[i-1] = data.block[i];
+		return data.block[0];
+	}
+}
+
+static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command,
+                                                   __u8 length,
+                                                   const __u8 *values)
+{
+	union i2c_smbus_data data;
+	int i;
+	if (length > 32)
+		length = 32;
+	for (i = 1; i <= length; i++)
+		data.block[i] = values[i-1];
+	data.block[0] = length;
+	return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+	                        I2C_SMBUS_I2C_BLOCK_BROKEN, &data);
+}
+
+/* Returns the number of read bytes */
+static inline __s32 i2c_smbus_block_process_call(int file, __u8 command,
+                                                 __u8 length, __u8 *values)
+{
+	union i2c_smbus_data data;
+	int i;
+	if (length > 32)
+		length = 32;
+	for (i = 1; i <= length; i++)
+		data.block[i] = values[i-1];
+	data.block[0] = length;
+	if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+	                     I2C_SMBUS_BLOCK_PROC_CALL,&data))
+		return -1;
+	else {
+		for (i = 1; i <= data.block[0]; i++)
+			values[i-1] = data.block[i];
+		return data.block[0];
+	}
+}
+
+
+#endif /* LIB_I2CDEV_H */
diff --git a/scripts/autojson.py b/scripts/autojson.py
new file mode 100755
index 0000000..e4f2818
--- /dev/null
+++ b/scripts/autojson.py
@@ -0,0 +1,14 @@
+#!/usr/bin/python3
+# all arguments to this script are considered as json files
+# and attempted to be formatted alphabetically
+
+import json
+from sys import argv
+
+for file in argv[1:]:
+   print("formatting file {}".format(file))
+   with open(file) as f:
+      j = json.load(f)
+
+   with open(file, 'w') as f:
+      f.write(json.dumps(j, indent=4, sort_keys=True, separators=(',', ': ')))
diff --git a/src/EntityManager.cpp b/src/EntityManager.cpp
new file mode 100644
index 0000000..950644f
--- /dev/null
+++ b/src/EntityManager.cpp
@@ -0,0 +1,634 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include <Utils.hpp>
+#include <dbus/properties.hpp>
+#include <nlohmann/json.hpp>
+#include <fstream>
+#include <regex>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/container/flat_map.hpp>
+#include <boost/container/flat_set.hpp>
+#include <VariantVisitors.hpp>
+
+constexpr const char *OUTPUT_DIR = "/var/configuration/";
+constexpr const char *CONFIGURATION_DIR = "/usr/share/configurations";
+constexpr const char *TEMPLATE_CHAR = "$";
+constexpr const size_t MAX_MAPPER_DEPTH = 99;
+
+namespace fs = std::experimental::filesystem;
+struct cmp_str
+{
+    bool operator()(const char *a, const char *b) const
+    {
+        return std::strcmp(a, b) < 0;
+    }
+};
+
+// underscore T for collison with dbus c api
+enum class probe_type_codes
+{
+    FALSE_T,
+    TRUE_T,
+    AND,
+    OR,
+    FOUND
+};
+const static boost::container::flat_map<const char *, probe_type_codes, cmp_str>
+    PROBE_TYPES{{{"FALSE", probe_type_codes::FALSE_T},
+                 {"TRUE", probe_type_codes::TRUE_T},
+                 {"AND", probe_type_codes::AND},
+                 {"OR", probe_type_codes::OR},
+                 {"FOUND", probe_type_codes::FOUND}}};
+
+using GetSubTreeType = std::vector<
+    std::pair<std::string,
+              std::vector<std::pair<std::string, std::vector<std::string>>>>>;
+
+using ManagedObjectType = boost::container::flat_map<
+    dbus::object_path,
+    boost::container::flat_map<
+        std::string,
+        boost::container::flat_map<std::string, dbus::dbus_variant>>>;
+
+boost::container::flat_map<
+    std::string,
+    std::vector<boost::container::flat_map<std::string, dbus::dbus_variant>>>
+    DBUS_PROBE_OBJECTS;
+std::vector<std::string> PASSED_PROBES;
+
+// todo: pass this through nicer
+std::shared_ptr<dbus::connection> SYSTEM_BUS;
+
+// calls the mapper to find all exposed objects of an interface type
+// and creates a vector<flat_map> that contains all the key value pairs
+// getManagedObjects
+bool findDbusObjects(
+    std::shared_ptr<dbus::connection> connection,
+    std::vector<boost::container::flat_map<std::string, dbus::dbus_variant>>
+        &interfaceDevices,
+    std::string interface)
+{
+    // find all connections in the mapper that expose a specific type
+    static const dbus::endpoint mapper("xyz.openbmc_project.ObjectMapper",
+                                       "/xyz/openbmc_project/object_mapper",
+                                       "xyz.openbmc_project.ObjectMapper",
+                                       "GetSubTree");
+    dbus::message getMap = dbus::message::new_call(mapper);
+    std::vector<std::string> objects = {interface};
+    if (!getMap.pack("", MAX_MAPPER_DEPTH, objects))
+    {
+        std::cerr << "Pack Failed GetSensorSubtree\n";
+        return false;
+    }
+    dbus::message getMapResp = connection->send(getMap);
+    GetSubTreeType interfaceSubtree;
+    if (!getMapResp.unpack(interfaceSubtree))
+    {
+        std::cerr << "Error communicating to mapper\n";
+        return false;
+    }
+    boost::container::flat_set<std::string> connections;
+    for (auto &object : interfaceSubtree)
+    {
+        for (auto &connPair : object.second)
+        {
+            connections.insert(connPair.first);
+        }
+    }
+    // iterate through the connections, adding creating individual device
+    // dictionaries
+    for (auto &conn : connections)
+    {
+        auto managedObj =
+            dbus::endpoint(conn, "/", "org.freedesktop.DBus.ObjectManager",
+                           "GetManagedObjects");
+        dbus::message getManagedObj = dbus::message::new_call(managedObj);
+        dbus::message getManagedObjResp = connection->send(getManagedObj);
+        ManagedObjectType managedInterface;
+        if (!getManagedObjResp.unpack(managedInterface))
+        {
+            std::cerr << "error getting managed object for device " << conn
+                      << "\n";
+            continue;
+        }
+        for (auto &interfaceManagedObj : managedInterface)
+        {
+            auto ifaceObjFind = interfaceManagedObj.second.find(interface);
+            if (ifaceObjFind != interfaceManagedObj.second.end())
+            {
+                interfaceDevices.emplace_back(ifaceObjFind->second);
+            }
+        }
+    }
+    return true;
+}
+
+// probes interface dictionary for a key with a value that matches a regex
+bool probeDbus(
+    const std::string &interface,
+    const std::map<std::string, nlohmann::json> &matches,
+    std::vector<boost::container::flat_map<std::string, dbus::dbus_variant>>
+        &devices,
+    bool &foundProbe)
+{
+    auto &dbusObject = DBUS_PROBE_OBJECTS[interface];
+    if (dbusObject.empty())
+    {
+        if (!findDbusObjects(SYSTEM_BUS, dbusObject, interface))
+        {
+            std::cerr << "Found no dbus objects with interface "
+                      << interface << "\n";
+            foundProbe = false;
+            return false;
+        }
+    }
+    foundProbe = true;
+
+    bool foundMatch = false;
+    for (auto &device : dbusObject)
+    {
+        bool deviceMatches = true;
+        for (auto &match : matches)
+        {
+            auto deviceValue = device.find(match.first);
+            if (deviceValue != device.end())
+            {
+                switch (match.second.type())
+                {
+                case nlohmann::json::value_t::string:
+                {
+                    std::regex search(match.second.get<std::string>());
+                    std::smatch match;
+
+                    // convert value to string respresentation
+                    std::string probeValue = boost::apply_visitor(
+                        [](const auto &x) {
+                            return boost::lexical_cast<std::string>(x);
+                        },
+                        deviceValue->second);
+                    if (!std::regex_search(probeValue, match, search))
+                    {
+                        deviceMatches = false;
+                        break;
+                    }
+                    break;
+                }
+                case nlohmann::json::value_t::boolean:
+                case nlohmann::json::value_t::number_unsigned:
+                {
+                    unsigned int probeValue = boost::apply_visitor(
+                        VariantToUnsignedIntVisitor(), deviceValue->second);
+
+                    if (probeValue != match.second.get<unsigned int>())
+                    {
+                        deviceMatches = false;
+                    }
+                    break;
+                }
+                case nlohmann::json::value_t::number_integer:
+                {
+                    int probeValue = boost::apply_visitor(VariantToIntVisitor(),
+                                                          deviceValue->second);
+
+                    if (probeValue != match.second.get<int>())
+                    {
+                        deviceMatches = false;
+                    }
+                    break;
+                }
+                case nlohmann::json::value_t::number_float:
+                {
+                    float probeValue = boost::apply_visitor(
+                        VariantToFloatVisitor(), deviceValue->second);
+
+                    if (probeValue != match.second.get<float>())
+                    {
+                        deviceMatches = false;
+                    }
+                    break;
+                }
+                }
+            }
+            else
+            {
+                deviceMatches = false;
+                break;
+            }
+        }
+        if (deviceMatches)
+        {
+            devices.emplace_back(
+                boost::container::flat_map<std::string, dbus::dbus_variant>(
+                    device));
+            foundMatch = true;
+            deviceMatches = false; // for next iteration
+        }
+    }
+    return foundMatch;
+}
+
+// default probe entry point, iterates a list looking for specific types to
+// call specific probe functions
+bool probe(
+    const std::vector<std::string> probeCommand,
+    std::vector<boost::container::flat_map<std::string, dbus::dbus_variant>>
+        &foundDevs)
+{
+    const static std::regex command(R"(\((.*)\))");
+    std::smatch match;
+    bool ret = false;
+    bool cur = true;
+    probe_type_codes lastCommand = probe_type_codes::FALSE_T;
+
+    for (auto &probe : probeCommand)
+    {
+        bool foundProbe = false;
+        boost::container::flat_map<const char *, probe_type_codes,
+                                   cmp_str>::const_iterator probeType;
+
+        for (probeType = PROBE_TYPES.begin(); probeType != PROBE_TYPES.end();
+             probeType++)
+        {
+            if (probe.find(probeType->first) != std::string::npos)
+            {
+                foundProbe = true;
+                break;
+            }
+        }
+        if (foundProbe)
+        {
+            switch (probeType->second)
+            {
+            case probe_type_codes::FALSE_T:
+            {
+                return false; // todo, actually evaluate?
+                break;
+            }
+            case probe_type_codes::TRUE_T:
+            {
+                return true; // todo, actually evaluate?
+                break;
+            }
+            /*case probe_type_codes::AND:
+              break;
+            case probe_type_codes::OR:
+              break;
+              // these are no-ops until the last command switch
+              */
+            case probe_type_codes::FOUND:
+            {
+                if (!std::regex_search(probe, match, command))
+                {
+                    std::cerr << "found probe sytax error " << probe << "\n";
+                    return false;
+                }
+                std::string commandStr = *(match.begin() + 1);
+                commandStr = boost::replace_all_copy(commandStr, "'", "");
+                cur = (std::find(PASSED_PROBES.begin(), PASSED_PROBES.end(),
+                                 commandStr) != PASSED_PROBES.end());
+                break;
+            }
+            }
+        }
+        // look on dbus for object
+        else
+        {
+            if (!std::regex_search(probe, match, command))
+            {
+                std::cerr << "dbus probe sytax error " << probe << "\n";
+                return false;
+            }
+            std::string commandStr = *(match.begin() + 1);
+            // convert single ticks and single slashes into legal json
+            commandStr = boost::replace_all_copy(commandStr, "'", R"(")");
+            commandStr = boost::replace_all_copy(commandStr, R"(\)", R"(\\)");
+            auto json = nlohmann::json::parse(commandStr, nullptr, false);
+            if (json.is_discarded())
+            {
+                std::cerr << "dbus command sytax error " << commandStr << "\n";
+                return false;
+            }
+            // we can match any (string, variant) property. (string, string)
+            // does a regex
+            std::map<std::string, nlohmann::json> dbusProbeMap =
+                json.get<std::map<std::string, nlohmann::json>>();
+            auto findStart = probe.find("(");
+            if (findStart == std::string::npos)
+            {
+                return false;
+            }
+            std::string probeInterface = probe.substr(0, findStart);
+            cur =
+                probeDbus(probeInterface, dbusProbeMap, foundDevs, foundProbe);
+        }
+
+        // some functions like AND and OR only take affect after the
+        // fact
+        switch (lastCommand)
+        {
+        case probe_type_codes::AND:
+            ret = cur && ret;
+            break;
+        case probe_type_codes::OR:
+            ret = cur || ret;
+            break;
+        default:
+            ret = cur;
+            break;
+        }
+        lastCommand = probeType != PROBE_TYPES.end()
+                          ? probeType->second
+                          : probe_type_codes::FALSE_T;
+
+        if (!foundProbe)
+        {
+            std::cerr << "Illegal probe type " << probe << "\n";
+            return false;
+        }
+    }
+
+    // probe passed, but empty device
+    // todo: should this be done in main?
+    if (ret && foundDevs.size() == 0)
+    {
+        foundDevs.emplace_back(
+            boost::container::flat_map<std::string, dbus::dbus_variant>());
+    }
+    return ret;
+}
+
+int main(int argc, char **argv)
+{
+    // find configuration files
+    std::vector<fs::path> jsonPaths;
+    if (!find_files(fs::path(CONFIGURATION_DIR), R"(.*\.json)", jsonPaths, 0))
+    {
+        std::cerr << "Unable to find any configuration files in "
+                  << CONFIGURATION_DIR << "\n";
+        return 1;
+    }
+    // setup connection to dbus
+    boost::asio::io_service io;
+    SYSTEM_BUS = std::make_shared<dbus::connection>(io, dbus::bus::system);
+    dbus::DbusObjectServer objServer(SYSTEM_BUS);
+    SYSTEM_BUS->request_name("xyz.openbmc_project.EntityManager");
+
+    std::vector<nlohmann::json> configurations;
+    for (auto &jsonPath : jsonPaths)
+    {
+        std::ifstream jsonStream(jsonPath.c_str());
+        if (!jsonStream.good())
+        {
+            std::cerr << "unable to open " << jsonPath.string() << "\n";
+            continue;
+        }
+        auto data = nlohmann::json::parse(jsonStream, nullptr, false);
+        if (data.is_discarded())
+        {
+            std::cerr << "syntax error in " << jsonPath.string() << "\n";
+            continue;
+        }
+        if (data.type() == nlohmann::json::value_t::array)
+        {
+            for (auto &d : data)
+            {
+                configurations.emplace_back(d);
+            }
+        }
+        else
+        {
+            configurations.emplace_back(data);
+        }
+    }
+
+    // keep looping as long as at least 1 new probe passed, removing
+    // configurations from the memory store once the probe passes
+    bool probePassed = true;
+    nlohmann::json systemConfiguration;
+    while (probePassed)
+    {
+        probePassed = false;
+        for (auto it = configurations.begin(); it != configurations.end();)
+        {
+            bool eraseConfig = false;
+            auto findProbe = (*it).find("probe");
+            auto findName = (*it).find("name");
+
+            // check for poorly formatted fields
+            if (findProbe == (*it).end())
+            {
+                std::cerr << "configuration file missing probe:\n " << *it
+                          << "\n";
+                eraseConfig = true;
+            }
+            if (findName == (*it).end())
+            {
+                std::cerr << "configuration file missing name:\n " << *it
+                          << "\n";
+                eraseConfig = true;
+            }
+
+            nlohmann::json probeCommand;
+            if ((*findProbe).type() != nlohmann::json::value_t::array)
+            {
+                probeCommand = nlohmann::json::array();
+                probeCommand.push_back(*findProbe);
+            }
+            else
+            {
+                probeCommand = *findProbe;
+            }
+            std::vector<
+                boost::container::flat_map<std::string, dbus::dbus_variant>>
+                foundDevices;
+            if (probe(probeCommand, foundDevices))
+            {
+                eraseConfig = true;
+                probePassed = true;
+                PASSED_PROBES.push_back(*findName);
+
+                size_t foundDeviceIdx = 0;
+
+                for (auto &foundDevice : foundDevices)
+                {
+                    auto findExpose = (*it).find("exposes");
+                    if (findExpose == (*it).end())
+                    {
+                        std::cerr
+                            << "Warning, configuration file missing exposes"
+                            << *it << "\n";
+                        continue;
+                    }
+                    for (auto &expose : *findExpose)
+                    {
+                        for (auto keyPair = expose.begin();
+                             keyPair != expose.end(); keyPair++)
+                        {
+                            // fill in template characters with devices
+                            // found
+                            if (keyPair.value().type() ==
+                                nlohmann::json::value_t::string)
+                            {
+                                std::string value = keyPair.value();
+                                if (value.find(TEMPLATE_CHAR) !=
+                                    std::string::npos)
+                                {
+                                    std::string templateValue = value;
+
+                                    templateValue.erase(
+                                        0, 1); // remove template character
+
+                                    // special case index
+                                    if ("index" == templateValue)
+                                    {
+                                        keyPair.value() = foundDeviceIdx;
+                                    }
+                                    else
+                                    {
+                                        std::string subsitute;
+                                        for (auto &foundDevicePair :
+                                             foundDevice)
+                                        {
+                                            if (boost::iequals(
+                                                    foundDevicePair.first,
+                                                    templateValue))
+                                            {
+                                                // convert value to string
+                                                // respresentation
+                                                subsitute =
+                                                    boost::apply_visitor(
+                                                        [](const auto &x) {
+                                                            return boost::
+                                                                lexical_cast<
+                                                                    std::
+                                                                        string>(
+                                                                    x);
+                                                        },
+                                                        foundDevicePair.second);
+                                                break;
+                                            }
+                                        }
+                                        if (!subsitute.size())
+                                        {
+                                            std::cerr << "could not find "
+                                                      << templateValue
+                                                      << " in device "
+                                                      << expose["name"] << "\n";
+                                        }
+                                        else
+                                        {
+                                            keyPair.value() = subsitute;
+                                        }
+                                    }
+                                }
+
+                                // special case bind
+                                if (boost::starts_with(keyPair.key(), "bind_"))
+                                {
+                                    bool foundBind = false;
+                                    std::string bind = keyPair.key().substr(
+                                        sizeof("bind_") - 1);
+                                    for (auto &configuration :
+                                         systemConfiguration)
+                                    {
+                                        auto &configList =
+                                            configuration["exposes"];
+                                        for (auto exposedObjectIt =
+                                                 configList.begin();
+                                             exposedObjectIt !=
+                                             configList.end();)
+                                        {
+                                            std::string foundObjectName =
+                                                (*exposedObjectIt)["name"];
+                                            if (boost::iequals(foundObjectName,
+                                                               value))
+                                            {
+                                                (*exposedObjectIt)["status"] =
+                                                    "okay"; // todo: is this the
+                                                            // right spot?
+                                                expose[bind] =
+                                                    (*exposedObjectIt);
+                                                foundBind = true;
+                                                exposedObjectIt =
+                                                    configList.erase(
+                                                        exposedObjectIt);
+                                                break;
+                                            }
+                                            else
+                                            {
+                                                exposedObjectIt++;
+                                            }
+                                        }
+                                        if (foundBind)
+                                        {
+                                            break;
+                                        }
+                                    }
+                                    if (!foundBind)
+                                    {
+                                        std::cerr << "configuration file "
+                                                     "dependency error, "
+                                                     "could not find bind "
+                                                  << value << "\n";
+                                        return 1;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    systemConfiguration.push_back(*it);
+                    foundDeviceIdx++;
+                }
+            }
+
+            if (eraseConfig)
+            {
+                it = configurations.erase(it);
+            }
+            else
+            {
+                it++;
+            }
+        }
+    }
+    // below here is temporary, to be added to dbus
+    std::ofstream output(std::string(OUTPUT_DIR) + "system.json");
+    output << systemConfiguration.dump(4);
+    output.close();
+
+    auto flat = nlohmann::json::array();
+    for (auto &pair : nlohmann::json::iterator_wrapper(systemConfiguration))
+    {
+        auto value = pair.value();
+        auto exposes = value.find("exposes");
+        if (exposes != value.end())
+        {
+            for (auto &item : *exposes)
+            {
+                flat.push_back(item);
+            }
+        }
+    }
+    output = std::ofstream(std::string(OUTPUT_DIR) + "flattened.json");
+    output << flat.dump(4);
+    output.close();
+
+    return 0;
+}
\ No newline at end of file
diff --git a/src/FruDevice.cpp b/src/FruDevice.cpp
new file mode 100644
index 0000000..b431f81
--- /dev/null
+++ b/src/FruDevice.cpp
@@ -0,0 +1,476 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include <Utils.hpp>
+#include <boost/container/flat_map.hpp>
+#include <ctime>
+#include <dbus/connection.hpp>
+#include <dbus/endpoint.hpp>
+#include <dbus/message.hpp>
+#include <dbus/properties.hpp>
+#include <fcntl.h>
+#include <fstream>
+#include <future>
+#include <i2c-dev-user.h>
+#include <iostream>
+#include <sys/ioctl.h>
+
+namespace fs = std::experimental::filesystem;
+static constexpr bool DEBUG = false;
+static size_t UNKNOWN_BUS_OBJECT_COUNT = 0;
+
+const static constexpr char *BASEBOARD_FRU_LOCATION =
+    "/etc/fru/baseboard.fru.bin";
+
+static constexpr std::array<const char *, 5> FRU_AREAS = {
+    "INTERNAL", "CHASSIS", "BOARD", "PRODUCT", "MULTIRECORD"};
+
+using DeviceMap = boost::container::flat_map<int, std::vector<char>>;
+using BusMap = boost::container::flat_map<int, std::shared_ptr<DeviceMap>>;
+
+int get_bus_frus(int file, int first, int last, int bus,
+                 std::shared_ptr<DeviceMap> devices)
+{
+    std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> block_data;
+
+    for (int ii = first; ii <= last; ii++)
+    {
+        // Set slave address
+        if (ioctl(file, I2C_SLAVE_FORCE, ii) < 0)
+        {
+            std::cerr << "device at bus " << bus << "register " << ii
+                      << "busy\n";
+            continue;
+        }
+        // probe
+        else if (i2c_smbus_read_byte(file) < 0)
+        {
+            continue;
+        }
+
+        if (DEBUG)
+        {
+            std::cout << "something at bus " << bus << "addr " << ii << "\n";
+        }
+        if (i2c_smbus_read_i2c_block_data(file, 0x0, 0x8, block_data.data()) <
+            0)
+        {
+            std::cerr << "failed to read bus " << bus << " address " << ii
+                      << "\n";
+            continue;
+        }
+        size_t sum = 0;
+        for (int jj = 0; jj < 7; jj++)
+        {
+            sum += block_data[jj];
+        }
+        sum = (256 - sum) & 0xFF;
+
+        // check the header checksum
+        if (sum == block_data[7])
+        {
+            std::vector<char> device;
+            device.insert(device.end(), block_data.begin(),
+                          block_data.begin() + 8);
+
+            for (int jj = 1; jj <= FRU_AREAS.size(); jj++)
+            {
+                auto area_offset = device[jj];
+                if (area_offset != 0)
+                {
+                    area_offset *= 8;
+                    if (i2c_smbus_read_i2c_block_data(file, area_offset, 0x8,
+                                                      block_data.data()) < 0)
+                    {
+                        std::cerr << "failed to read bus " << bus << " address "
+                                  << ii << "\n";
+                        return -1;
+                    }
+                    int length = block_data[1] * 8;
+                    device.insert(device.end(), block_data.begin(),
+                                  block_data.begin() + 8);
+                    length -= 8;
+                    area_offset += 8;
+
+                    while (length > 0)
+                    {
+                        auto to_get = std::min(0x20, length);
+                        if (i2c_smbus_read_i2c_block_data(
+                                file, area_offset, to_get, block_data.data()) <
+                            0)
+                        {
+                            std::cerr << "failed to read bus " << bus
+                                      << " address " << ii << "\n";
+                            return -1;
+                        }
+                        device.insert(device.end(), block_data.begin(),
+                                      block_data.begin() + to_get);
+                        area_offset += to_get;
+                        length -= to_get;
+                    }
+                }
+            }
+            (*devices).emplace(ii, device);
+        }
+    }
+
+    return 0;
+}
+
+static BusMap FindI2CDevices(const std::vector<fs::path> &i2cBuses)
+{
+    static std::vector<std::future<void>> futures;
+    BusMap busMap;
+    for (auto &i2cBus : i2cBuses)
+    {
+        auto busnum = i2cBus.string();
+        auto lastDash = busnum.rfind(std::string("-"));
+        // delete everything before dash inclusive
+        if (lastDash != std::string::npos)
+        {
+            busnum.erase(0, lastDash + 1);
+        }
+        auto bus = std::stoi(busnum);
+
+        auto file = open(i2cBus.c_str(), O_RDWR);
+        if (file < 0)
+        {
+            std::cerr << "unable to open i2c device " << i2cBus.string()
+                      << "\n";
+            continue;
+        }
+        unsigned long funcs = 0;
+
+        if (ioctl(file, I2C_FUNCS, &funcs) < 0)
+        {
+            std::cerr
+                << "Error: Could not get the adapter functionality matrix bus"
+                << bus << "\n";
+            continue;
+        }
+        if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE) ||
+            !(I2C_FUNC_SMBUS_READ_I2C_BLOCK))
+        {
+            std::cerr << "Error: Can't use SMBus Receive Byte command bus "
+                      << bus << "\n";
+            continue;
+        }
+        auto &device = busMap[bus];
+        device = std::make_shared<DeviceMap>();
+
+        // todo: call with boost asio?
+        futures.emplace_back(
+            std::async(std::launch::async, [file, device, bus] {
+                //  i2cdetect by default uses the range 0x03 to 0x77, as this is
+                //  what we
+                //  have tested with, use this range. Could be changed in
+                //  future.
+                get_bus_frus(file, 0x03, 0x77, bus, device);
+                close(file);
+            }));
+    }
+    for (auto &fut : futures)
+    {
+        fut.get(); // wait for all scans
+    }
+    return busMap;
+}
+
+static const std::tm intelEpoch(void)
+{
+    std::tm val = {0};
+    val.tm_year = 1996 - 1900;
+    return val;
+}
+
+bool formatFru(const std::vector<char> &fruBytes,
+               boost::container::flat_map<std::string, std::string> &result)
+{
+    static const std::vector<const char *> CHASSIS_FRU_AREAS = {
+        "PART_NUMBER", "SERIAL_NUMBER", "CHASSIS_INFO_AM1", "CHASSIS_INFO_AM2"};
+
+    static const std::vector<const char *> BOARD_FRU_AREAS = {
+        "MANUFACTURER", "PRODUCT_NAME", "SERIAL_NUMBER", "PART_NUMBER",
+        "VERSION_ID"};
+
+    static const std::vector<const char *> PRODUCT_FRU_AREAS = {
+        "MANUFACTURER",    "PRODUCT_NAME",          "PART_NUMBER",
+        "PRODUCT_VERSION", "PRODUCT_SERIAL_NUMBER", "ASSET_TAG"};
+
+    size_t sum = 0;
+
+    if (fruBytes.size() < 8)
+    {
+        return false;
+    }
+    std::vector<char>::const_iterator fruAreaOffsetField = fruBytes.begin();
+    result["Common Format Version"] =
+        std::to_string(static_cast<int>(*fruAreaOffsetField));
+
+    const std::vector<const char *> *fieldData;
+
+    for (auto &area : FRU_AREAS)
+    {
+        fruAreaOffsetField++;
+        if (fruAreaOffsetField >= fruBytes.end())
+        {
+            return false;
+        }
+        size_t offset = (*fruAreaOffsetField) * 8;
+
+        if (offset > 1)
+        {
+            // +2 to skip format and length
+            std::vector<char>::const_iterator fruBytesIter =
+                fruBytes.begin() + offset + 2;
+
+            if (fruBytesIter >= fruBytes.end())
+            {
+                return false;
+            }
+
+            if (area == "CHASSIS")
+            {
+                result["CHASSIS_TYPE"] =
+                    std::to_string(static_cast<int>(*fruBytesIter));
+                fruBytesIter += 1;
+                fieldData = &CHASSIS_FRU_AREAS;
+            }
+            else if (area == "BOARD")
+            {
+                result["BOARD_LANGUAGE_CODE"] =
+                    std::to_string(static_cast<int>(*fruBytesIter));
+                fruBytesIter += 1;
+                if (fruBytesIter >= fruBytes.end())
+                {
+                    return false;
+                }
+
+                unsigned int minutes = *fruBytesIter |
+                                       *(fruBytesIter + 1) << 8 |
+                                       *(fruBytesIter + 2) << 16;
+                std::tm fruTime = intelEpoch();
+                time_t timeValue = mktime(&fruTime);
+                timeValue += minutes * 60;
+                fruTime = *gmtime(&timeValue);
+
+                result["BOARD_MANUFACTURE_DATE"] = asctime(&fruTime);
+                result["BOARD_MANUFACTURE_DATE"]
+                    .pop_back(); // remove trailing null
+                fruBytesIter += 3;
+                fieldData = &BOARD_FRU_AREAS;
+            }
+            else if (area == "PRODUCT")
+            {
+                result["PRODUCT_LANGUAGE_CODE"] =
+                    std::to_string(static_cast<int>(*fruBytesIter));
+                fruBytesIter += 1;
+                fieldData = &PRODUCT_FRU_AREAS;
+            }
+            else
+            {
+                continue;
+            }
+            for (auto &field : *fieldData)
+            {
+                if (fruBytesIter >= fruBytes.end())
+                {
+                    return false;
+                }
+
+                size_t length = *fruBytesIter & 0x3f;
+                fruBytesIter += 1;
+
+                if (fruBytesIter >= fruBytes.end())
+                {
+                    return false;
+                }
+
+                result[std::string(area) + "_" + field] =
+                    std::string(fruBytesIter, fruBytesIter + length);
+                fruBytesIter += length;
+                if (fruBytesIter >= fruBytes.end())
+                {
+                    std::cerr << "Warning Fru Length Mismatch:\n    ";
+                    for (auto &c : fruBytes)
+                    {
+                        std::cerr << c;
+                    }
+                    std::cerr << "\n";
+                    if (DEBUG)
+                    {
+                        for (auto &keyPair : result)
+                        {
+                            std::cerr << keyPair.first << " : "
+                                      << keyPair.second << "\n";
+                        }
+                    }
+                    return false;
+                }
+            }
+        }
+    }
+
+    return true;
+}
+
+void AddFruObjectToDbus(
+    std::shared_ptr<dbus::connection> dbusConn, std::vector<char> &device,
+    dbus::DbusObjectServer &objServer,
+    boost::container::flat_map<std::pair<size_t, size_t>,
+                               std::shared_ptr<dbus::DbusObject>>
+        &dbusObjectMap,
+    int bus, size_t address)
+{
+    boost::container::flat_map<std::string, std::string> formattedFru;
+    if (!formatFru(device, formattedFru))
+    {
+        std::cerr << "failed to format fru for device at bus " << std::hex
+                  << bus << "address " << address << "\n";
+        return;
+    }
+    auto productNameFind = formattedFru.find("BOARD_PRODUCT_NAME");
+    std::string productName;
+    if (productNameFind == formattedFru.end())
+    {
+        productNameFind = formattedFru.find("PRODUCT_PRODUCT_NAME");
+    }
+    if (productNameFind != formattedFru.end())
+    {
+        productName = productNameFind->second;
+    }
+    else
+    {
+        productName = "UNKNOWN" + std::to_string(UNKNOWN_BUS_OBJECT_COUNT);
+        UNKNOWN_BUS_OBJECT_COUNT++;
+    }
+
+    auto object =
+        objServer.add_object("/xyz/openbmc_project/FruDevice/" + productName);
+    dbusObjectMap[std::pair<size_t, size_t>(bus, address)] = object;
+
+    auto iface = std::make_shared<dbus::DbusInterface>(
+        "xyz.openbmc_project.FruDevice", dbusConn);
+    object->register_interface(iface);
+    for (auto &property : formattedFru)
+    {
+        iface->set_property(property.first, property.second);
+    }
+    // baseboard can set this to -1 to not set a bus / address
+    if (bus > 0)
+    {
+        std::stringstream data;
+        data << "0x" << std::hex << bus;
+        iface->set_property("BUS", data.str());
+        data.str("");
+        data << "0x" << std::hex << address;
+        iface->set_property("ADDRESS", data.str());
+    }
+}
+
+static bool readBaseboardFru(std::vector<char> &baseboardFru)
+{
+    // try to read baseboard fru from file
+    std::ifstream baseboardFruFile(BASEBOARD_FRU_LOCATION, std::ios::binary);
+    if (baseboardFruFile.good())
+    {
+        baseboardFruFile.seekg(0, std::ios_base::end);
+        std::streampos fileSize = baseboardFruFile.tellg();
+        baseboardFru.resize(fileSize);
+        baseboardFruFile.seekg(0, std::ios_base::beg);
+        baseboardFruFile.read(baseboardFru.data(), fileSize);
+    }
+    else
+    {
+        return false;
+    }
+    return true;
+}
+
+int main(int argc, char **argv)
+{
+    auto devDir = fs::path("/dev/");
+    auto matchString = std::string("i2c*");
+    std::vector<fs::path> i2cBuses;
+
+    if (!find_files(devDir, matchString, i2cBuses, 0))
+    {
+        std::cerr << "unable to find i2c devices\n";
+        return 1;
+    }
+    BusMap busMap = FindI2CDevices(i2cBuses);
+
+    boost::asio::io_service io;
+    auto systemBus = std::make_shared<dbus::connection>(io, dbus::bus::system);
+    dbus::DbusObjectServer objServer(systemBus);
+    systemBus->request_name("com.intel.FruDevice");
+
+    // this is a map with keys of pair(bus number, adddress) and values of the
+    // object on dbus
+    boost::container::flat_map<std::pair<size_t, size_t>,
+                               std::shared_ptr<dbus::DbusObject>>
+        dbusObjectMap;
+
+    for (auto &devicemap : busMap)
+    {
+        for (auto &device : *devicemap.second)
+        {
+            AddFruObjectToDbus(systemBus, device.second, objServer,
+                               dbusObjectMap, devicemap.first, device.first);
+        }
+    }
+
+    std::vector<char> baseboardFru;
+    if (readBaseboardFru(baseboardFru))
+    {
+        AddFruObjectToDbus(systemBus, baseboardFru, objServer, dbusObjectMap,
+                           -1, -1);
+    }
+
+    auto object = std::make_shared<dbus::DbusObject>(
+        systemBus, "/xyz/openbmc_project/FruDevice");
+    objServer.register_object(object);
+    auto iface = std::make_shared<dbus::DbusInterface>(
+        "xyz.openbmc_project.FruDeviceManager", systemBus);
+    object->register_interface(iface);
+
+    iface->register_method("ReScan", [&]() {
+        busMap = FindI2CDevices(i2cBuses);
+
+        for (auto &busObj : dbusObjectMap)
+        {
+            objServer.remove_object(busObj.second);
+        }
+        dbusObjectMap.clear();
+        UNKNOWN_BUS_OBJECT_COUNT = 0;
+
+        for (auto &devicemap : busMap)
+        {
+            for (auto &device : *devicemap.second)
+            {
+                AddFruObjectToDbus(systemBus, device.second, objServer,
+                                   dbusObjectMap, devicemap.first,
+                                   device.first);
+            }
+        }
+
+        return std::tuple<>(); // this is a bug in boost-dbus, needs some sort
+                               // of return
+    });
+
+    io.run();
+    return 0;
+}
diff --git a/src/Utils.cpp b/src/Utils.cpp
new file mode 100644
index 0000000..e63861e
--- /dev/null
+++ b/src/Utils.cpp
@@ -0,0 +1,49 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include <Utils.hpp>
+#include <experimental/filesystem>
+#include <fstream>
+#include <regex>
+
+namespace fs = std::experimental::filesystem;
+
+bool find_files(const fs::path &dir_path, const std::string &match_string,
+                std::vector<fs::path> &found_paths, unsigned int symlink_depth)
+{
+    if (!fs::exists(dir_path))
+        return false;
+
+    fs::directory_iterator end_itr;
+    std::regex search(match_string);
+    std::smatch match;
+    for (auto &p : fs::recursive_directory_iterator(dir_path))
+    {
+        std::string path = p.path().string();
+        if (!is_directory(p))
+        {
+            if (std::regex_search(path, match, search))
+                found_paths.emplace_back(p.path());
+        }
+        // since we're using a recursve iterator, these should only be symlink
+        // dirs
+        else if (symlink_depth)
+        {
+            find_files(p.path(), match_string, found_paths, symlink_depth - 1);
+        }
+    }
+    return true;
+}
\ No newline at end of file