From d88d798d6c76e4da903d7b316935107d2c52d242 Mon Sep 17 00:00:00 2001
From: Armin Co <armin.co@hs-bochum.de>
Date: Tue, 25 Aug 2020 15:37:02 +0200
Subject: [PATCH] Update

---
 .gitignore              |   1 +
 CMakeFile.txt           |   0
 CMakeLists.txt          |  13 ++++
 Readme.md               |  24 +++++++
 src/Arduino.hpp         |  72 ---------------------
 src/ComTest.cpp         |  76 ++++++++++++++++++++++
 src/SimModell.hpp       |  43 -------------
 src/SmartGridModell.cpp | 136 ++++++++++++++++++++++++++++++++++++++++
 src/SmartGridModell.hpp | 127 +++++++++++++++++++++++++++++++++++++
 src/main.cpp            |  38 +++++++++++
 src/playground.cpp      |   3 -
 11 files changed, 415 insertions(+), 118 deletions(-)
 create mode 100644 .gitignore
 delete mode 100644 CMakeFile.txt
 create mode 100644 CMakeLists.txt
 delete mode 100644 src/Arduino.hpp
 create mode 100644 src/ComTest.cpp
 delete mode 100644 src/SimModell.hpp
 create mode 100644 src/SmartGridModell.cpp
 create mode 100644 src/SmartGridModell.hpp
 create mode 100644 src/main.cpp
 delete mode 100644 src/playground.cpp

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c795b05
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+build
\ No newline at end of file
diff --git a/CMakeFile.txt b/CMakeFile.txt
deleted file mode 100644
index e69de29..0000000
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..b7a9ee0
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.10)
+
+project(SmartGridModell)
+
+# Add spdlog for nice and easy logging
+add_subdirectory(libs/spdlog)
+
+include_directories(src)
+
+# Test application to manually send commands to the Arduino
+add_executable(manual_control src/ComTest.cpp)
+target_link_libraries(manual_control spdlog)
+
diff --git a/Readme.md b/Readme.md
index e5bf5b9..9facfc5 100644
--- a/Readme.md
+++ b/Readme.md
@@ -1,5 +1,19 @@
 # Smart-Grid-Modell (SGM)
 
+## Installation
+
+Voraussetzungen und Abhängigkeiten
+
+Dieses Repository [https://gitlab.cvh-server.de/aco/smart-grid-modell](https://gitlab.cvh-server.de/aco/smart-grid-modell)
+Darin werden die Bibliotheken [spdlog](https://github.com/gabime/spdlog) für das Loggen von Benachritigungen und
+[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:
+
+  - libmbedx509-0
+  - libmbedcrypto1
+  - libmbedtls-dev
 
 
 # Durchgeführte Arbeiten
@@ -13,3 +27,13 @@
 * Neues Build-System mit aktuellem Stand (CMake & C++)
 * Aufteilen in eine SGM-Runnable mit API für GUI, CLI oder OPC UA.
 * Überarbeiten der Simulationsparameter
+
+# Tools
+
+- kleines Kommandozeilen-Programm zur manuellen Kommunikation mit dem Arduino (i2c_control.exe)
+
+
+# Notizen
+
+- Adresse des Arduinos: 0x14
+- Adresse des Lux-Sensors: 0x23
\ No newline at end of file
diff --git a/src/Arduino.hpp b/src/Arduino.hpp
deleted file mode 100644
index ecf5167..0000000
--- a/src/Arduino.hpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/// @file   Arduino.hpp
-/// @brief  Interface to interact with an Arduino.
-///
-/// @details    Wrapps commands for setting output pins
-///             and reading sensor values.
-///
-
-#ifndef ARDUINO_HEADER
-#define ARDUINO_HEADER
-
-#include "i2c/Node.hpp"
-
-namespace arduino
-{
-
-/// @brief Configuration to pass at the 
-///         creation of an new object.
-///
-struct Config
-{
-    char I2CNodeAdress; ///< Adress as hex
-};
-
-/// @brief Pins that are used on the arduino
-///
-enum class Pin : unsigned char
-{
-    MotorPWM     = 0x02,    ///< 2
-    LampPWM      = 0x03,    ///< 3
-    SolarPWM     = 0x04,    ///< 4
-    WindPWM      = 0x05,    ///< 5
-    WindSolarPWM = 0x06,    ///< 6
-    NetPWM       = 0x07,    ///< 7
-    MixGreenPWM  = 0x08,    ///< 8
-    MixRedPWM    = 0x09,    ///< 9
-    HousesWhite  = 0x10,    ///< 16
-    House1Red    = 0x2f,    ///< 47
-    House1Green  = 0x29,    ///< 41
-    House2Red    = 0x35,    ///< 53
-    House2Green  = 0x2d,    ///< 45
-    House3Red    = 0x33,    ///< 51
-    House3Green  = 0x31,    ///< 49
-    House4Red    = 0x2B,    ///< 43
-    House4Green  = 0x25,    ///< 37
-    House5Red    = 0x27,    ///< 39
-    Hoise5Green  = 0x23     ///< 35
-};
-
-
-/// @brief Arduino board class.
-///
-class Board
-{
-public:
-    /// @brief Create Arduino interface
-    ///
-    Board(Config conf);
-
-    /// @brief Set an output pin to the given value
-    /// @param pin Pin that should be set
-    /// @param value The value the pin should be set to 0x00 - 0xFF
-    ///
-    void set_output_pin(Pin pin, char value);
-
-private:
-    Config m_conf; ///< Configuration
-    i2c::Node m_Node; ///< I2C communication interface
-};
-
-}
-
-#endif ARDUINO_HEADER
diff --git a/src/ComTest.cpp b/src/ComTest.cpp
new file mode 100644
index 0000000..1890ae8
--- /dev/null
+++ b/src/ComTest.cpp
@@ -0,0 +1,76 @@
+/// @brief Test Commands to Arduino with I2C
+///
+
+// to open i2c device
+#include <fcntl.h>
+
+// select and interact with device
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+// Definition of I2C_SLAVE
+#include <linux/i2c-dev.h>
+
+// Nice and easy logging
+#include <spdlog/spdlog.h>
+
+#include<vector>
+#include<array>
+
+/// @brief Device name of the I2C interface on the Pi
+///
+const char* i2c_device_name = "/dev/i2c-1";
+constexpr uint8_t arduino_address = 0x14;
+
+void write_to_node(int fd, std::vector<uint8_t> data)
+{
+
+    int buffer_size = data.size();
+
+    int bytes_written = write(fd, data.data(), buffer_size);
+
+    if (bytes_written != buffer_size)
+    {
+        spdlog::error("Failed to write buffer over I2C");
+        spdlog::info("Bytes written {}", bytes_written);
+    }
+}
+
+
+int main(int argc, char* argv[])
+{
+    int fd_i2c = open(i2c_device_name, O_RDWR);
+    if (fd_i2c < 0)
+    {
+        spdlog::error("Unable to open I2C device");
+        return 1;
+    }
+
+    int device_selected = ioctl(fd_i2c, I2C_SLAVE, arduino_address);
+    if (device_selected < 0)
+    {
+        spdlog::error("Unable to select I2C device");
+        return 1;
+    }
+
+    if (argc == 3)
+    {
+        uint8_t arg1 = atoi(argv[1]);
+        uint8_t arg2 = atoi(argv[2]);
+
+        write_to_node(fd_i2c, {arg1, arg2});
+        spdlog::info("Bytes written: {} {}", arg1, arg2);
+    }
+    else
+    {
+        spdlog::error("Number of input arguments is not correct!");
+        spdlog::error("Usage: val1 val2");
+        for (int i = 0; i < argc; ++i)
+        {
+            spdlog::info("arg{}: {}", i, argv[i]);
+        }
+    }
+    close(fd_i2c);
+
+    return 0;
+}
diff --git a/src/SimModell.hpp b/src/SimModell.hpp
deleted file mode 100644
index bf5586d..0000000
--- a/src/SimModell.hpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/// @file
-/// @brief A collection of functions used in the simulation.
-///
-/// @details
-///
-
-#ifndef SIM_MODELL_HEADER
-#define SIM_MODELL_HEADER
-
-namespace sim
-{
-    struct Consumption
-    {
-        double total; ///< [kW]
-    };
-
-    struct Production
-    {
-        double wind; ///< [kW]
-        double sun; ///< [kW]
-        double conventional; ///< [kW]
-    };
-
-    struct Environment
-    {
-        double wind_speed; ///< [ms]
-        double lux_sensor; ///< [lux]
-        double sun_brightness; ///< [lux]
-    };
-
-    struct Time
-    {
-        int hour;
-        int minute;
-    };
-
-    void calc_wind_production();
-    void calc_photovoltaic_production();
-    void energy_consumption_per_min();
-    void update_smart_grid();
-}
-
-#endif SIM_MODELL_HEADER
\ No newline at end of file
diff --git a/src/SmartGridModell.cpp b/src/SmartGridModell.cpp
new file mode 100644
index 0000000..a837ea8
--- /dev/null
+++ b/src/SmartGridModell.cpp
@@ -0,0 +1,136 @@
+///
+
+#include <SmartGridModell.hpp>
+
+
+
+
+SmartGridModell::SmartGridModell(i2c::Node& node, DefaultState initial_state)
+    : m_modell{node}
+{
+    put_modell_into_state(initial_state);
+}
+
+
+void SmartGridModell::put_modell_into_state(DefaultState state)
+{
+    switch (state)
+    {
+    case DefaultState::Off:
+        default_state_off();
+        break;
+    
+    case DefaultState::Fancy:
+        default_state_fancy();
+    default:
+        break;
+    }
+}
+
+
+void SmartGridModell::default_state_off()
+{
+    update_windmill_speed(0);
+    set_village_color(0, 0);
+    set_power_plant(0);
+    set_solar_plant(0);
+    set_windmill_net(0);
+    set_renewable_net(0);
+}
+
+
+void SmartGridModell::default_state_fancy()
+{
+    update_windmill_speed(50);
+    set_village_color(20, 20);
+    set_power_plant(20);
+    set_solar_plant(20);
+    set_windmill_net(20);
+    set_renewable_net(20);
+}
+
+
+void SmartGridModell::update_windmill_speed(uint8_t speed)
+{
+    constexpr uint8_t min_motor_speed {35};
+    if (speed >= min_motor_speed)
+    {
+        set_output_pin(Pin::WindmillMotor, speed);
+    }
+    else if (speed > 20)
+    {
+        set_output_pin(Pin::WindmillMotor, min_motor_speed);
+    }
+    else
+    {
+        set_output_pin(Pin::WindmillMotor, 0);
+    }
+}
+
+
+void SmartGridModell::set_village_color(uint8_t red, uint8_t green)
+{
+    set_output_pin(Pin::VillageNetRed, red);
+    set_output_pin(Pin::VillageNetGreen, green);
+    
+    for (auto house : {House::One, House::Two, House::Three, House::Four, House::Five})
+    {
+        set_house_color(house, red, green);
+    }
+}
+
+void SmartGridModell::set_power_plant(uint8_t brightness)
+{
+    set_output_pin(Pin::PowerPlantNet, brightness);
+}
+
+void SmartGridModell::set_solar_plant(uint8_t brightness)
+{
+    set_output_pin(Pin::SolarFieldNet, brightness);
+}
+
+void SmartGridModell::set_windmill_net(uint8_t brightness)
+{
+    set_output_pin(Pin::WindmillNet, brightness);
+}
+
+void SmartGridModell::set_renewable_net(uint8_t brightness)
+{
+    set_output_pin(Pin::WindAndSolarNet, brightness);
+}
+
+
+void SmartGridModell::set_output_pin(Pin pin, uint8_t value)
+{
+    m_modell.send(static_cast<uint8_t>(pin), value);
+}
+
+void SmartGridModell::set_house_color(House number, uint8_t red, uint8_t green)
+{
+    switch (number)
+    {
+    case House::One:
+        set_output_pin(Pin::House1Red, red);
+        set_output_pin(Pin::House1Green, green);
+        break;
+    case House::Two:
+        set_output_pin(Pin::House2Red, red);
+        set_output_pin(Pin::House2Green, green);
+        break;
+    case House::Three:
+        set_output_pin(Pin::House3Red, red);
+        set_output_pin(Pin::House3Green, green);
+        break;
+    case House::Four:
+        set_output_pin(Pin::House4Red, red);
+        set_output_pin(Pin::House4Green, green);
+        break;
+    case House::Five:
+        set_output_pin(Pin::House5Red, red);
+        set_output_pin(Pin::House5Green, green);
+        break;
+    
+    default:
+        break;
+    }
+}
\ No newline at end of file
diff --git a/src/SmartGridModell.hpp b/src/SmartGridModell.hpp
new file mode 100644
index 0000000..1b419e4
--- /dev/null
+++ b/src/SmartGridModell.hpp
@@ -0,0 +1,127 @@
+
+
+#ifndef SMART_GRID_MODELL_HEADER
+#define SMART_GRID_MODELL_HEADER
+
+
+#include <i2c/Node.hpp>
+
+class SmartGridModell
+{
+public:
+
+    /// @brief Pre defined states of the smart grid modell.
+    ///
+    enum class DefaultState
+    {
+        Off,    ///< just turn everything off.
+        Fancy   ///< show some fancy lights.
+    };
+
+    /// @biref Enumeration of houses on the smart grid modell.
+    ///
+    enum class House
+    {
+        One,
+        Two,
+        Three,
+        Four,
+        Five
+    };
+
+    /// @brief Pins that are used on the arduino
+    ///
+    enum class Pin : uint8_t
+    {
+        WindmillMotor   = 0x02,    ///< 2
+        Sun             = 0x03,    ///< 3
+        SolarFieldNet   = 0x04,    ///< 4
+        WindmillNet     = 0x05,    ///< 5
+        WindAndSolarNet = 0x06,    ///< 6
+        PowerPlantNet   = 0x07,    ///< 7
+        VillageNetGreen = 0x08,    ///< 8
+        VillageNetRed   = 0x09,    ///< 9
+
+        House1Red       = 0x2f,    ///< 47
+        House1Green     = 0x29,    ///< 41
+        House2Red       = 0x35,    ///< 53
+        House2Green     = 0x2d,    ///< 45
+        House3Red       = 0x33,    ///< 51
+        House3Green     = 0x31,    ///< 49
+        House4Red       = 0x2B,    ///< 43
+        House4Green     = 0x25,    ///< 37
+        House5Red       = 0x27,    ///< 39
+        House5Green     = 0x23     ///< 35
+    };
+
+    /// @brief Initialiese modell with everything off.
+    ///
+    SmartGridModell(i2c::Node& node, DefaultState initial_state = DefaultState::Off);
+
+    /// @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);
+
+    /// @brief Set the turning speed of the windmill.
+    /// @details 
+    /// Checks if the value is high enough to turn the mill.
+    /// If not high enough the motor will be turned off.
+    ///
+    /// @param speed Turning speed of the windmill.
+    ///
+    void update_windmill_speed(uint8_t speed);
+    
+    /// @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);
+    
+    /// @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);
+    
+    /// @brief Set brightness of the solar plant LEDs.
+    /// 
+    /// @param brightness Brightness of the solar power plant LEDs.
+    ///
+    void set_solar_plant(uint8_t brightness);
+    
+    /// @brief Set brightness of the windmill LEDs.
+    ///
+    /// @param brightness Brightness of the windmill LEDs.
+    ///    
+    void set_windmill_net(uint8_t brightness);
+    
+    /// @brief Set the brightness of the combined renewable
+    ///        energy net.
+    ///
+    /// @param brightness Brightness off the LEDs.
+    void set_renewable_net(uint8_t brightness);
+
+private:
+
+    /// @brief Set the color of the given house.
+    ///
+    /// @param number Selected house.
+    /// @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 default_state_off();
+    void default_state_fancy();
+
+    
+    void set_output_pin(Pin pin, uint8_t value);
+
+    i2c::Node& m_modell;     ///< I2C connection to the Arduino
+
+};
+
+#endif
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..903fab6
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,38 @@
+/// @file   main.cpp
+/// 
+
+struct ModellState
+{
+
+};
+
+struct CleanPower
+{
+    float solar;
+    float wind;
+};
+
+struct PowerProduction
+{
+    float conventional;
+    CleanPower renewable; 
+};
+
+struct PowerUsage
+{
+    float village;
+    float industry;
+};
+
+struct EnergyMix
+{
+    PowerUsage used;
+    PowerProduction available;
+};
+
+int main()
+{
+
+
+    return 0;
+}
\ No newline at end of file
diff --git a/src/playground.cpp b/src/playground.cpp
deleted file mode 100644
index b3fb8d7..0000000
--- a/src/playground.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-/// @brief Playground for SGM
-
-
-- 
GitLab