From f05e1dd552b81d7cfcbbd37d70ed0004e4bf333c Mon Sep 17 00:00:00 2001 From: Zoe Pfister <zoe.pfister@student.uibk.ac.at> Date: Thu, 6 Oct 2022 17:40:19 +0200 Subject: [PATCH] move to c++17, change message building, refactored SensorInformation and MeasurementData - messages are now built using the constructor - messages now only contain a single measurement value, even if a sensor might include more than one measurement - buildMessage has been changed to buildMessages and now returns a list of messages depending on how many measurements a sensor contains - ClientDataPackage now builds from SensorInformation and MeasurementData - minor naming refactors --- client/client/include/ForteSensor.hpp | 10 +-- client/client/include/MeasurementData.hpp | 40 ++++++++++ .../include/NoDataAvailableException.hpp | 2 +- .../client/include/{pinout.hpp => Pinout.hpp} | 4 +- client/client/include/Protocol.hpp | 5 +- client/client/include/SensorInformation.hpp | 25 ++++++ .../lib/dr26_analogue/{src => }/dr26.cpp | 25 +++--- client/client/lib/dr26_analogue/dr26.hpp | 24 ++++++ client/client/lib/dr26_analogue/src/dr26.hpp | 22 ------ client/client/lib/drs26_digital/drs26.cpp | 26 ++++--- client/client/lib/drs26_digital/drs26.hpp | 9 ++- .../lib/espnow/src/ClientDataPackage.hpp | 45 ++++++----- client/client/lib/espnow/src/Message.cpp | 78 ++++--------------- client/client/lib/espnow/src/Message.hpp | 15 ++-- client/client/lib/ina219/ina219.cpp | 14 ++-- client/client/lib/ina219/ina219.hpp | 9 ++- client/client/lib/scd30/scd30.cpp | 15 ++-- client/client/lib/scd30/scd30.hpp | 9 ++- client/client/platformio.ini | 6 +- client/client/src/main.cpp | 16 ++-- client/client/test/TestClientDataPackage.cpp | 31 +++++++- client/client/test/TestClientDataPackage.hpp | 2 + client/client/test/main.cpp | 2 + 23 files changed, 247 insertions(+), 187 deletions(-) create mode 100644 client/client/include/MeasurementData.hpp rename client/client/include/{pinout.hpp => Pinout.hpp} (77%) create mode 100644 client/client/include/SensorInformation.hpp rename client/client/lib/dr26_analogue/{src => }/dr26.cpp (74%) create mode 100644 client/client/lib/dr26_analogue/dr26.hpp delete mode 100644 client/client/lib/dr26_analogue/src/dr26.hpp diff --git a/client/client/include/ForteSensor.hpp b/client/client/include/ForteSensor.hpp index 1db845d..add5a01 100644 --- a/client/client/include/ForteSensor.hpp +++ b/client/client/include/ForteSensor.hpp @@ -3,15 +3,15 @@ #include "Message.hpp" #include "Protocol.hpp" +#include "SensorInformation.hpp" template <class T> -class Forte_Sensor { +class ForteSensor { public: virtual T readData() = 0; virtual void setup() = 0; - virtual Message buildMessage() = 0; - virtual Protocol getProtocol() = 0; - - private: + virtual std::list<Message> buildMessages() = 0; + [[nodiscard]] virtual SensorInformation getSensorInformation() const = 0; + virtual ~ForteSensor() = default; }; #endif \ No newline at end of file diff --git a/client/client/include/MeasurementData.hpp b/client/client/include/MeasurementData.hpp new file mode 100644 index 0000000..9434e6a --- /dev/null +++ b/client/client/include/MeasurementData.hpp @@ -0,0 +1,40 @@ +// +// Created by cynthya on 10/6/22. +// + +#ifndef CLIENT_MEASUREMENTDATA_HPP +#define CLIENT_MEASUREMENTDATA_HPP + +#include "ArduinoJson.h" +#include "Protocol.hpp" +#include "SensorInformation.hpp" +#include <list> +#include <optional> +#include <string> +#include <utility> +class MeasurementData { + public: + MeasurementData(double value, std::optional<int> channel, std::optional<int> i2cAddress, + std::string measurementType) + : value(value), measurementType(std::move(measurementType)), channel(channel), i2cAddress(i2cAddress) + { + } + + MeasurementData(double value, std::string measurementType) + : value(value), measurementType(std::move(measurementType)) + { + } + + [[nodiscard]] double getValue() const { return value; } + [[nodiscard]] const std::string &getMeasurementType() const { return measurementType; } + [[nodiscard]] const std::optional<int> &getChannel() const { return channel; } + [[nodiscard]] const std::optional<int> &getI2CAddress() const { return i2cAddress; } + + private: + double value; + std::string measurementType; // TODO: consider using an enum + std::optional<int> channel; + + std::optional<int> i2cAddress; +}; +#endif // CLIENT_MEASUREMENTDATA_HPP diff --git a/client/client/include/NoDataAvailableException.hpp b/client/client/include/NoDataAvailableException.hpp index a5de09a..83c5697 100644 --- a/client/client/include/NoDataAvailableException.hpp +++ b/client/client/include/NoDataAvailableException.hpp @@ -4,5 +4,5 @@ #include <iostream> struct NoDataAvailableException : public std::exception { - const char *what() const throw() { return "Sensor could not read data"; } + const char *what() const noexcept override { return "Sensor could not read data"; } }; \ No newline at end of file diff --git a/client/client/include/pinout.hpp b/client/client/include/Pinout.hpp similarity index 77% rename from client/client/include/pinout.hpp rename to client/client/include/Pinout.hpp index b80b32d..f277fd9 100644 --- a/client/client/include/pinout.hpp +++ b/client/client/include/Pinout.hpp @@ -2,8 +2,8 @@ #define _FORTE_PINOUT // Pins for I2C -#define I2C_SDA 18 -#define I2C_SCL 19 +constexpr int I2C_SDA = 18; +constexpr int I2C_SCL = 19; // TODO: IF THE BOARD CHANGES (I.E. ESPCAM MODULE), THESE HAVE TO BE CHANGED (EITHER COMPILE TIME FLAG OR IFDEF OR SMTH) diff --git a/client/client/include/Protocol.hpp b/client/client/include/Protocol.hpp index 2bcdab9..92270db 100644 --- a/client/client/include/Protocol.hpp +++ b/client/client/include/Protocol.hpp @@ -6,9 +6,10 @@ #define CLIENT_PROTOCOL_HPP #include <map> -enum Protocol { I2C, RS485, Analog }; +enum class Protocol { I2C, RS485, Analog }; // protocol to string -static std::map<Protocol, const char *> protocolToString = {{I2C, "I2C"}, {RS485, "RS485"}, {Analog, "Analog"}}; +const static std::map<Protocol, const char *> protocolToString = { + {Protocol::I2C, "I2C"}, {Protocol::RS485, "RS485"}, {Protocol::Analog, "ANALOG"}}; #endif // CLIENT_PROTOCOL_HPP diff --git a/client/client/include/SensorInformation.hpp b/client/client/include/SensorInformation.hpp new file mode 100644 index 0000000..4b8af5d --- /dev/null +++ b/client/client/include/SensorInformation.hpp @@ -0,0 +1,25 @@ +// +// Created by cynthya on 10/6/22. +// + +#ifndef CLIENT_SENSORINFORMATION_HPP +#define CLIENT_SENSORINFORMATION_HPP + +#include "Protocol.hpp" +#include <string> + +class SensorInformation { + public: + SensorInformation(std::string sensorName, Protocol protocol) : sensorName(std::move(sensorName)), protocol(protocol) + { + } + + [[nodiscard]] const std::string &getSensorName() const { return sensorName; } + [[nodiscard]] Protocol getProtocol() const { return protocol; } + + private: + std::string sensorName; + Protocol protocol; +}; + +#endif // CLIENT_SENSORINFORMATION_HPP diff --git a/client/client/lib/dr26_analogue/src/dr26.cpp b/client/client/lib/dr26_analogue/dr26.cpp similarity index 74% rename from client/client/lib/dr26_analogue/src/dr26.cpp rename to client/client/lib/dr26_analogue/dr26.cpp index 626203d..e8d4555 100644 --- a/client/client/lib/dr26_analogue/src/dr26.cpp +++ b/client/client/lib/dr26_analogue/dr26.cpp @@ -1,23 +1,18 @@ #include "dr26.hpp" -static const char* TAG = "DR26"; - -Adafruit_ADS1115 ads; - -void Forte_DR26 ::setup() +void ForteDR26 ::setup() { Wire.begin(I2C_SDA, I2C_SCL); // ads.setGain(0); - if(ads.begin()){ - ESP_LOGI(TAG, "ADS initialized."); - } - else{ - ESP_LOGW(TAG, "ADS initialization failed."); + if (ads.begin()) { + ESP_LOGI(sensorInformation.getSensorName().c_str(), "ADS initialized."); + } else { + ESP_LOGW(sensorInformation.getSensorName().c_str(), "ADS initialization failed."); } delay(100); } -float Forte_DR26 ::readData() +float ForteDR26 ::readData() { float volts = 0; for (int i = 0; i < 10; i++) { @@ -44,16 +39,16 @@ float Forte_DR26 ::readData() // GAIN_FOUR // 4x gain +/- 1.024V 1 bit = 0.03125mV // GAIN_EIGHT // 8x gain +/- 0.512V 1 bit = 0.015625mV // GAIN_SIXTEEN // 16x gain +/- 0.256V 1 bit = 0.0078125mV -void Forte_DR26 ::changeGain(adsGain_t gain) +void ForteDR26 ::changeGain(adsGain_t gain) { ads.setGain(gain); } -Message Forte_DR26::buildMessage() +std::list<Message> ForteDR26::buildMessages() { throw "Not implemented"; } -Protocol Forte_DR26::getProtocol() +SensorInformation ForteDR26::getSensorInformation() const { - return Analog; + return sensorInformation; } diff --git a/client/client/lib/dr26_analogue/dr26.hpp b/client/client/lib/dr26_analogue/dr26.hpp new file mode 100644 index 0000000..778f8fe --- /dev/null +++ b/client/client/lib/dr26_analogue/dr26.hpp @@ -0,0 +1,24 @@ +#ifndef _DR26 +#define _DR26 + +#include "Adafruit_ADS1X15.h" +#include "ForteSensor.hpp" +#include "Message.hpp" +#include "Pinout.hpp" +#include "esp_log.h" +#include <Wire.h> + +class ForteDR26 : public ForteSensor<float> { + public: + void setup() override; + float readData() override; + void changeGain(adsGain_t gain); + std::list<Message> buildMessages() override; + [[nodiscard]] SensorInformation getSensorInformation() const override; + + private: + Adafruit_ADS1115 ads; + const SensorInformation sensorInformation{"DR26", Protocol::Analog}; +}; + +#endif \ No newline at end of file diff --git a/client/client/lib/dr26_analogue/src/dr26.hpp b/client/client/lib/dr26_analogue/src/dr26.hpp deleted file mode 100644 index 9c9efa5..0000000 --- a/client/client/lib/dr26_analogue/src/dr26.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _DR26 -#define _DR26 - -#include "ForteSensor.hpp" -#include "Message.hpp" -#include "esp_log.h" -#include "pinout.hpp" -#include <Adafruit_ADS1X15.h> -#include <Wire.h> - -class Forte_DR26 : public Forte_Sensor<float> { - public: - void setup() override; - float readData() override; - void changeGain(adsGain_t gain); - Message buildMessage() override; - Protocol getProtocol() override; - - private: -}; - -#endif \ No newline at end of file diff --git a/client/client/lib/drs26_digital/drs26.cpp b/client/client/lib/drs26_digital/drs26.cpp index 9e77230..5c21f3a 100644 --- a/client/client/lib/drs26_digital/drs26.cpp +++ b/client/client/lib/drs26_digital/drs26.cpp @@ -1,18 +1,17 @@ #include <drs26.hpp> -static const std::string TAG = "DRS26"; /* It happens for some reason that the sensor cant get reached every 2 time Because the sensor use sdi12 protocoll we have to wait aproxemettly 1 secound between the commands It is not known how lond the response takes so we use a while loop which can be a risk wehre the programm can get stuck */ -void Forte_DRS26 ::setup() +void ForteDRS26 ::setup() { drs26.begin(4); } -out_data_drs26 Forte_DRS26 ::readData() +out_data_drs26 ForteDRS26 ::readData() { String sdiResponse = ""; String measurement_command = @@ -42,14 +41,21 @@ out_data_drs26 Forte_DRS26 ::readData() return data; } -Message Forte_DRS26 ::buildMessage() +std::list<Message> ForteDRS26 ::buildMessages() { - auto message = Message(); - message.addData(12.12, measurementTypeToString[MeasurementType::TEMPERATURE], TAG, 4); - ESP_LOGE(TAG.c_str(), "test"); - return message; + std::list<Message> messages; + MeasurementData circumferenceIncrementMeasurementData{ + data.circumferenceIncrement, 0, {}, measurementTypeToString.at(MeasurementType::CIRCUMFERENCE_INCREMENT)}; + MeasurementData temperatureMeasurementData{ + data.temperature, 0, {}, measurementTypeToString.at(MeasurementType::TEMPERATURE)}; + + messages.emplace_back(Message{circumferenceIncrementMeasurementData, sensorInformation, 0}); + messages.emplace_back(Message{temperatureMeasurementData, sensorInformation, 0}); + + ESP_LOGE(sensorInformation.getSensorName().c_str(), "test"); + return messages; } -Protocol Forte_DRS26::getProtocol() +SensorInformation ForteDRS26::getSensorInformation() const { - return I2C; + return sensorInformation; } diff --git a/client/client/lib/drs26_digital/drs26.hpp b/client/client/lib/drs26_digital/drs26.hpp index 153371d..0d713ca 100644 --- a/client/client/lib/drs26_digital/drs26.hpp +++ b/client/client/lib/drs26_digital/drs26.hpp @@ -3,9 +3,9 @@ #include "ForteSensor.hpp" #include "Message.hpp" +#include "Pinout.hpp" #include "Wire.h" #include "esp_log.h" -#include "pinout.hpp" #include <SDI12.h> #include <map> @@ -15,16 +15,17 @@ struct out_data_drs26 { float temperature; }; -class Forte_DRS26 : public Forte_Sensor<out_data_drs26> { +class ForteDRS26 : public ForteSensor<out_data_drs26> { public: void setup() override; out_data_drs26 readData() override; - Message buildMessage() override; - Protocol getProtocol() override; + std::list<Message> buildMessages() override; + [[nodiscard]] SensorInformation getSensorInformation() const override; private: SDI12 drs26; out_data_drs26 data; + const SensorInformation sensorInformation{"DRS26", Protocol::I2C}; enum class MeasurementType { TEMPERATURE, CIRCUMFERENCE_INCREMENT }; // enum to string diff --git a/client/client/lib/espnow/src/ClientDataPackage.hpp b/client/client/lib/espnow/src/ClientDataPackage.hpp index 727127d..2458ca6 100644 --- a/client/client/lib/espnow/src/ClientDataPackage.hpp +++ b/client/client/lib/espnow/src/ClientDataPackage.hpp @@ -1,43 +1,50 @@ #pragma once #include "ArduinoJson.h" +#include "MeasurementData.hpp" #include "Protocol.hpp" +#include "SensorInformation.hpp" #include <list> +#include <optional> #include <string> #include <utility> -struct MeasurementData { - double value; - int channel; - std::string measurementType; // TODO: consider using an enum -}; - // having the data be a struct of basic types makes sending easier, // otherwise we would have to serialize the data before sending class ClientDataPackage { private: - MeasurementData value; - std::string sensorName; - std::string protocol; - long timestamp; // maybe make this array + MeasurementData measurementData; + SensorInformation sensorInformation; + unsigned long timestamp; // maybe make this array public: - ClientDataPackage(MeasurementData value, std::string sensorName, long timestamp, Protocol protocol) - : value(std::move(std::move(value))), sensorName(std::move(sensorName)), timestamp(timestamp), - protocol(protocolToString[protocol]) + ClientDataPackage(MeasurementData value, SensorInformation sensorInformation, unsigned long timestamp) + : measurementData(std::move(value)), sensorInformation(std::move(sensorInformation)), timestamp(timestamp) { } - std::string getDataPackageAsMinifiedJsonString() + [[nodiscard]] const MeasurementData &getMeasurementData() const { return measurementData; } + [[nodiscard]] const SensorInformation &getSensorInformation() const { return sensorInformation; } + [[nodiscard]] unsigned long getTimestamp() const { return timestamp; } + + [[nodiscard]] std::string getDataPackageAsMinifiedJsonString() const { StaticJsonDocument<250> document; // 250 byte is the max send size of espnow - document["sensorName"] = sensorName; + document["sensorName"] = sensorInformation.getSensorName(); document["timestamp"] = timestamp; - document["protocol"] = protocol; - document["value"] = value.value; - document["channel"] = value.channel; - document["measurementType"] = value.measurementType; + document["protocol"] = protocolToString.at(sensorInformation.getProtocol()); + document["value"] = measurementData.getValue(); + + if (measurementData.getChannel().has_value()) { + document["channel"] = measurementData.getChannel().value(); + } + + if (measurementData.getI2CAddress().has_value()) { + document["i2cAddress"] = measurementData.getI2CAddress().value(); + } + + document["measurementType"] = measurementData.getMeasurementType(); std::string jsonString; serializeJson(document, jsonString); diff --git a/client/client/lib/espnow/src/Message.cpp b/client/client/lib/espnow/src/Message.cpp index 4a23314..8c69a11 100644 --- a/client/client/lib/espnow/src/Message.cpp +++ b/client/client/lib/espnow/src/Message.cpp @@ -1,90 +1,42 @@ #include "Message.hpp" -static const char *TAG = "MESSAGE"; - -void Message::addData(float value, int identifier) -{ - StaticJsonDocument<100> document; - document["value"] = value; - document["identifier"] = identifier; - data["values"].add(document); - ESP_LOGD(TAG, "Added data: %s", getMessageAsMinifiedJsonString().c_str()); -} - -void Message::addData(float value, const std::string &measurementType, const std::string &sensorName) -{ - StaticJsonDocument<100> document; - - document["sensorName"] = sensorName; - document["measurementType"] = measurementType; - data["values"].add(document); +#include <utility> - ESP_LOGD(TAG, "Added data: %s", getMessageAsMinifiedJsonString().c_str()); -} - -/** - * Add data to a message that originates from an analog sensor with multiple channels - * @param value Value of the measurement - * @param measurementType Type of the measurement - * @param sensorName Name of the sensor - * @param channel Connected analog channel - */ -void Message::addData(float value, const std::string &measurementType, const std::string &sensorName, int channel) -{ - StaticJsonDocument<100> document; - - document["sensorName"] = sensorName; - document["channel"] = channel; - document["measurementType"] = measurementType; - document["value"] = value; - data["values"].add(document); - - ESP_LOGD(TAG, "Added data: %s", getMessageAsMinifiedJsonString().c_str()); -} +static const char *TAG = "MESSAGE"; -esp_err_t Message::send() +esp_err_t Message::send() const { ESP_LOGI(TAG, "Sending message"); esp_err_t success; auto messageData = getMessageAsMinifiedJsonString(); - success = esp_now_send(recipient, (uint8_t *)&messageData, sizeof(data)); + success = esp_now_send(recipient, (uint8_t *)&messageData, sizeof(clientDataPackage)); if (success != ESP_OK) { // TODO REWRITE FOR JSON -// if (!ram_cache_is_full()) { -// // ram_cache_push(messageData); -// } + // if (!ram_cache_is_full()) { + // // ram_cache_push(messageData); + // } } ESP_LOGD(TAG, "Sent data: %s", messageData.c_str()); - std::string timestampString = data["timestamp"]; - ESP_LOGD(TAG, "time sent: %s", timestampString.c_str()); + ESP_LOGD(TAG, "time sent: %l", clientDataPackage.getTimestamp()); ESP_LOGD(TAG, "send status: %d", success); return success; } -StaticJsonDocument<256> Message::getData() +std::string Message::getMessageAsMinifiedJsonString() const { - return data; + return clientDataPackage.getDataPackageAsMinifiedJsonString(); } -Message ::Message() +Message::Message(ClientDataPackage data) : clientDataPackage(std::move(data)) { // check for existing host mac address, use broadcast otherwise get_host_mac(recipient); - data["values"] = JsonArray(); - addTimestamp(); } - -std::string Message::getMessageAsMinifiedJsonString() +Message::Message(MeasurementData const &data, const SensorInformation &information, unsigned long timestamp) + : clientDataPackage(data, information, timestamp) { - std::string minimizedJson; - serializeJson(data, minimizedJson); - return minimizedJson; -} -void Message::addTimestamp() -{ - // TODO: if we are not time synced (i.e. didn't reach the host for current time, use another value like number of - // reboots of the ESP) - data["timestamp"] = esptime::rtc.getMillis(); + // check for existing host mac address, use broadcast otherwise + get_host_mac(recipient); } diff --git a/client/client/lib/espnow/src/Message.hpp b/client/client/lib/espnow/src/Message.hpp index 8a26ea7..3711df2 100644 --- a/client/client/lib/espnow/src/Message.hpp +++ b/client/client/lib/espnow/src/Message.hpp @@ -13,19 +13,14 @@ // if more things are sent from the host the name might not be accurate anymore class Message { public: - void addData(float value, int identifier); - void addData(float value, const std::string &measurementType, const std::string &sensorName); - void addData(float value, const std::string &measurementType, const std::string &sensorName, int channel); - Message(); + explicit Message(ClientDataPackage data); - esp_err_t send(); - StaticJsonDocument<256> getData(); - std::string getMessageAsMinifiedJsonString(); + Message(MeasurementData const &data, const SensorInformation &information, unsigned long timestamp); + esp_err_t send() const; + [[nodiscard]] std::string getMessageAsMinifiedJsonString() const; private: - StaticJsonDocument<256> data; - void addTimestamp(); - // ClientDataPackage data; + ClientDataPackage clientDataPackage; uint8_t recipient[6]{}; }; \ No newline at end of file diff --git a/client/client/lib/ina219/ina219.cpp b/client/client/lib/ina219/ina219.cpp index 5d1ff38..def6a9d 100644 --- a/client/client/lib/ina219/ina219.cpp +++ b/client/client/lib/ina219/ina219.cpp @@ -1,18 +1,16 @@ #include "ina219.hpp" -static const char* TAG = "INA219"; - -void Forte_INA219 ::setup() +void ForteINA219 ::setup() { Wire.begin(I2C_SDA, I2C_SCL); if (!ina219.init()) { // Sensor init went wrong - ESP_LOGW(TAG, "Initialization failed"); + ESP_LOGW(sensorInformation.getSensorName().c_str(), "Initialization failed"); return; } } -out_data_ina219 Forte_INA219 ::readData() +out_data_ina219 ForteINA219 ::readData() { if (!ina219.getOverflow()) { data.shuntVoltage_mV = ina219.getShuntVoltage_mV(); @@ -27,11 +25,11 @@ out_data_ina219 Forte_INA219 ::readData() return data; } -Message Forte_INA219::buildMessage() +std::list<Message> ForteINA219::buildMessages() { throw "Not yet implemented"; } -Protocol Forte_INA219::getProtocol() +SensorInformation ForteINA219::getSensorInformation() const { - return I2C; + return sensorInformation; } diff --git a/client/client/lib/ina219/ina219.hpp b/client/client/lib/ina219/ina219.hpp index cfcb01d..4a34d95 100644 --- a/client/client/lib/ina219/ina219.hpp +++ b/client/client/lib/ina219/ina219.hpp @@ -3,9 +3,9 @@ #include "ForteSensor.hpp" #include "Message.hpp" +#include "Pinout.hpp" #include "Wire.h" #include "esp_log.h" -#include "pinout.hpp" #include <INA219_WE.h> struct out_data_ina219 { @@ -17,16 +17,17 @@ struct out_data_ina219 { bool ina219_overflow = false; }; -class Forte_INA219 : public Forte_Sensor<out_data_ina219> { +class ForteINA219 : public ForteSensor<out_data_ina219> { public: void setup() override; out_data_ina219 readData() override; - Message buildMessage() override; - Protocol getProtocol() override; + std::list<Message> buildMessages() override; + [[nodiscard]] SensorInformation getSensorInformation() const override; private: INA219_WE ina219; out_data_ina219 data; + const SensorInformation sensorInformation{"INA219", Protocol::I2C}; }; #endif \ No newline at end of file diff --git a/client/client/lib/scd30/scd30.cpp b/client/client/lib/scd30/scd30.cpp index eb7e743..507d815 100644 --- a/client/client/lib/scd30/scd30.cpp +++ b/client/client/lib/scd30/scd30.cpp @@ -1,18 +1,16 @@ #include "scd30.hpp" -static const char* TAG = "SCD30"; - -void Forte_SCD30 ::setup() +void ForteSCD30 ::setup() { Wire.begin(I2C_SDA, I2C_SCL); if (!airSensor.begin()) { // Sensor init went wrong - ESP_LOGW(TAG, "Initialization failed."); + ESP_LOGW(sensorInformation.getSensorName().c_str(), "Initialization failed."); return; } } -out_data_scd30 Forte_SCD30 ::readData() +out_data_scd30 ForteSCD30 ::readData() { if (airSensor.dataAvailable()) { data.C02 = airSensor.getCO2(); @@ -22,14 +20,13 @@ out_data_scd30 Forte_SCD30 ::readData() return data; } throw NoDataAvailableException(); - // return out_data_scd30{-1, -1, -1}; } -Message Forte_SCD30::buildMessage() +std::list<Message> ForteSCD30::buildMessages() { throw "Not yet implemented"; } -Protocol Forte_SCD30::getProtocol() +SensorInformation ForteSCD30::getSensorInformation() const { - return I2C; + return sensorInformation; } diff --git a/client/client/lib/scd30/scd30.hpp b/client/client/lib/scd30/scd30.hpp index a1fa290..db3e855 100644 --- a/client/client/lib/scd30/scd30.hpp +++ b/client/client/lib/scd30/scd30.hpp @@ -4,8 +4,8 @@ #include "ForteSensor.hpp" #include "Message.hpp" #include "NoDataAvailableException.hpp" +#include "Pinout.hpp" #include "esp_log.h" -#include "pinout.hpp" #include <SparkFun_SCD30_Arduino_Library.h> #include <Wire.h> @@ -15,16 +15,17 @@ struct out_data_scd30 { float Humidity; }; -class Forte_SCD30 : public Forte_Sensor<out_data_scd30> { +class ForteSCD30 : public ForteSensor<out_data_scd30> { public: void setup() override; out_data_scd30 readData() override; - Message buildMessage() override; - Protocol getProtocol() override; + std::list<Message> buildMessages() override; + [[nodiscard]] SensorInformation getSensorInformation() const override; private: SCD30 airSensor; out_data_scd30 data; + const SensorInformation sensorInformation{"SCD30", Protocol::I2C}; }; #endif \ No newline at end of file diff --git a/client/client/platformio.ini b/client/client/platformio.ini index a28a589..28cc58c 100644 --- a/client/client/platformio.ini +++ b/client/client/platformio.ini @@ -13,10 +13,14 @@ platform = espressif32 board = esp32-c3-devkitm-1 framework = arduino monitor_speed = 115200 +; C++17 https://community.platformio.org/t/esp32-c-17-toolchain-missing-std-optional/25850/6 +; we use c++17 features (i.e. optionals in ClientDataPackage.hpp) build_flags = -I include -DCORE_DEBUG_LEVEL=5 -lib_deps = + -std=gnu++17 +build_unflags = -std=gnu++11 +lib_deps = sparkfun/SparkFun SCD30 Arduino Library@^1.0.18 Wire adafruit/Adafruit ADS1X15@^2.4.0 diff --git a/client/client/src/main.cpp b/client/client/src/main.cpp index fe98c19..77265a5 100644 --- a/client/client/src/main.cpp +++ b/client/client/src/main.cpp @@ -1,14 +1,14 @@ +#include "../lib/dr26_analogue/dr26.hpp" #include "NoDataAvailableException.hpp" #include "esp_log.h" #include <Arduino.h> -#include <dr26.hpp> #include <drs26.hpp> #include <ina219.hpp> #include <scd30.hpp> // #include "esp32-hal-log.h" -static const char *TAG = "MAIN"; +static const std::string TAG = "MAIN"; -Forte_DRS26 drs26; +ForteDRS26 drs26; void setup() { @@ -25,13 +25,17 @@ void loop() try { espnow_setup(); // data = drs26.readData(); - auto message = drs26.buildMessage(); - message.send(); + auto messages = drs26.buildMessages(); + + for (const Message &message : messages) { + message.send(); + } + } catch (const NoDataAvailableException &e) { std::cerr << e.what() << '\n'; } - ESP_LOGE(TAG, "Sensor Circumference: "); + ESP_LOGE(TAG.c_str(), "Sensor Circumference: "); // log_e("Temperature: "); // log_e("Id: "); diff --git a/client/client/test/TestClientDataPackage.cpp b/client/client/test/TestClientDataPackage.cpp index bae42a2..eea536c 100644 --- a/client/client/test/TestClientDataPackage.cpp +++ b/client/client/test/TestClientDataPackage.cpp @@ -3,17 +3,44 @@ // #include "TestClientDataPackage.hpp" +#include "MeasurementData.hpp" #include "Protocol.hpp" #include <vector> void test_export_to_json() { - ClientDataPackage dataPackage = ClientDataPackage(MeasurementData{1.1, 0, "TEMPERATURE"}, "DRS26", 0, Analog); + auto dataPackage = + ClientDataPackage(MeasurementData{1.1, 0, {}, "TEMPERATURE"}, SensorInformation{"DRS26", Protocol::Analog}, 0); std::string json = dataPackage.getDataPackageAsMinifiedJsonString(); // expected std::string expected = - R"({"sensorName":"DRS26","timestamp":0,"protocol":"Analog","value":1.1,"channel":0,"measurementType":"TEMPERATURE"})"; + R"({"sensorName":"DRS26","timestamp":0,"protocol":"ANALOG","value":1.1,"channel":0,"measurementType":"TEMPERATURE"})"; + + TEST_ASSERT_EQUAL_STRING(expected.c_str(), json.c_str()); +} +void test_export_to_json_no_analog() +{ + auto dataPackage = + ClientDataPackage(MeasurementData{1.1, {}, {}, "TEMPERATURE"}, SensorInformation{"DRS26_DIGITAL", Protocol::I2C}, 0); + + std::string json = dataPackage.getDataPackageAsMinifiedJsonString(); + // expected + std::string expected = + R"({"sensorName":"DRS26_DIGITAL","timestamp":0,"protocol":"I2C","value":1.1,"measurementType":"TEMPERATURE"})"; + + TEST_ASSERT_EQUAL_STRING(expected.c_str(), json.c_str()); +} + +void test_export_to_json_no_channel_no_address() +{ + auto dataPackage = + ClientDataPackage(MeasurementData{1.1,"TEMPERATURE"}, SensorInformation{"DRS26_DIGITAL", Protocol::I2C}, 0); + + std::string json = dataPackage.getDataPackageAsMinifiedJsonString(); + // expected + std::string expected = + R"({"sensorName":"DRS26_DIGITAL","timestamp":0,"protocol":"I2C","value":1.1,"measurementType":"TEMPERATURE"})"; TEST_ASSERT_EQUAL_STRING(expected.c_str(), json.c_str()); } \ No newline at end of file diff --git a/client/client/test/TestClientDataPackage.hpp b/client/client/test/TestClientDataPackage.hpp index 74a7b90..fa5f203 100644 --- a/client/client/test/TestClientDataPackage.hpp +++ b/client/client/test/TestClientDataPackage.hpp @@ -10,5 +10,7 @@ #include <ClientDataPackage.hpp> void test_export_to_json(); +void test_export_to_json_no_analog(); +void test_export_to_json_no_channel_no_address(); #endif // CLIENT_TESTCLIENTDATAPACKAGE_HPP diff --git a/client/client/test/main.cpp b/client/client/test/main.cpp index b4aedce..5ad5f3f 100644 --- a/client/client/test/main.cpp +++ b/client/client/test/main.cpp @@ -10,6 +10,8 @@ void setup() UNITY_BEGIN(); RUN_TEST(test_on_data_recv_valid_config); RUN_TEST(test_export_to_json); + RUN_TEST(test_export_to_json_no_analog); + RUN_TEST(test_export_to_json_no_channel_no_address); UNITY_END(); } -- GitLab