From ca8d66c5216940ee12b8ab8d0846dabea45b9afe Mon Sep 17 00:00:00 2001 From: "o.likhogub" Date: Sun, 8 Oct 2023 02:29:14 +0300 Subject: [PATCH] Added aggregator code --- cybergarden-aggregator/.gitignore | 5 + .../lib/UuidModule/Uuid.cpp | 180 ++++++++++++++++++ cybergarden-aggregator/lib/UuidModule/Uuid.h | 75 ++++++++ cybergarden-aggregator/platformio.ini | 18 ++ cybergarden-aggregator/src/main.cpp | 107 +++++++++++ 5 files changed, 385 insertions(+) create mode 100644 cybergarden-aggregator/.gitignore create mode 100644 cybergarden-aggregator/lib/UuidModule/Uuid.cpp create mode 100644 cybergarden-aggregator/lib/UuidModule/Uuid.h create mode 100644 cybergarden-aggregator/platformio.ini create mode 100644 cybergarden-aggregator/src/main.cpp diff --git a/cybergarden-aggregator/.gitignore b/cybergarden-aggregator/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/cybergarden-aggregator/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/cybergarden-aggregator/lib/UuidModule/Uuid.cpp b/cybergarden-aggregator/lib/UuidModule/Uuid.cpp new file mode 100644 index 0000000..9dd81a9 --- /dev/null +++ b/cybergarden-aggregator/lib/UuidModule/Uuid.cpp @@ -0,0 +1,180 @@ +// +// FILE: UUID.cpp +// AUTHOR: Rob Tillaart +// VERSION: 0.1.5 +// DATE: 2022-06-14 +// PURPOSE: Arduino Library for generating UUID's +// URL: https://github.com/RobTillaart/UUID +// https://en.wikipedia.org/wiki/Universally_unique_identifier + + +#include "UUID.h" + + +UUID::UUID() +{ + seed(1, 2); + setVariant4Mode(); + generate(); +} + + +void UUID::seed(uint32_t s1, uint32_t s2) +{ + // set Marsaglia constants, prevent 0 as value + if (s1 == 0) s1 = 1; + if (s2 == 0) s2 = 2; + _m_w = s1; + _m_z = s2; +} + + +// check version 0.1.1 for more readable code +void UUID::generate() +{ + uint32_t ar[4]; + for (uint8_t i = 0; i < 4; i++) + { + ar[i] = _random(); + // store binary version globally ? + // _ar[i] = ar[i]; + } + // Conforming to RFC 4122 Specification + // - byte 7: four most significant bits ==> 0100 --> always 4 + // - byte 9: two most significant bits ==> 10 --> always {8, 9, A, B}. + // + // patch bits for version 1 and variant 4 here + if (_mode == UUID_MODE_VARIANT4) + { + ar[1] &= 0xFFF0FFFF; // remove 4 bits. + ar[1] |= 0x00040000; // variant 4 + ar[2] &= 0xFFFFFFF3; // remove 2 bits + ar[2] |= 0x00000008; // version 1 + } + + // process 16 bytes build up the char array. + for (uint8_t i = 0, j = 0; i < 16; i++) + { + // multiples of 4 between 8 and 20 get a -. + // note we are processing 2 digits in one loop. + if ((i & 0x1) == 0) + { + if ((4 <= i) && (i <= 10)) + { + _buffer[j++] = '-'; + } + } + + // process one byte at the time instead of a nibble + uint8_t nr = i / 4; + uint8_t xx = ar[nr]; + uint8_t ch = xx & 0x0F; + _buffer[j++] = (ch < 10) ? '0' + ch : ('a' - 10) + ch; + + ch = (xx >> 4) & 0x0F; + ar[nr] >>= 8; + _buffer[j++] = (ch < 10) ? '0' + ch : ('a' - 10) + ch; + } + + // if (_upperCase) + // { + // for (int i = 0; i < 37; i++) + // { + // _buffer[i] = toUpper(_buffer[i]); + // } + // } + _buffer[36] = 0; +} + + +char * UUID::toCharArray() +{ + // if (_upperCase) + // { + // for (int i = 0; i < 37; i++) + // { + // _buffer[i] = toLower(_buffer[i]); + // } + // } + // else + // { + // for (int i = 0; i < 37; i++) + // { + // _buffer[i] = toLower(_buffer[i]); + // } + // } + return _buffer; +} + + +////////////////////////////////////////////////// +// +// MODE +// +void UUID::setVariant4Mode() +{ + _mode = UUID_MODE_VARIANT4; +} + + +void UUID::setRandomMode() +{ + _mode = UUID_MODE_RANDOM; +} + + +uint8_t UUID::getMode() +{ + return _mode; +} + + +////////////////////////////////////////////////// +// +// PRINTING +// +size_t UUID::printTo(Print& p) const +{ + return p.print(_buffer); +} + + +////////////////////////////////////////////////// +// +// CASE +// +// void UUID::setLowerCase() +// { +// _upperCase = false; +// } +// +// +// void UUID::setUpperCase() +// { +// _upperCase = true; +// } + + +////////////////////////////////////////////////// +// +// PRIVATE +// + + + +////////////////////////////////////////////////// +// +// RANDOM GENERATOR MARSAGLIA +// +// An example of a simple pseudo-random number generator is the +// Multiply-with-carry method invented by George Marsaglia. +// two initializers (not null) +uint32_t UUID::_random() +{ + _m_z = 36969L * (_m_z & 65535L) + (_m_z >> 16); + _m_w = 18000L * (_m_w & 65535L) + (_m_w >> 16); + return (_m_z << 16) + _m_w; // 32-bit result +} + + +// -- END OF FILE -- diff --git a/cybergarden-aggregator/lib/UuidModule/Uuid.h b/cybergarden-aggregator/lib/UuidModule/Uuid.h new file mode 100644 index 0000000..ea77a1b --- /dev/null +++ b/cybergarden-aggregator/lib/UuidModule/Uuid.h @@ -0,0 +1,75 @@ +#pragma once +// +// FILE: UUID.h +// AUTHOR: Rob Tillaart +// VERSION: 0.1.5 +// DATE: 2022-06-14 +// PURPOSE: Arduino Library for generating UUID's +// URL: https://github.com/RobTillaart/UUID +// https://en.wikipedia.org/wiki/Universally_unique_identifier +// +// e.g. 20d24650-d900-e34f-de49-8964ab3eb46d + + +#include "Arduino.h" +#include "Printable.h" + + +#define UUID_LIB_VERSION (F("0.1.5")) + +// TODO an enum? +const uint8_t UUID_MODE_VARIANT4 = 0; +const uint8_t UUID_MODE_RANDOM = 1; + + +///////////////////////////////////////////////// +// +// CLASS VERSION +// +class UUID : public Printable +{ +public: + UUID(); + + // at least one seed value is mandatory, two is better. + void seed(uint32_t s1, uint32_t s2 = 0); + // generate a new UUID + void generate(); + // make a UUID string + char * toCharArray(); + + // MODE + void setVariant4Mode(); + void setRandomMode(); + uint8_t getMode(); + + // Printable interface + size_t printTo(Print& p) const; + + + // CASE + // (experimental code, not tested yet) + // lower case is default and according to spec. + // upper case is an additional feature. + // must it be done at generation or at toCharArray() ? + // fast or flex + // + // void setLowerCase(); + // void setUpperCase(); + + +private: + // Marsaglia 'constants' + function + uint32_t _m_w = 1; + uint32_t _m_z = 2; + uint32_t _random(); + + // UUID in string format + char _buffer[37]; + uint8_t _mode = UUID_MODE_VARIANT4; + + // bool _upperCase = false; +}; + + +// -- END OF FILE -- diff --git a/cybergarden-aggregator/platformio.ini b/cybergarden-aggregator/platformio.ini new file mode 100644 index 0000000..9f9afbf --- /dev/null +++ b/cybergarden-aggregator/platformio.ini @@ -0,0 +1,18 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:esp32doit-devkit-v1] +platform = espressif32 +board = esp32doit-devkit-v1 +framework = arduino +monitor_speed = 115200 +lib_deps = + mikem/RadioHead@^1.120 + bblanchon/ArduinoJson@^6.21.3 diff --git a/cybergarden-aggregator/src/main.cpp b/cybergarden-aggregator/src/main.cpp new file mode 100644 index 0000000..dee7707 --- /dev/null +++ b/cybergarden-aggregator/src/main.cpp @@ -0,0 +1,107 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#ifdef RH_HAVE_HARDWARE_SPI +#include // Not actually used but needed to compile +#endif + +#include "Uuid.h" +#include + +String serverName = "http://gw.cg.k-lab.su/api/v1/measures/register"; + +ReedSolomonModule reedSolomonModule; +TransmitterModule transmitterModule; +TransmissionModule transmissionModule(transmitterModule, reedSolomonModule); + +UUID uuid; + +const char *ntpServer = "pool.ntp.org"; +unsigned long epochTime; + +void setup() +{ + Serial.begin(115200); + WiFi.mode(WIFI_STA); + WiFi.begin("Darius wifi", "alstroemeria"); + Serial.println("\nConnecting"); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(100); + } + pinMode(LED_BUILTIN, OUTPUT); + transmitterModule.init(); + configTime(0, 0, ntpServer); +} + +uint8_t sensor_id; +MeasureData measureData; + +unsigned long getTime() +{ + time_t now; + struct tm timeinfo; + if (!getLocalTime(&timeinfo)) + { + Serial.println("Failed to obtain time"); + return (0); + } + time(&now); + return now; +} + +String getPayload(MeasureData &data) +{ + String serverPath = serverName; + serverPath += String("/") + getTime(); + serverPath += String("/") + data.sensor_id; + serverPath += String("/") + WiFi.macAddress(); + serverPath += String("/") + getTime(); + if (data.sensor_type == 1) { + serverPath += String("/") + "temperature"; + } else { + serverPath += String("/") + data.sensor_type; + } + serverPath += String("/") + data.payload; + return serverPath; +} + +bool sendPayload(MeasureData &data) { + if (WiFi.status() == WL_CONNECTED) { + HTTPClient http; + String serverPath = getPayload(data); + + http.begin(serverPath.c_str()); + int httpResponseCode = http.GET(); + if (httpResponseCode > 0) { + Serial.print("HTTP Response code: "); + Serial.println(httpResponseCode); + String payload = http.getString(); + Serial.println(payload); + return true; + } + else { + Serial.print("Error code: "); + Serial.println(httpResponseCode); + } + http.end(); + } + return false; +} + +MeasureData data; + +void loop() { + data.sensor_id = 0; + data.sensor_type = 1; + data.payload = rand() & 0xffff; + sendPayload(data); + delay(5000); +} \ No newline at end of file