diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1987450e7ed2fede863b9a58b8bb5e53bd76049d..ae3df2a49f570379784be49007b6d77321248a56 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
 cmake_minimum_required(VERSION 3.6)
 
-project(SmartGridModell)
+project(SmartGridModel)
 set(CMAKE_CXX_STANDARD 17)
 
 # Add spdlog for nice and easy logging
@@ -32,32 +32,35 @@ include_directories(src/i2c)
 include_directories(src/smart_grid)
 
 add_executable(smart_grid.exe
-    src/smg_server.cpp
-    src/smart_grid/SmartGridModell.cpp
-    src/smart_grid/StateLogger.cpp
+    src/apps/smart_grid/smg_server.cpp
+    src/apps/smart_grid/SmgStateMachine.cpp
+    src/apps/smart_grid/SmartOpcServer.cpp
+    src/smart_grid/SmartGridModel.cpp
+    # src/smart_grid/StateLogger.cpp
     src/i2c/Node.cpp
     src/com/Socket.cpp
     src/com/Protocol.cpp
-    src/smart_grid/ModelState.cpp
+    src/smart_grid/HardwareControl.cpp
 )
 
 target_link_libraries(smart_grid.exe spdlog)
 target_compile_options(smart_grid.exe PRIVATE -Wall -Wextra -pedantic)
-
+target_include_directories(smart_grid.exe PUBLIC libs/freeopcua/include)
+target_link_libraries(smart_grid.exe opcuacore opcuaserver)
 
 # Add OPC UA
 # macro(SET_OPTION option value)
 #   set(${option} ${value} CACHE "" INTERNAL FORCE)
 # endmacro()
-option(BUILD_CLIENT "Build Client" OFF)
-option(BUILD_SERVER "Build Server" ON)
+# option(BUILD_CLIENT "Build Client" OFF)
+# option(BUILD_SERVER "Build Server" ON)
 
-option(SSL_SUPPORT_MBEDTLS "Support rsa-oaep password encryption using mbedtls library " OFF)
+# option(SSL_SUPPORT_MBEDTLS "Support rsa-oaep password encryption using mbedtls library " OFF)
 
-option(BUILD_PYTHON "Build Python bindings" OFF)
-option(BUILD_TESTING "Build and run tests" OFF)
-option(BUILD_SHARED_LIBS "Build shared libraries." ON)
-add_subdirectory(libs/freeopcua)
+# option(BUILD_PYTHON "Build Python bindings" OFF)
+# option(BUILD_TESTING "Build and run tests" OFF)
+# option(BUILD_SHARED_LIBS "Build shared libraries." ON)
+# add_subdirectory(libs/freeopcua)
 
 add_executable(opc_server.exe src/apps/SmgOPC_server/opc_server.cpp)
 target_include_directories(opc_server.exe PUBLIC libs/freeopcua/include)
diff --git a/src/apps/SmgOPC_server/opc_server.cpp b/src/apps/SmgOPC_server/opc_server.cpp
index a1e68f123e9b4bcced6af0b7367633aea8f5dc91..b9bc21c935cd46b79f86f56770980ccf91a3982a 100644
--- a/src/apps/SmgOPC_server/opc_server.cpp
+++ b/src/apps/SmgOPC_server/opc_server.cpp
@@ -13,20 +13,37 @@ std::vector<OpcUa::Variant> my_method(NodeId context, std::vector<OpcUa::Variant
 {
     std::cout << "Method triggered" << std::endl;
     std::cout << renewable.GetValue().ToString() << std::endl;
+    std::cout << renewable.GetValue().Type() << std::endl;
+
+    auto vv = renewable.GetValue().As<double>();
+    vv += 1;
+    //renewable.SetValue(Variant(vv));
 
     std::vector<OpcUa::Variant> result;
     result.push_back(Variant(static_cast<uint8_t>(0)));
     return result;
 }
 
+class SubClient : public SubscriptionHandler
+{
+  void DataChange(uint32_t handle, const Node & node, const Variant & val, AttributeId attr) override
+  {
+    std::cout << "Received DataChange event for Node " << node << std::endl;
+
+  }
+};
+
 void add_nodes_to(uint32_t idx, Node &objects)
 {
     Node smart_grid = objects.AddFolder(idx, "smart_grid");
     renewable = smart_grid.AddVariable(idx, "renewable_power", Variant(42.0));
     Node prop = smart_grid.AddProperty(idx, "a_property_thin", Variant("something"));
     Node method = smart_grid.AddMethod(idx, "trigger_method_x", my_method);
-}
 
+    SubClient clt;
+    auto sub = server.CreateSubscription(100, clt);
+    sub->SubscribeDataChange(renewable);
+}
 
 int main(int argc, char **argv)
 {
@@ -42,9 +59,11 @@ int main(int argc, char **argv)
 
     add_nodes_to(idx, objects);
 
+
     while (true)
     {
-        std::this_thread::sleep_for(std::chrono::seconds(1));
+        std::this_thread::sleep_for(std::chrono::seconds(10));
+
     }
 
     return 0;
diff --git a/src/apps/smart_grid/SmartOpcServer.cpp b/src/apps/smart_grid/SmartOpcServer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9283130a6705f2befee97bfed211e01ca8a4eca2
--- /dev/null
+++ b/src/apps/smart_grid/SmartOpcServer.cpp
@@ -0,0 +1,98 @@
+///
+
+#include "SmartOpcServer.hpp"
+
+using namespace OpcUa;
+
+
+class SubClientTime : public SubscriptionHandler
+{
+public:
+    SubClientTime(SmartGridModel &model)
+        : m_model{model}{}
+
+private:
+    void DataChange(uint32_t handle, const Node &node, const Variant &val, AttributeId attr) override
+    {
+        auto v = val.As<int>();
+        m_model.set_time(v);
+    }
+    SmartGridModel &m_model;
+};
+
+class SubClientProductionEnabled : public SubscriptionHandler
+{
+public:
+    SubClientProductionEnabled(SmartGridModel &model) : m_model{model}{}
+
+private:
+    void DataChange(uint32_t handle, const Node &node, const Variant &val, AttributeId attr) override
+    {
+        auto v = val.As<bool>();
+        m_model.set_producing_state(v);
+    }
+    SmartGridModel &m_model;
+};
+
+class SubClientSimModeEnabled : public SubscriptionHandler
+{
+public:
+   SubClientSimModeEnabled(SmgStateMachine &state_machine) : m_state_machine{state_machine}{}
+
+private:
+    void DataChange(uint32_t handle, const Node &node, const Variant &val, AttributeId attr) override
+    {
+        auto v = val.As<bool>();
+        m_state_machine.set_sim_mode_enabled(v);
+    }
+    SmgStateMachine &m_state_machine;
+};
+
+
+SmartOpcServer::SmartOpcServer(SmgStateMachine &state_machine)
+    : m_state_machine{state_machine}
+{
+    m_logger = spdlog::stderr_color_mt("server");
+    m_server = UaServer(m_logger);
+    m_server.SetEndpoint(k_opc_server_url);
+    m_server.SetServerURI("Smart Grid OPC UA server");
+}
+
+void SmartOpcServer::setup_server()
+{
+    m_server.Start();
+    m_idx = m_server.RegisterNamespace("https://gitlab.cvh-server.de/aco/smart-grid-modell");
+    m_objects_folder = m_server.GetObjectsNode();
+    m_root_node = m_server.GetRootNode();
+
+    Node smart_grid_folder{m_objects_folder.AddFolder(m_idx, "smart_grid_model")};
+
+    m_state = smart_grid_folder.AddObject(m_idx, "state");
+    m_time = m_state.AddVariable(m_idx, "time", Variant(m_state_machine.m_model.get_time()));
+    m_excess_power = m_state.AddVariable(m_idx, "excess_power", Variant(m_state_machine.m_model.get_excess_power()));
+
+    m_controls = smart_grid_folder.AddObject(m_idx, "controls");
+    m_producing = m_controls.AddVariable(m_idx, "producing", Variant(m_state_machine.m_model.get_producing_state()));
+    m_sim_mode_enabled = m_controls.AddVariable(m_idx, "sim_mode_enabled", Variant(m_state_machine.is_sim_mode_enabled()));
+}
+
+
+void SmartOpcServer::run_server()
+{
+    setup_server();
+
+    SubClientTime subcl_time{m_state_machine.m_model};
+    auto sub_time = m_server.CreateSubscription(100, subcl_time);
+    sub_time->SubscribeDataChange(m_time);
+
+    SubClientProductionEnabled subcl_production_enabled{m_state_machine.m_model};
+    auto sub_production_enabled = m_server.CreateSubscription(100, subcl_production_enabled);
+    sub_production_enabled->SubscribeDataChange(m_producing);
+
+
+    while(true)
+    {
+        m_state_machine.run();
+        std::this_thread::sleep_for(std::chrono::seconds(1));
+    }
+}
\ No newline at end of file
diff --git a/src/apps/smart_grid/SmartOpcServer.hpp b/src/apps/smart_grid/SmartOpcServer.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2ad423112d011bf4beb85253f7aed28f611d5ac9
--- /dev/null
+++ b/src/apps/smart_grid/SmartOpcServer.hpp
@@ -0,0 +1,47 @@
+
+#ifndef SMART_OPC_SERVER_HPP
+#define SMART_OPC_SERVER_HPP
+
+#include <thread>
+#include <chrono>
+#include <string>
+
+#include <opc/ua/node.h>
+#include <opc/ua/subscription.h>
+#include <opc/ua/server/server.h>
+
+#include "SmgStateMachine.hpp"
+
+const char* k_opc_server_url = "opc.tcp://localhost:4840/opcua/smart-grid-model";
+
+class SmartOpcServer
+{
+public:
+    SmartOpcServer(SmgStateMachine &state_machine);
+
+    void run_server();
+
+private:
+    void setup_server();
+
+    SmgStateMachine &m_state_machine;
+
+    OpcUa::UaServer m_server;
+    uint32_t m_idx; // namespace index in server
+    OpcUa::Node m_objects_folder; // address space for node objects
+    OpcUa::Node m_root_node;
+
+    OpcUa::Node m_state;
+    OpcUa::Node m_time;
+    OpcUa::Node m_excess_power;
+
+    OpcUa::Node m_controls;
+    OpcUa::Node m_producing;
+    OpcUa::Node m_sim_mode_enabled;
+
+    std::shared_ptr<spdlog::logger> m_logger;
+
+};
+
+
+#endif
\ No newline at end of file
diff --git a/src/apps/smart_grid/SmgStateMachine.cpp b/src/apps/smart_grid/SmgStateMachine.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3b885ed4639ece6695dd06f4cc4fc9774d70e4b2
--- /dev/null
+++ b/src/apps/smart_grid/SmgStateMachine.cpp
@@ -0,0 +1,95 @@
+///
+
+#include "SmgStateMachine.hpp"
+
+SmgStateMachine::SmgStateMachine(SmartGridModel &model)
+    : m_model{model}
+{
+}
+
+
+void SmgStateMachine::run()
+{
+    if (m_state_machine_is_running)
+    {
+        switch (m_main_state)
+        {
+        case MainState::Simulation:
+            simulation_state();
+            break;
+        case MainState::ManualControl:
+            manual_state();
+            break;
+        }
+    }
+}
+
+
+void SmgStateMachine::simulation_state()
+{
+    switch (m_sim_state)
+    {
+    case SimState::Entry:
+        m_sim_state = SimState::Do;
+        break;
+    case SimState::Do:
+            m_model.next_hour();
+            if (false) // some external condition
+            {
+                m_sim_state = SimState::Exit;
+            }
+        break;
+    case SimState::Exit:
+        m_sim_state = SimState::Entry;
+        m_main_state = MainState::ManualControl;
+        m_manual_state = ManualState::Entry;
+        break;
+    }
+}
+
+void SmgStateMachine::manual_state()
+{
+    switch (m_manual_state)
+    {
+    case ManualState::Entry:
+        m_manual_state = ManualState::Do;
+        break;
+    case ManualState::Do:
+
+        // apply changes
+        m_model.update_states();
+        if (false) // some external condition
+        {
+            m_manual_state = ManualState::Exit;
+        }
+        break;
+    case ManualState::Exit:
+        m_manual_state = ManualState::Entry;
+        m_main_state = MainState::Simulation;
+        m_sim_state = SimState::Entry;
+        break;
+    }
+}
+
+bool SmgStateMachine::is_sim_mode_enabled()
+{
+    return MainState::Simulation == m_main_state;
+}
+
+void SmgStateMachine::set_sim_mode_enabled(bool enable)
+{
+    if (enable)
+    {
+        if (m_main_state == MainState::ManualControl)
+        {
+            m_manual_state = ManualState::Exit;
+        }
+    }
+    else
+    {
+        if (m_main_state == MainState::Simulation)
+        {
+            m_sim_state = SimState::Exit;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/apps/smart_grid/SmgStateMachine.hpp b/src/apps/smart_grid/SmgStateMachine.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..501a62413c8e2d57d4e13dc013ff84c3dc3adf02
--- /dev/null
+++ b/src/apps/smart_grid/SmgStateMachine.hpp
@@ -0,0 +1,51 @@
+///
+
+#ifndef SMG_STATE_MACHINE_HPP
+#define SMG_STATE_MACHINE_HPP
+
+#include "SmartGridModel.hpp"
+#include "HardwareControl.hpp"
+
+enum class MainState
+{
+    Simulation,
+    ManualControl
+};
+
+enum class SimState
+{
+    Entry,
+    Do,
+    Exit
+};
+
+enum class ManualState
+{
+    Entry,
+    Do,
+    Exit
+};
+
+
+class SmgStateMachine
+{
+public:
+    SmgStateMachine(SmartGridModel &model);
+    void run();
+    bool is_sim_mode_enabled();
+    void set_sim_mode_enabled(bool enable);
+
+    SmartGridModel &m_model;
+private:
+
+    void simulation_state();
+    void manual_state();
+
+
+    bool m_state_machine_is_running {true};
+    MainState m_main_state {MainState::Simulation};
+    SimState m_sim_state {SimState::Entry};
+    ManualState m_manual_state {ManualState::Entry};
+};
+
+#endif
\ No newline at end of file
diff --git a/src/apps/smart_grid/smg_server.cpp b/src/apps/smart_grid/smg_server.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..34f0daf75edf4b96ca3dc96c5b234a6787d8e39b
--- /dev/null
+++ b/src/apps/smart_grid/smg_server.cpp
@@ -0,0 +1,51 @@
+/// @file   main.cpp
+///
+#include <thread>
+#include "spdlog/spdlog.h"
+
+#include "i2c/Node.hpp"
+#include "HardwareControl.hpp"
+
+#include "Socket.hpp"
+#include "Protocol.hpp"
+
+#include "SmartGridModel.hpp"
+#include "SmgStateMachine.hpp"
+
+/// @brief Log user inputs
+///
+void log_args(int argc, char **argv)
+{
+    spdlog::debug("User arguments:");
+    for (int i = 0; i < argc; ++i)
+    {
+        spdlog::debug("[{}] {}", i, argv[i]);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    spdlog::set_level(spdlog::level::info);
+    spdlog::info("Starting - Smart Grid Modell");
+    log_args(argc, argv);
+
+    uint8_t slave_address{0x14};
+    i2c::Node i2c_channel{slave_address};
+    if (false == i2c_channel.open_device("/dev/i2c-1"))
+    {
+        exit(1);
+    }
+
+    HardwareControl hardware{i2c_channel};
+    SmartGridModel model{hardware};
+    SmgStateMachine stateMachine{model};
+
+    // auto log = std::make_shared<StateLogger>();
+    // model.attach(log);
+
+    // run state machine
+    stateMachine.run();
+
+    spdlog::info("End");
+    return 0;
+}
diff --git a/src/smart_grid/SmartGridModell.cpp b/src/smart_grid/HardwareControl.cpp
similarity index 73%
rename from src/smart_grid/SmartGridModell.cpp
rename to src/smart_grid/HardwareControl.cpp
index cef86c005a0d716fe3e442f3022af8e643f3c1e1..62c0c9a5cd295b6eae6d1739d429cb945014aa63 100644
--- a/src/smart_grid/SmartGridModell.cpp
+++ b/src/smart_grid/HardwareControl.cpp
@@ -1,24 +1,24 @@
-/// @file SmartGridModell.cpp
-/// @
+/// @file HardwareControl.cpp
+///
 
-#include <SmartGridModell.hpp>
+#include <HardwareControl.hpp>
 #include <spdlog/spdlog.h>
 
 #include <thread>
 
-SmartGridModell::SmartGridModell(i2c::Node& node, DefaultState initial_state)
+HardwareControl::HardwareControl(i2c::Node& node, DefaultState initial_state)
     : m_modell{node}
 {
     put_modell_into_state(initial_state);
 }
 
-SmartGridModell::~SmartGridModell()
+HardwareControl::~HardwareControl()
 {
-    // put_modell_into_state(DefaultState::Off);
+    put_modell_into_state(DefaultState::Off);
 }
 
 
-void SmartGridModell::put_modell_into_state(DefaultState state)
+void HardwareControl::put_modell_into_state(DefaultState state) const
 {
     switch (state)
     {
@@ -34,7 +34,7 @@ void SmartGridModell::put_modell_into_state(DefaultState state)
 }
 
 
-void SmartGridModell::default_state_off()
+void HardwareControl::default_state_off() const
 {
     update_windmill_speed(0);
     set_village_color(0, 0);
@@ -45,7 +45,7 @@ void SmartGridModell::default_state_off()
 }
 
 
-void SmartGridModell::default_state_fancy()
+void HardwareControl::default_state_fancy() const
 {
     update_windmill_speed(50);
     set_village_color(20, 20);
@@ -56,7 +56,7 @@ void SmartGridModell::default_state_fancy()
 }
 
 
-void SmartGridModell::update_windmill_speed(uint8_t speed)
+void HardwareControl::update_windmill_speed(uint8_t speed) const
 {
     constexpr uint8_t min_motor_speed {40};
     if (speed == 0)
@@ -78,7 +78,7 @@ void SmartGridModell::update_windmill_speed(uint8_t speed)
 }
 
 
-void SmartGridModell::set_village_color(uint8_t red, uint8_t green)
+void HardwareControl::set_village_color(uint8_t red, uint8_t green) const
 {
     set_output_pin(Pin::VillageNetRed, red);
     set_output_pin(Pin::VillageNetGreen, green);
@@ -93,28 +93,28 @@ void SmartGridModell::set_village_color(uint8_t red, uint8_t green)
     }
 }
 
-void SmartGridModell::set_power_plant(uint8_t brightness)
+void HardwareControl::set_power_plant(uint8_t brightness) const
 {
     set_output_pin(Pin::PowerPlantNet, brightness);
 }
 
-void SmartGridModell::set_solar_plant(uint8_t brightness)
+void HardwareControl::set_solar_plant(uint8_t brightness) const
 {
     set_output_pin(Pin::SolarFieldNet, brightness);
 }
 
-void SmartGridModell::set_windmill_net(uint8_t brightness)
+void HardwareControl::set_windmill_net(uint8_t brightness) const
 {
     set_output_pin(Pin::WindmillNet, brightness);
 }
 
-void SmartGridModell::set_renewable_net(uint8_t brightness)
+void HardwareControl::set_renewable_net(uint8_t brightness) const
 {
     set_output_pin(Pin::WindAndSolarNet, brightness);
 }
 
 
-void SmartGridModell::set_output_pin(Pin pin, uint8_t value)
+void HardwareControl::set_output_pin(Pin pin, uint8_t value) const
 {
     bool succ = m_modell.send(static_cast<uint8_t>(pin), value);
     spdlog::debug("Send: {} {}, success: {}", pin, value, succ);
@@ -122,7 +122,7 @@ void SmartGridModell::set_output_pin(Pin pin, uint8_t value)
     this_thread::sleep_for(chrono::milliseconds(14));
 }
 
-void SmartGridModell::set_house_color(House number, uint8_t red, uint8_t green)
+void HardwareControl::set_house_color(House number, uint8_t red, uint8_t green) const
 {
     switch (number)
     {
diff --git a/src/smart_grid/SmartGridModell.hpp b/src/smart_grid/HardwareControl.hpp
similarity index 80%
rename from src/smart_grid/SmartGridModell.hpp
rename to src/smart_grid/HardwareControl.hpp
index de4f792812aa961f141285d857f90f2bc1ba0587..055d01d35104eedbc9aa2898f1460350bc98581b 100644
--- a/src/smart_grid/SmartGridModell.hpp
+++ b/src/smart_grid/HardwareControl.hpp
@@ -1,12 +1,12 @@
 
 
-#ifndef SMART_GRID_MODELL_HEADER
-#define SMART_GRID_MODELL_HEADER
+#ifndef HARDWARE_CONTROL_HEADER
+#define HARDWARE_CONTROL_HEADER
 
 
 #include <i2c/Node.hpp>
 
-class SmartGridModell
+class HardwareControl
 {
 public:
 
@@ -56,16 +56,16 @@ public:
 
     /// @brief Initialiese modell with everything off.
     ///
-    SmartGridModell(i2c::Node& node, DefaultState initial_state = DefaultState::Off);
+    HardwareControl(i2c::Node& node, DefaultState initial_state = DefaultState::Off);
 
-    ~SmartGridModell();
+    ~HardwareControl();
 
 
     /// @brief Put the to one of the predefined states.
     /// 
     /// @param state Default state to which the modell will be changed.
     ///
-    void put_modell_into_state(DefaultState state);
+    void put_modell_into_state(DefaultState state) const;
 
     /// @brief Set the turning speed of the windmill.
     /// @details 
@@ -74,39 +74,39 @@ public:
     ///
     /// @param speed Turning speed of the windmill.
     ///
-    void update_windmill_speed(uint8_t speed);
+    void update_windmill_speed(uint8_t speed) const;
     
     /// @brief Set the color mix of the whole village.
     ///
     /// @param red Brightness of the red LEDs.
     /// @param green Brightness of the green LEDs.
     //
-    void set_village_color(uint8_t red, uint8_t green);
+    void set_village_color(uint8_t red, uint8_t green) const;
     
     /// @brief Set brightness of the power plant (only red LEDs)
     ///
     /// @param brightness Brightness of the power plant LEDs.
     ///
-    void set_power_plant(uint8_t brightness);
+    void set_power_plant(uint8_t brightness) const;
     
     /// @brief Set brightness of the solar plant LEDs.
     /// 
     /// @param brightness Brightness of the solar power plant LEDs.
     ///
-    void set_solar_plant(uint8_t brightness);
+    void set_solar_plant(uint8_t brightness) const;
     
     /// @brief Set brightness of the windmill LEDs.
     ///
     /// @param brightness Brightness of the windmill LEDs.
     ///    
-    void set_windmill_net(uint8_t brightness);
+    void set_windmill_net(uint8_t brightness) const;
     
     /// @brief Set the brightness of the combined renewable
     ///        energy net.
     ///
     /// @param brightness Brightness off the LEDs.
     ///
-    void set_renewable_net(uint8_t brightness);
+    void set_renewable_net(uint8_t brightness) const;
 
 private:
 
@@ -116,13 +116,13 @@ private:
     /// @param red Brightness of red LEDs.
     /// @param green Brightness of green LEDs.
     ///
-    void set_house_color(House number, uint8_t red, uint8_t green);
+    void set_house_color(House number, uint8_t red, uint8_t green) const;
     
-    void default_state_off();
-    void default_state_fancy();
+    void default_state_off() const;
+    void default_state_fancy() const;
 
     
-    void set_output_pin(Pin pin, uint8_t value);
+    void set_output_pin(Pin pin, uint8_t value) const;
 
     i2c::Node& m_modell;     ///< I2C connection to the Arduino
 
diff --git a/src/smart_grid/ModelState.hpp b/src/smart_grid/ModelState.hpp
deleted file mode 100644
index 9a4bd8fc2cd75f317d3d2803f04f2a59377f2e85..0000000000000000000000000000000000000000
--- a/src/smart_grid/ModelState.hpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/// @file   ModelState.hpp
-///
-
-#ifndef MODEL_STATE_HPP
-#define MODEL_STATE_HPP
-
-#include <cstdlib>
-#include <ctime>
-
-#include "spdlog/spdlog.h"
-#include "SmartGridModell.hpp"
-
-#include "ObserverPattern.hpp"
-#include "StateLogger.hpp"
-struct MaxPower
-{
-    static constexpr double village = 600;
-    static constexpr double industry = 200;
-    static constexpr double wind = 250;
-    static constexpr double solar = 110;
-};
-
-constexpr double village_consumption_at[]{
-    98, 95, 93, 94, 95, 101, 115,
-    127, 132, 134, 136, 139, 138,
-    136, 134, 132, 130, 132, 132,
-    131, 125, 119, 114, 105, 98};
-
-constexpr double sunnshine_percentage[]{
-    0, 0, 0, 0, 0, 0, 3,
-    12, 30, 52, 73, 88, 97,
-    100, 98, 91, 81, 66, 46,
-    25, 10, 2, 0, 0, 0};
-
-constexpr double power_wind[]{
-    0, 3, 25, 82, 174,
-    321, 532, 815, 1180,
-    1612, 1890, 2000, 2100};
-
-struct CleanPower
-{
-    double solar = 0.0;
-    double wind = 0.0;
-};
-
-struct PowerProduction
-{
-    double conventional;
-    CleanPower renewable;
-    double clean() { return renewable.solar + renewable.wind; }
-    double sum() { return conventional + clean(); }
-};
-
-struct PowerUsage
-{
-    double village = 0.0;
-    double industry = 0.0;
-    double sum() { return village + industry; }
-};
-
-
-class StateLogger;
-class ModelState : public Subject<StateLogger, ModelState>
-{
-public:
-    ModelState(SmartGridModell &modell);
-    void next_hour();
-    double excess_power();
-
-    PowerProduction getPowerProduction() const {return m_production;}
-    PowerUsage getPowerUsage() const {return m_usage;}
-
-private:
-    void update_time();
-    void update_sun();
-    void update_wind();
-    void update_power_consumption();
-    void update_power_production();
-    void update_modell();
-    void print_states();
-
-
-    static constexpr double solar_size{10};
-    static constexpr double windpark_size{1.0};
-    static constexpr double village_size{10};
-
-    int m_time{0};
-    double m_sun{0};
-    double m_wind{0};
-    double m_excess_power{0.0};
-    PowerProduction m_production;
-    PowerUsage m_usage;
-    bool m_producing{false};
-    SmartGridModell &m_modell;
-};
-
-#endif
\ No newline at end of file
diff --git a/src/smart_grid/ModelState.cpp b/src/smart_grid/SmartGridModel.cpp
similarity index 65%
rename from src/smart_grid/ModelState.cpp
rename to src/smart_grid/SmartGridModel.cpp
index 3bcd87c43575175a878fd3fb825acbe722171ab6..18f1295b7632bcd2930f3a4d6a88a1f9eb906891 100644
--- a/src/smart_grid/ModelState.cpp
+++ b/src/smart_grid/SmartGridModel.cpp
@@ -1,16 +1,17 @@
-/// @file   ModelState.cpp
+/// @file   SmartGridModel.cpp
 ///
 
-#include "ModelState.hpp"
+#include "SmartGridModel.hpp"
+#include "spdlog/spdlog.h"
 
-
-ModelState::ModelState(SmartGridModell &modell)
+SmartGridModel::SmartGridModel(HardwareControl &modell)
     : m_modell(modell)
 {
     std::srand(std::time(nullptr));
+    update_states();
 }
 
-void ModelState::update_wind()
+void SmartGridModel::update_wind()
 {
     auto wind_by_sun = m_sun * 9.0 / 100.0; // wind by sun should be 5 max.
     auto random_wind = ((std::rand() * 1.0) / RAND_MAX) * 3.0;
@@ -18,7 +19,7 @@ void ModelState::update_wind()
 }
 
 
-void ModelState::update_modell()
+void SmartGridModel::update_modell()
 {
     auto sun = m_sun * 3.5;
     auto wind = m_wind / 9.3;
@@ -40,10 +41,10 @@ void ModelState::update_modell()
 }
 
 
-void ModelState::update_power_production()
+void SmartGridModel::update_power_production()
 {
-     m_production.renewable.solar = m_sun * solar_size;
-    m_production.renewable.wind = m_wind * windpark_size;
+     m_production.renewable.solar = m_sun * m_solar_size;
+    m_production.renewable.wind = m_wind * m_windpark_size;
     if (m_usage.sum() > m_production.clean())
     {
         m_excess_power = 0.0;
@@ -57,17 +58,18 @@ void ModelState::update_power_production()
 }
 
 
-double ModelState::excess_power()
+double SmartGridModel::calc_excess_power()
 {
     auto sum_prod = m_production.conventional + m_production.renewable.solar + m_production.renewable.wind;
     auto sum_used = m_usage.industry + m_usage.village;
-    return sum_prod - sum_used;
+    m_excess_power = sum_prod - sum_used;
+    return m_excess_power;
 }
 
 
-void ModelState::update_power_consumption()
+void SmartGridModel::update_power_consumption()
 {
-    m_usage.village = village_consumption_at[m_time] * village_size;
+    m_usage.village = village_consumption_at[m_time] * m_village_size;
     if (m_producing == true)
     {
         m_usage.industry = MaxPower::industry;
@@ -78,41 +80,52 @@ void ModelState::update_power_consumption()
     }
 }
 
-void ModelState::update_time()
+void SmartGridModel::next_hour()
 {
     if (m_time < 23)
     {
-        ++m_time;
+        set_time(m_time + 1);
     }
     else
     {
-        m_time = 0;
+        set_time(0);
     }
+    update_states();
 }
 
-void ModelState::update_sun()
+void SmartGridModel::update_sun()
 {
     m_sun = sunnshine_percentage[m_time];
 }
 
 
-void ModelState::print_states()
+void SmartGridModel::print_states()
 {
     spdlog::debug("Time         <{}> Sun     <{}> Wind<{}>", m_time, m_sun, m_wind);
     spdlog::debug("Power Conv   <{}> Solar   <{}> Wind<{}>", m_production.conventional, m_production.renewable.solar, m_production.renewable.wind);
     spdlog::debug("Usage Village<{}> Industry<{}>", m_usage.village, m_usage.industry);
-    spdlog::debug("excess_power<{}>", excess_power());
+    spdlog::debug("excess_power<{}>", calc_excess_power());
 }
 
 
-void ModelState::next_hour()
+void SmartGridModel::update_states()
 {
-    update_time();
     update_sun();
     update_wind();
     update_power_consumption();
     update_power_production();
     update_modell();
     print_states();
-    notify(*this);
+}
+
+void SmartGridModel::set_time(int hour)
+{
+    if ((hour >= 0) & (hour <= 23))
+    {
+        m_time = hour;
+    }
+    else
+    {
+        m_time = 0;
+    }
 }
\ No newline at end of file
diff --git a/src/smart_grid/SmartGridModel.hpp b/src/smart_grid/SmartGridModel.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b5940d5f5e40ba582d96690014ac7b641017790d
--- /dev/null
+++ b/src/smart_grid/SmartGridModel.hpp
@@ -0,0 +1,121 @@
+/// @file   SmartGridModel.hpp
+///
+
+#ifndef MODEL_STATE_HPP
+#define MODEL_STATE_HPP
+
+#include <cstdlib>
+#include <ctime>
+
+#include "HardwareControl.hpp"
+
+#include "ObserverPattern.hpp"
+#include "StateLogger.hpp"
+struct MaxPower
+{
+    static constexpr double village = 600;
+    static constexpr double industry = 200;
+    static constexpr double wind = 250;
+    static constexpr double solar = 110;
+};
+
+constexpr double village_consumption_at[]{
+    98, 95, 93, 94, 95, 101, 115,
+    127, 132, 134, 136, 139, 138,
+    136, 134, 132, 130, 132, 132,
+    131, 125, 119, 114, 105, 98};
+
+constexpr double sunnshine_percentage[]{
+    0, 0, 0, 0, 0, 0, 3,
+    12, 30, 52, 73, 88, 97,
+    100, 98, 91, 81, 66, 46,
+    25, 10, 2, 0, 0, 0};
+
+constexpr double power_wind[]{
+    0, 3, 25, 82, 174,
+    321, 532, 815, 1180,
+    1612, 1890, 2000, 2100};
+
+struct CleanPower
+{
+    double solar = 0.0;
+    double wind = 0.0;
+};
+
+struct PowerProduction
+{
+    double conventional;
+    CleanPower renewable;
+    double clean() { return renewable.solar + renewable.wind; }
+    double sum() { return conventional + clean(); }
+};
+
+struct PowerUsage
+{
+    double village = 0.0;
+    double industry = 0.0;
+    double sum() { return village + industry; }
+};
+
+
+/// @brief Class representing the state of the Smart Grid Model and that has control over the hardware.
+///
+class SmartGridModel
+{
+public:
+    SmartGridModel(HardwareControl &modell);
+
+    // update modle state with new values
+    void next_hour();
+
+    // calculate model states
+    void update_states();
+
+
+    int get_time() const {return m_time;} // current time in hours [0-24]
+    double get_sun() const {return m_sun;} // sunshine in [%]
+    double get_wind() const {return m_wind;} // wind "speed"
+    double get_excess_power() const {return m_excess_power;} // "available" power
+    bool get_producing_state() const {return m_producing;} // returns if production is enabled
+
+    double get_solar_park_size() const {return m_solar_size;} // "Size of the solar production plant"
+    double get_wind_park_size() const {return m_windpark_size;} // "Size" of the windpark
+    double get_village_size() const {return m_village_size;} // "Size of the village"
+
+    PowerProduction get_power_production() const {return m_production;}
+    PowerUsage get_power_usage() const {return m_usage;}
+
+    void set_time(const int hour);
+    void set_solar_size(const double solar_size) {if (solar_size >= 0) m_solar_size = solar_size;}
+    void set_windpark_size(const double windpark_size) {if (windpark_size >= 0) m_windpark_size = windpark_size;}
+    void set_village_size(const double village_size){ if(village_size >= 0) m_village_size = village_size;}
+    void set_producing_state(const bool produce){m_producing = produce;}
+
+
+private:
+    void update_sun();
+    void update_wind();
+    void update_power_consumption();
+    void update_power_production();
+    void update_modell();
+    void print_states();
+
+    double calc_excess_power();
+
+    double m_solar_size{10}; ///< scale for solar power production
+    double m_windpark_size{1.0}; ///< scale the power production by wind 
+    double m_village_size{10}; ///< scale how much power is used by the village
+
+    int m_time{0};
+    double m_sun{0};
+    double m_wind{0};
+    double m_excess_power{0.0};
+    bool m_producing{false};
+    
+    PowerProduction m_production;
+    PowerUsage m_usage;
+    
+    HardwareControl &m_modell;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/smart_grid/SmgStateMachine.hpp b/src/smart_grid/SmgStateMachine.hpp
deleted file mode 100644
index 6dcb770b1159677629f3af0088bd5b9ea1754cdc..0000000000000000000000000000000000000000
--- a/src/smart_grid/SmgStateMachine.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-///
-
-#ifndef SMG_STATE_MACHINE_HPP
-#define SMG_STATE_MACHINE_HPP
-
-#include "ModelState.hpp"
-#include "SmartGridModell.hpp"
-
-enum class MainState
-{
-    Simulation,
-    ManualControl
-};
-
-enum class SimSate
-{
-    Entry,
-    Do,
-    Exit
-};
-
-enum class ManualSate
-{
-    Entry,
-    Do,
-    Exit
-};
-
-
-class SmgStateMachine
-{
-public:
-    void run();
-    
-private:
-    SmartGridModell m_modell;
-    ModelState m_state;
-};
-
-#endif
\ No newline at end of file
diff --git a/src/smart_grid/StateLogger.cpp b/src/smart_grid/StateLogger.cpp
deleted file mode 100644
index 2aee2ea8d4f259f84cb5406da2c02e8473ff330d..0000000000000000000000000000000000000000
--- a/src/smart_grid/StateLogger.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-///
-
-#include "StateLogger.hpp"
-
-void StateLogger::update(const ModelState &model)
-{
-    spdlog::debug("Clean solar power: {}", model.getPowerProduction().renewable.solar);
-}
\ No newline at end of file
diff --git a/src/smart_grid/StateLogger.hpp b/src/smart_grid/StateLogger.hpp
deleted file mode 100644
index 96ded4065194c8ca621ca23f60e7c6ffd66ce811..0000000000000000000000000000000000000000
--- a/src/smart_grid/StateLogger.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-///
-
-#ifndef STATE_LOGGER_HPP
-#define STATE_LOGGER_HPP
-
-#include "ModelState.hpp"
-#include "ObserverPattern.hpp"
-
-class ModelState;
-class StateLogger : IObserver<ModelState>
-{
-public:
-    virtual void update(const ModelState &state) override;
-};
-
-#endif
\ No newline at end of file
diff --git a/src/smg_server.cpp b/src/smg_server.cpp
deleted file mode 100644
index 8c4cfcc71bdb1c0c0f5561c3508849bcf9d4f076..0000000000000000000000000000000000000000
--- a/src/smg_server.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/// @file   main.cpp
-///
-#include <thread>
-#include "spdlog/spdlog.h"
-
-#include "i2c/Node.hpp"
-#include "SmartGridModell.hpp"
-
-#include "Socket.hpp"
-#include "Protocol.hpp"
-
-#include "ModelState.hpp"
-
-enum class MainState
-{
-    Simulation,
-    ManualControl
-};
-
-enum class SimState
-{
-    Entry,
-    Do,
-    Exit
-};
-
-bool sim_state_do(ModelState &day)
-{
-    bool exit_to_manual_control {false};
-
-    // check for new inputs
-    day.next_hour();
-
-    return exit_to_manual_control;
-}
-
-void run_sim()
-{
-    i2c::Node i2c_device{0x14};
-    if (false == i2c_device.open_device("/dev/i2c-1"))
-    {
-        exit(1);
-    }
-    else
-    {
-        spdlog::debug("Node created");
-    }
-
-    SmartGridModell modell{i2c_device};
-    ModelState day{modell};
-    auto log = std::make_shared<StateLogger>();
-    day.attach(log);
-
-    MainState main_state {MainState::Simulation};
-    SimState sim_state {SimState::Entry};
-
-    bool active{true};
-    while (active)
-    {
-        switch (main_state)
-        {
-        case MainState::Simulation:
-            switch (sim_state)
-            {
-            case SimState::Entry:
-                modell.put_modell_into_state(SmartGridModell::DefaultState::Off);
-                sim_state = SimState::Do;
-                break;
-            case SimState::Do:
-                // limit speed of simulation
-                std::this_thread::sleep_for(std::chrono::milliseconds(500));
-                if (sim_state_do(day) == true)
-                {
-                    sim_state = SimState::Exit;
-                }
-                break;
-            case SimState::Exit:
-                modell.put_modell_into_state(SmartGridModell::DefaultState::Off);
-                sim_state = SimState::Entry;
-                main_state = MainState::ManualControl;
-                break;
-            }
-            break;
-
-        case MainState::ManualControl:
-
-            break;
-        }
-    }
-
-    modell.put_modell_into_state(SmartGridModell::DefaultState::Off);
-}
-
-void log_args(int argc, char **argv)
-{
-    for (int i = 0; i < argc; ++i)
-    {
-        spdlog::debug("[{}] {}", i, argv[i]);
-    }
-}
-
-int main(int argc, char **argv)
-{
-    spdlog::set_level(spdlog::level::debug);
-    spdlog::info("Starting - Smart Grid Modell");
-    log_args(argc, argv);
-
-    run_sim();
-
-    spdlog::info("End");
-    return 0;
-}