diff --git a/xyz.openbmc_project.State.Host.cpp b/xyz.openbmc_project.State.Host.cpp
new file mode 100644
index 0000000..490d171
--- /dev/null
+++ b/xyz.openbmc_project.State.Host.cpp
@@ -0,0 +1,272 @@
+#include <algorithm>
+#include <sdbusplus/server.hpp>
+#include <sdbusplus/exception.hpp>
+#include <xyz/openbmc_project/State/Host/server.hpp>
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace State
+{
+namespace server
+{
+
+Host::Host(bus::bus& bus, const char* path)
+        : _xyz_openbmc_project_State_Host_interface(
+                bus, path, _interface, _vtable, this)
+{
+}
+
+
+
+auto Host::requestedHostTransition() const ->
+        Transition
+{
+    return _requestedHostTransition;
+}
+
+int Host::_callback_get_RequestedHostTransition(
+        sd_bus* bus, const char* path, const char* interface,
+        const char* property, sd_bus_message* reply, void* context,
+        sd_bus_error* error)
+{
+    using sdbusplus::server::binding::details::convertForMessage;
+
+    try
+    {
+        auto m = message::message(sd_bus_message_ref(reply));
+
+        auto o = static_cast<Host*>(context);
+        m.append(convertForMessage(o->requestedHostTransition()));
+    }
+    catch(sdbusplus::internal_exception_t& e)
+    {
+        sd_bus_error_set_const(error, e.name(), e.description());
+        return -EINVAL;
+    }
+
+    return true;
+}
+
+auto Host::requestedHostTransition(Transition value) ->
+        Transition
+{
+    if (_requestedHostTransition != value)
+    {
+        _requestedHostTransition = value;
+        _xyz_openbmc_project_State_Host_interface.property_changed("RequestedHostTransition");
+    }
+
+    return _requestedHostTransition;
+}
+
+int Host::_callback_set_RequestedHostTransition(
+        sd_bus* bus, const char* path, const char* interface,
+        const char* property, sd_bus_message* value, void* context,
+        sd_bus_error* error)
+{
+    try
+    {
+        auto m = message::message(sd_bus_message_ref(value));
+
+        auto o = static_cast<Host*>(context);
+
+        std::string v{};
+        m.read(v);
+        o->requestedHostTransition(convertTransitionFromString(v));
+    }
+    catch(sdbusplus::internal_exception_t& e)
+    {
+        sd_bus_error_set_const(error, e.name(), e.description());
+        return -EINVAL;
+    }
+
+    return true;
+}
+
+namespace details
+{
+namespace Host
+{
+static const auto _property_RequestedHostTransition =
+    utility::tuple_to_array(message::types::type_id<
+            std::string>());
+}
+}
+auto Host::currentHostState() const ->
+        HostState
+{
+    return _currentHostState;
+}
+
+int Host::_callback_get_CurrentHostState(
+        sd_bus* bus, const char* path, const char* interface,
+        const char* property, sd_bus_message* reply, void* context,
+        sd_bus_error* error)
+{
+    using sdbusplus::server::binding::details::convertForMessage;
+
+    try
+    {
+        auto m = message::message(sd_bus_message_ref(reply));
+
+        auto o = static_cast<Host*>(context);
+        m.append(convertForMessage(o->currentHostState()));
+    }
+    catch(sdbusplus::internal_exception_t& e)
+    {
+        sd_bus_error_set_const(error, e.name(), e.description());
+        return -EINVAL;
+    }
+
+    return true;
+}
+
+auto Host::currentHostState(HostState value) ->
+        HostState
+{
+    if (_currentHostState != value)
+    {
+        _currentHostState = value;
+        _xyz_openbmc_project_State_Host_interface.property_changed("CurrentHostState");
+    }
+
+    return _currentHostState;
+}
+
+int Host::_callback_set_CurrentHostState(
+        sd_bus* bus, const char* path, const char* interface,
+        const char* property, sd_bus_message* value, void* context,
+        sd_bus_error* error)
+{
+    try
+    {
+        auto m = message::message(sd_bus_message_ref(value));
+
+        auto o = static_cast<Host*>(context);
+
+        std::string v{};
+        m.read(v);
+        o->currentHostState(convertHostStateFromString(v));
+    }
+    catch(sdbusplus::internal_exception_t& e)
+    {
+        sd_bus_error_set_const(error, e.name(), e.description());
+        return -EINVAL;
+    }
+
+    return true;
+}
+
+namespace details
+{
+namespace Host
+{
+static const auto _property_CurrentHostState =
+    utility::tuple_to_array(message::types::type_id<
+            std::string>());
+}
+}
+
+
+namespace
+{
+/** String to enum mapping for Host::Transition */
+static const std::tuple<const char*, Host::Transition> mappingHostTransition[] =
+        {
+            std::make_tuple( "xyz.openbmc_project.State.Host.Transition.Off",                 Host::Transition::Off ),
+            std::make_tuple( "xyz.openbmc_project.State.Host.Transition.On",                 Host::Transition::On ),
+            std::make_tuple( "xyz.openbmc_project.State.Host.Transition.Reboot",                 Host::Transition::Reboot ),
+        };
+
+} // anonymous namespace
+
+auto Host::convertTransitionFromString(std::string& s) ->
+        Transition
+{
+    auto i = std::find_if(
+            std::begin(mappingHostTransition),
+            std::end(mappingHostTransition),
+            [&s](auto& e){ return 0 == strcmp(s.c_str(), std::get<0>(e)); } );
+    if (std::end(mappingHostTransition) == i)
+    {
+        throw sdbusplus::exception::InvalidEnumString();
+    }
+    else
+    {
+        return std::get<1>(*i);
+    }
+}
+
+std::string convertForMessage(Host::Transition v)
+{
+    auto i = std::find_if(
+            std::begin(mappingHostTransition),
+            std::end(mappingHostTransition),
+            [v](auto& e){ return v == std::get<1>(e); });
+    return std::get<0>(*i);
+}
+
+namespace
+{
+/** String to enum mapping for Host::HostState */
+static const std::tuple<const char*, Host::HostState> mappingHostHostState[] =
+        {
+            std::make_tuple( "xyz.openbmc_project.State.Host.HostState.Off",                 Host::HostState::Off ),
+            std::make_tuple( "xyz.openbmc_project.State.Host.HostState.Running",                 Host::HostState::Running ),
+        };
+
+} // anonymous namespace
+
+auto Host::convertHostStateFromString(std::string& s) ->
+        HostState
+{
+    auto i = std::find_if(
+            std::begin(mappingHostHostState),
+            std::end(mappingHostHostState),
+            [&s](auto& e){ return 0 == strcmp(s.c_str(), std::get<0>(e)); } );
+    if (std::end(mappingHostHostState) == i)
+    {
+        throw sdbusplus::exception::InvalidEnumString();
+    }
+    else
+    {
+        return std::get<1>(*i);
+    }
+}
+
+std::string convertForMessage(Host::HostState v)
+{
+    auto i = std::find_if(
+            std::begin(mappingHostHostState),
+            std::end(mappingHostHostState),
+            [v](auto& e){ return v == std::get<1>(e); });
+    return std::get<0>(*i);
+}
+
+const vtable::vtable_t Host::_vtable[] = {
+    vtable::start(),
+    vtable::property("RequestedHostTransition",
+                     details::Host::_property_RequestedHostTransition
+                        .data(),
+                     _callback_get_RequestedHostTransition,
+                     _callback_set_RequestedHostTransition,
+                     vtable::property_::emits_change),
+    vtable::property("CurrentHostState",
+                     details::Host::_property_CurrentHostState
+                        .data(),
+                     _callback_get_CurrentHostState,
+                     _callback_set_CurrentHostState,
+                     vtable::property_::emits_change),
+    vtable::end()
+};
+
+} // namespace server
+} // namespace State
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
