From 9bd0a3fccfc6ee002cd491cafe861d675ce98525 Mon Sep 17 00:00:00 2001
From: Armin Co <armin.co@hs-bochum.de>
Date: Sat, 29 Aug 2020 12:28:58 +0200
Subject: [PATCH] Update

---
 CMakeLists.txt          |  17 +++-
 Readme.md               |  11 +-
 src/SmartGridModell.cpp |   3 +-
 src/SmartGridModell.hpp |   3 +-
 src/main.cpp            | 119 ----------------------
 src/smg_server.cpp      | 221 ++++++++++++++++++++++++++++++++++++++++
 6 files changed, 249 insertions(+), 125 deletions(-)
 delete mode 100644 src/main.cpp
 create mode 100644 src/smg_server.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5c3aa2e..fbbf492 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,12 +11,23 @@ include_directories(src)
 add_executable(manual_control src/manual_control/ComTest.cpp)
 target_link_libraries(manual_control spdlog)
 
+add_executable(sample_client
+    src/manual_control/sample_client.cpp
+    src/com/Socket.cpp
+    src/com/Protocol.cpp
+)
+target_link_libraries(sample_client spdlog)
 
 # Smart Grid Simulation
 include_directories(src/i2c)
+include_directories(src/com)
 
 add_executable(smart_grid.exe
-    src/main.cpp
+    src/smg_server.cpp
     src/SmartGridModell.cpp
-    src/i2c/Node.cpp)
-target_link_libraries(smart_grid.exe spdlog)
\ No newline at end of file
+    src/i2c/Node.cpp
+    src/com/Socket.cpp
+    src/com/Protocol.cpp
+)
+
+target_link_libraries(smart_grid.exe spdlog)
diff --git a/Readme.md b/Readme.md
index 9facfc5..81cb4b9 100644
--- a/Readme.md
+++ b/Readme.md
@@ -9,13 +9,22 @@ Darin werden die Bibliotheken [spdlog](https://github.com/gabime/spdlog) für da
 [freeopcua](https://github.com/FreeOpcUa/freeopcua) für OPC-UA Server und Client.
 Für freeopcua werden zusätzliche Pakete benötigt. Für Debian sind diese in der Datei 'debain.soft' aufgelistet.
 
-Weitere:
+Die Git-Submodules müssen vor dem kompilieren mit
+'git submodule init && git submodule update' heruntergeladen werden.
+
+Die derzeitig auf dem Pi installierte Version von Raspbian hat nur Zugriff auf die alte CMake Version 3.6.2
+für 'spdlog' wird jedoch 3.10 erwartet.
+
+
+Weitere, wernn diese Pakete auf Raspbian nicht zur Verfügung stehen, dann kann TLS deaktiviert werden:
 
   - libmbedx509-0
   - libmbedcrypto1
   - libmbedtls-dev
 
 
+
+
 # Durchgeführte Arbeiten
 
 * Systemupdate des Raspberry Pi
diff --git a/src/SmartGridModell.cpp b/src/SmartGridModell.cpp
index d5938a9..89559cd 100644
--- a/src/SmartGridModell.cpp
+++ b/src/SmartGridModell.cpp
@@ -1,4 +1,5 @@
-///
+/// @file SmartGridModell.cpp
+/// @
 
 #include <SmartGridModell.hpp>
 #include <spdlog/spdlog.h>
diff --git a/src/SmartGridModell.hpp b/src/SmartGridModell.hpp
index 1b419e4..cee45b0 100644
--- a/src/SmartGridModell.hpp
+++ b/src/SmartGridModell.hpp
@@ -77,7 +77,7 @@ public:
     ///
     /// @param red Brightness of the red LEDs.
     /// @param green Brightness of the green LEDs.
-    ///
+    //
     void set_village_color(uint8_t red, uint8_t green);
     
     /// @brief Set brightness of the power plant (only red LEDs)
@@ -102,6 +102,7 @@ public:
     ///        energy net.
     ///
     /// @param brightness Brightness off the LEDs.
+    ///
     void set_renewable_net(uint8_t brightness);
 
 private:
diff --git a/src/main.cpp b/src/main.cpp
deleted file mode 100644
index 0771c3d..0000000
--- a/src/main.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/// @file   main.cpp
-/// 
-
-struct CleanPower
-{
-    float solar = 0.0;
-    float wind = 0.0;
-};
-
-struct PowerProduction
-{
-    float conventional;
-    CleanPower renewable; 
-};
-
-struct PowerUsage
-{
-    float village = 0.0;
-    float industry = 0.0;
-};
-
-
-struct ModellState
-{
-    PowerProduction production;
-    PowerUsage usage;
-};
-
-class ModelState
-{
-public:
-    unsigned get_time();
-    void next_step();
-private:
-    void update_model_states();
-    void calc_wind();
-    void calc_soalr();
-
-    PowerProduction m_power_production;
-    PowerUsage m_pwer_usage;
-    unsigned m_time = 0; //< 0-24h
-};
-
-
-/// @brief Peak Power consumption or production in MW
-///     
-struct MaxPower
-{
-    float conventional = 600;
-    float village = 600;
-    float industry = 200;
-    float wind = 250;
-    float solar = 110;
-};
-
-constexpr float 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 float 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 float power_wind[] {
-    0, 3, 25, 82, 174, 
-    321, 532, 815, 1180, 
-    1612, 1890, 2000, 2100
-};
-
-
-
-#include <i2c/Node.hpp>
-#include <SmartGridModell.hpp>
-#include <spdlog/spdlog.h>
-
-#include <thread>
-
-int main()
-{
-    spdlog::set_level(spdlog::level::debug);
-    spdlog::info("Starting - Smart Grid Modell");
-    // Intialisation
-    // put model into a base state
-    // Intialise environment data
-
-    // select operating mode
-    // manual control
-    // sim mode
-
-    // run loop
-    i2c::Node i2c_device {0x14};
-    if (false == i2c_device.open_device("/dev/i2c-1"))
-    {
-        spdlog::error("Failed to open device. Exiting...");
-        exit(1);
-    }
-    spdlog::debug("Node created");
-    
-    SmartGridModell modell{i2c_device, SmartGridModell::DefaultState::Fancy};
-    spdlog::debug("Modell created");
-
-
-    // ModelState state {};
-    // bool simulation_is_running {true};
-    // while (simulation_is_running)
-    // {
-    //     state.next_step();
-
-    // }
-    modell.put_modell_into_state(SmartGridModell::DefaultState::Off);
-    spdlog::info("End");
-    return 0;
-}
\ No newline at end of file
diff --git a/src/smg_server.cpp b/src/smg_server.cpp
new file mode 100644
index 0000000..07b2dd9
--- /dev/null
+++ b/src/smg_server.cpp
@@ -0,0 +1,221 @@
+/// @file   main.cpp
+/// 
+#include <i2c/Node.hpp>
+#include <SmartGridModell.hpp>
+#include <spdlog/spdlog.h>
+
+#include <thread>
+#include <cstdlib>
+#include <ctime>
+
+
+#include <Socket.hpp>
+#include <Protocol.hpp>
+
+struct CleanPower
+{
+    double solar = 0.0;
+    double wind = 0.0;
+};
+
+struct PowerProduction
+{
+    double conventional;
+    CleanPower renewable; 
+};
+
+struct PowerUsage
+{
+    double village = 0.0;
+    double industry = 0.0;
+};
+
+
+/// @brief Peak Power consumption or production in MW
+///
+struct MaxPower
+{
+    static constexpr double conventional = 600;
+    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
+};
+
+class Day
+{
+public:
+    Day()
+    {
+        std::srand(std::time(nullptr));
+    }
+
+    void next_hour()
+    {
+        update_time();
+        update_sun();
+        update_wind();
+        update_power_production();
+        update_power_consumption();
+        print_states();
+    }
+
+private:
+    void update_time()
+    {
+        if (m_time < 23)
+        {
+            ++m_time;
+        }
+        else
+        {
+            m_time = 0;
+        }
+    }
+    void update_sun()
+    {
+        m_sun = sunnshine_percentage[m_time];
+    }
+    void update_wind()
+    {
+        double wind_by_sun = m_sun * 5.0 / 100.0; // wind by sun should by 5 max.
+        auto random_wind = ((std::rand() * 1.0) / RAND_MAX) * 7.0;
+        m_wind = power_wind[static_cast<int>(wind_by_sun + random_wind)];
+        spdlog::debug("wind: {} {} {}", random_wind, wind_by_sun, m_wind);
+    }
+    void update_power_production()
+    {
+        m_production.renewable.solar = m_sun * solar_size;
+        spdlog::debug("wind power {} {}", m_production.renewable.wind, m_wind);
+
+        m_production.renewable.wind = m_wind * windpark_size;
+        m_production.conventional = MaxPower::conventional;
+        spdlog::debug("wind power {} {}", m_production.renewable.wind, m_wind);
+    }
+    void update_power_consumption()
+    {
+        m_usage.village = village_consumption_at[m_time] * village_size;
+        if (m_producing == true)
+        {
+            m_usage.industry = MaxPower::industry;
+        }
+        else
+        {
+            m_usage.industry = 0.0;
+        }
+    }
+
+
+    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};
+    PowerProduction m_production;
+    PowerUsage m_usage;
+    bool m_producing {false};
+
+    void 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);
+    }
+};
+
+
+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, SmartGridModell::DefaultState::Fancy};
+    spdlog::debug("Modell created");
+
+    modell.put_modell_into_state(SmartGridModell::DefaultState::Off);
+    Day day{};
+
+    bool active {true};
+    while (active)
+    {
+        day.next_hour();
+        std::this_thread::sleep_for(std::chrono::seconds(1));
+    }
+}
+
+
+void test_x64()
+{
+    i2c::Node i2c_device {0x14};
+    bool done = i2c_device.open_device("/dev/i2c-1");
+    if (done == false)
+    {
+        spdlog::debug("You could try running as root");
+    }
+
+    ServerSocket server(8080);
+    bool finished {false};
+    Day day{};
+    while (!finished)
+    {
+        DataSocket accept = server.accept();
+        ProtocolSimple accept_simple(accept);
+
+        std::string message;
+        accept_simple.recv_message(message);
+        spdlog::info("RECV: {}", message);
+
+        accept_simple.send_message("", "OK");
+
+        day.next_hour();
+    }
+}
+
+
+int main(int argc, char** argv)
+{
+    spdlog::set_level(spdlog::level::debug);
+    spdlog::info("Starting - Smart Grid Modell");
+
+    if (argc > 1)
+    {
+        test_x64();
+    }
+    else
+    {
+        run_sim();
+    }
+
+    spdlog::info("End");
+    return 0;
+}
-- 
GitLab