diff --git a/client/client_mock/platformio.ini b/client/client_mock/platformio.ini index b7c388a5d2b4fd93dd5ddb27969ebd259d807847..1a9a18984b3f34f3cba2b6d992ddf9eb49f61e74 100644 --- a/client/client_mock/platformio.ini +++ b/client/client_mock/platformio.ini @@ -6,6 +6,7 @@ monitor_speed = 115200 lib_ldf_mode = deep lib_extra_dirs = ../libs + ../../shared-libs ; 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 = diff --git a/client/client_mock/src/main.cpp b/client/client_mock/src/main.cpp index ca790730dc00ceedbe1ffb9d7f899811bff6337b..b76d3e6fd67b510110902d67d89fe00a81c065ae 100644 --- a/client/client_mock/src/main.cpp +++ b/client/client_mock/src/main.cpp @@ -15,112 +15,121 @@ MockSensor mock_channel2; MockSensor mock_channel3; void send_msgs(const std::__cxx11::list<Message> msgs) { - for (const Message &msg: msgs) { - - if (msg.send() != ESP_OK) { - RtcMemory::store(msg.getMessageAsMinifiedJsonString()); - } - unsigned long ts = millis(); - // it takes ~110ms for receiving an acknowledgement by the host in perfect conditions - uint16_t message_timeout = 2000; - while (!was_msg_received()) { - if ((millis() - ts) > message_timeout) { - RtcMemory::store(msg.getMessageAsMinifiedJsonString()); - ESP_LOGE(TAG, "Timeout: Host not available\n"); - break; - } - } - ESP_LOGD(TAG, "Time until acknowledgement: %ld", millis() - ts); + for (const Message &msg: msgs) { + + if (msg.send() != ESP_OK) { + RtcMemory::store(msg.getMessageAsMinifiedJsonString()); + } + unsigned long ts = millis(); + // it takes ~110ms for receiving an acknowledgement by the host in perfect conditions + uint16_t message_timeout = 2000; + while (!was_msg_received()) { + if ((millis() - ts) > message_timeout) { + RtcMemory::store(msg.getMessageAsMinifiedJsonString()); + ESP_LOGE(TAG, "Timeout: Host not available\n"); + break; + } } + ESP_LOGD(TAG, "Time until acknowledgement: %ld", millis() - ts); + } } // one loop takes ~2200 ms void setup() { - // disable brownout - WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); - unsigned long ts = millis(); - Serial.begin(115200); - - DeepSleep::print_wakeup_reason(); - DeepSleep::bootCount++; - ESP_LOGD(TAG, "Boot number: %d", DeepSleep::bootCount); - - // delay(100); - mock_channel0.setup(); - mock_channel1.setup(); - mock_channel2.setup(); - mock_channel3.setup(); - - mock_channel0.setChannel(0); - mock_channel1.setChannel(1); - mock_channel2.setChannel(2); - mock_channel3.setChannel(3); - - ESP_LOGD(TAG, "Setup took %ld ms", millis() - ts); - - try { - // FIXME: put me into seperate trys? No data will be sent when 1 exception occurs - - ts = millis(); - auto messages0 = mock_channel0.buildMessages(); - auto messages1 = mock_channel1.buildMessages(); - auto messages2 = mock_channel2.buildMessages(); - auto messages3 = mock_channel3.buildMessages(); - // roughly takes 500ms, ~120ms for each adc channel, barely anything for battery monitor - ESP_LOGD(TAG, "Reading data and building messages took %ld ms", millis() - ts); - gpio_set_level(GPIO_NUM_32, 0); - - ESP_LOGD(TAG, "Size of message to be sent: %d", sizeof(messages0.front())); - ESP_LOGD(TAG, "Size of Message class: %d", sizeof(Message)); - ESP_LOGD(TAG, "Size of ClientDataPackage class: %d", sizeof(ClientDataPackage)); - // sizeof string - ESP_LOGD(TAG, "Size of string: %d", sizeof(std::string)); - // sizeof string with 5 char - ESP_LOGD(TAG, "Size of string with 5 char: %d", sizeof(char[5])); - // sizeof optional int - ESP_LOGD(TAG, "Size of optional int: %d", sizeof(std::optional<int>)); - // sizeof int - ESP_LOGD(TAG, "Size of int: %d", sizeof(int)); - // sizeof double - ESP_LOGD(TAG, "Size of double: %d", sizeof(double)); - // sizeof float - ESP_LOGD(TAG, "Size of float: %d", sizeof(float)); - // list of 5 compresseddatapackage - CompressedDataPackage compresseddatapackage{}; - ESP_LOGD(TAG, "Size of list of 4 CompressedDataPackage: %d", sizeof(std::list<CompressedDataPackage>) + (sizeof(CompressedDataPackage) * 4)); - // sizeof compresseddatapackage - ESP_LOGD(TAG, "Size of CompressedDataPackage: %d", sizeof(CompressedDataPackage)); - // sizeof list - ESP_LOGD(TAG, "Size of list: %d", sizeof(std::list<CompressedDataPackage>)); - // sizeof vector - ESP_LOGD(TAG, "Size of vector: %d", sizeof(std::vector<CompressedDataPackage>)); - - // FIXME: put this outside the try loop? - ts = millis(); - espnow_setup(); - ESP_LOGD(TAG, "EPSNow setup took %ld ms", millis() - ts); - // make a list of messages - std::list<Message> messages; - messages.insert(messages.end(), messages0.begin(), messages0.end()); - messages.insert(messages.end(), messages1.begin(), messages1.end()); - messages.insert(messages.end(), messages2.begin(), messages2.end()); - messages.insert(messages.end(), messages3.begin(), messages3.end()); - - ts = millis(); -// Message::sendMessages(messages); - send_msgs(messages0); + // disable brownout + WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); + unsigned long ts = millis(); + Serial.begin(115200); + + DeepSleep::print_wakeup_reason(); + DeepSleep::bootCount++; + ESP_LOGD(TAG, "Boot number: %d", DeepSleep::bootCount); + + // delay(100); + mock_channel0.setup(); + mock_channel1.setup(); + mock_channel2.setup(); + mock_channel3.setup(); + + mock_channel0.setChannel(0); + mock_channel1.setChannel(1); + mock_channel2.setChannel(2); + mock_channel3.setChannel(3); + + ESP_LOGD(TAG, "Setup took %ld ms", millis() - ts); + + try { + // FIXME: put me into seperate trys? No data will be sent when 1 exception occurs + + ts = millis(); + auto messages0 = mock_channel0.buildMessages(); + auto messages1 = mock_channel1.buildMessages(); + auto messages2 = mock_channel2.buildMessages(); + auto messages3 = mock_channel3.buildMessages(); + // roughly takes 500ms, ~120ms for each adc channel, barely anything for battery monitor + ESP_LOGD(TAG, + "Reading data and building messages took %ld ms", + millis() - ts); + gpio_set_level(GPIO_NUM_32, 0); + + ESP_LOGD(TAG, "Size of message to be sent: %d", sizeof(messages0.front())); + ESP_LOGD(TAG, "Size of Message class: %d", sizeof(Message)); + ESP_LOGD(TAG, + "Size of ClientDataPackage class: %d", + sizeof(ClientDataPackage)); + // sizeof string + ESP_LOGD(TAG, "Size of string: %d", sizeof(std::string)); + // sizeof string with 5 char + ESP_LOGD(TAG, "Size of string with 5 char: %d", sizeof(char[5])); + // sizeof optional int + ESP_LOGD(TAG, "Size of optional int: %d", sizeof(std::optional<int>)); + // sizeof int + ESP_LOGD(TAG, "Size of int: %d", sizeof(int)); + // sizeof double + ESP_LOGD(TAG, "Size of double: %d", sizeof(double)); + // sizeof float + ESP_LOGD(TAG, "Size of float: %d", sizeof(float)); + // list of 5 compresseddatapackage + CompressedDataPackage compresseddatapackage{}; + ESP_LOGD(TAG, + "Size of list of 4 CompressedDataPackage: %d", + sizeof(std::list<CompressedDataPackage>) + + (sizeof(CompressedDataPackage) * 4)); + // sizeof compresseddatapackage + ESP_LOGD(TAG, + "Size of CompressedDataPackage: %d", + sizeof(CompressedDataPackage)); + // sizeof list + ESP_LOGD(TAG, "Size of list: %d", sizeof(std::list<CompressedDataPackage>)); + // sizeof vector + ESP_LOGD(TAG, + "Size of vector: %d", + sizeof(std::vector<CompressedDataPackage>)); + + // FIXME: put this outside the try loop? + ts = millis(); + espnow_setup(); + ESP_LOGD(TAG, "EPSNow setup took %ld ms", millis() - ts); + // make a list of messages + std::array<Message, 4> messages = + {messages0.front(), messages1.front(), messages2.front(), + Message::nullMessage()}; + + ts = millis(); + Message::sendMessages(messages); +// send_msgs(messages0); // send_msgs(messages1); // send_msgs(messages2); // send_msgs(messages3); - // roughly takes 3s in ideal conditions - ESP_LOGD(TAG, "Sending messages took %ld ms", millis() - ts); + // roughly takes 3s in ideal conditions + ESP_LOGD(TAG, "Sending messages took %ld ms", millis() - ts); - } catch (const NoDataAvailableException &e) { - std::cerr << e.what() << '\n'; - } + } catch (const NoDataAvailableException &e) { + std::cerr << e.what() << '\n'; + } - // battery protection: go to deep sleep for unlimited time when voltage less than 3.2V - DeepSleep::deep_sleep(5); + // battery protection: go to deep sleep for unlimited time when voltage less than 3.2V + DeepSleep::deep_sleep(5); } diff --git a/client/libs/espnow/src/Message.cpp b/client/libs/espnow/src/Message.cpp index fbfe8d2a8451bce8801ee52aeff461c9239c464e..0c159b3d9bacd582bbb9867116270ce6ad7efecb 100644 --- a/client/libs/espnow/src/Message.cpp +++ b/client/libs/espnow/src/Message.cpp @@ -4,75 +4,85 @@ static const char *TAG = "MESSAGE"; esp_err_t Message::send() const { - ESP_LOGD(TAG, "Sending message"); - esp_err_t success; - auto messageData = getCompressedDataPackage(); + ESP_LOGD(TAG, "Sending message"); + esp_err_t success; + auto messageData = getCompressedDataPackage(); - // conversion from std::string to c_str adds null terminator, which is why we add 1 to message length - success = esp_now_send(recipient, (uint8_t * ) & messageData, sizeof(CompressedDataPackage)); - if (success != ESP_OK) { - ESP_LOGE(TAG, "Error sending the data"); - // Removed caching from here, better do this in main - } + // conversion from std::string to c_str adds null terminator, which is why we add 1 to message length + success = esp_now_send(recipient, + (uint8_t *) &messageData, + sizeof(CompressedDataPackage)); + if (success != ESP_OK) { + ESP_LOGE(TAG, "Error sending the data"); + // Removed caching from here, better do this in main + } // ESP_LOGD(TAG, "Sent data: %s", messageData.c_str()); - ESP_LOGD(TAG, "Timestamp sent: %ld", clientDataPackage.getTimestamp()); - ESP_LOGD(TAG, "send status: %d", success); + ESP_LOGD(TAG, "Timestamp sent: %ld", clientDataPackage.getTimestamp()); + ESP_LOGD(TAG, "send status: %d", success); - return success; + return success; } -esp_err_t Message::sendMessages(const std::list<Message> &messages) { - // recipient - uint8_t rec[6]{}; - get_host_mac(rec); - ESP_LOGD(TAG, "Sending messages"); - esp_err_t success; - // list of compressed data - std::list<CompressedDataPackage> compressedDataPackages; - // max 4 messages - int i = 0; - for (const auto &message: messages) { - i++; - compressedDataPackages.push_back(message.getCompressedDataPackage()); - if (i == 4) { - break; - } +esp_err_t Message::sendMessages(const std::array<Message, 4> &messages) { + // recipient + uint8_t rec[6]{}; + get_host_mac(rec); + ESP_LOGD(TAG, "Sending messages"); + esp_err_t success; + // list of compressed data. Sending 4 at a time + std::array<CompressedDataPackage, 4> compressedDataPackages{}; + // max 4 messages + for (int i = 0; i < 4; i++) { + compressedDataPackages[i] = messages[i].getCompressedDataPackage(); + if (messages[i].clientDataPackage.getTimestamp() == NULL_TIMESTAMP) { + compressedDataPackages[i].errorType = ErrorTypes::NULL_MESSAGE; } + } - // conversion from std::string to c_str adds null terminator, which is why we add 1 to message length - success = esp_now_send(rec, (uint8_t * ) & compressedDataPackages, - sizeof(std::list<CompressedDataPackage>) + - 4 * sizeof(CompressedDataPackage)); - if (success != ESP_OK) { - ESP_LOGE(TAG, "Error sending the data"); - // Removed caching from here, better do this in main + // conversion from std::string to c_str adds null terminator, which is why we add 1 to message length + success = esp_now_send(rec, (uint8_t *) &compressedDataPackages, + sizeof(std::array<CompressedDataPackage, 4>)); + if (success != ESP_OK) { + ESP_LOGE(TAG, "Error sending the data"); + // Removed caching from here, better do this in main + } + unsigned long ts = millis(); + // it takes ~110ms for receiving an acknowledgement by the host in perfect conditions + uint16_t message_timeout = 2000; + while (!was_msg_received()) { + if ((millis() - ts) > message_timeout) { + ESP_LOGE(TAG, "Timeout: Host not available\n"); + break; } + } + ESP_LOGD(TAG, "Time until acknowledgement: %ld", millis() - ts); // ESP_LOGD(TAG, "Sent data: %s", messageData.c_str()); // ESP_LOGD(TAG, "Timestamp sent: %ld", clientDataPackage.getTimestamp()); - ESP_LOGD(TAG, "send status: %d", success); + ESP_LOGD(TAG, "send status: %d", success); - return success; + return success; } std::string Message::getMessageAsMinifiedJsonString() const { - return clientDataPackage.getDataPackageAsMinifiedJsonString(); + return clientDataPackage.getDataPackageAsMinifiedJsonString(); } CompressedDataPackage Message::getCompressedDataPackage() const { - return clientDataPackage.getCompressedDataPackage(); + return clientDataPackage.getCompressedDataPackage(); } Message::Message(ClientDataPackage data) : clientDataPackage(std::move(data)) { - // check for existing host mac address, use broadcast otherwise - get_host_mac(recipient); + // check for existing host mac address, use broadcast otherwise + get_host_mac(recipient); } -Message::Message(MeasurementData const &data, const SensorInformation &information, +Message::Message(MeasurementData const &data, + const SensorInformation &information, unsigned long timestamp) - : clientDataPackage(data, information, timestamp) { - // check for existing host mac address, use broadcast otherwise - get_host_mac(recipient); + : clientDataPackage(data, information, timestamp) { + // check for existing host mac address, use broadcast otherwise + get_host_mac(recipient); } diff --git a/client/libs/espnow/src/Message.hpp b/client/libs/espnow/src/Message.hpp index 16e58bee29f4a2a6bea31f1a0acaf6ce46c9698f..3fb4de40ed928c0f1a9892079f34e156bca6efd2 100644 --- a/client/libs/espnow/src/Message.hpp +++ b/client/libs/espnow/src/Message.hpp @@ -14,19 +14,29 @@ // Format of the message sent from host to client_satellite // if more things are sent from the host the name might not be accurate anymore class Message { - public: - explicit Message(ClientDataPackage data); + public: + explicit Message(ClientDataPackage data); - Message(MeasurementData const &data, const SensorInformation &information, unsigned long timestamp); - esp_err_t send() const; - [[nodiscard]] std::string getMessageAsMinifiedJsonString() const; + Message(MeasurementData const &data, + const SensorInformation &information, + unsigned long timestamp); + esp_err_t send() const; + [[nodiscard]] std::string getMessageAsMinifiedJsonString() const; + static Message nullMessage() { + return Message{MeasurementData(ERROR_VALUE, + std::nullopt, + std::nullopt, + "null"), + SensorInformation("null", SensorProtocol::NULL_PROTOCOL), + NULL_TIMESTAMP}; + } - static esp_err_t sendMessages(const std::list<Message>& messages); -private: - ClientDataPackage clientDataPackage; + static esp_err_t sendMessages(const std::array<Message, 4> &messages); + private: + ClientDataPackage clientDataPackage; - uint8_t recipient[6]{}; + uint8_t recipient[6]{}; - CompressedDataPackage getCompressedDataPackage() const; + CompressedDataPackage getCompressedDataPackage() const; }; diff --git a/client/libs/includes/ErrorTypes.h b/client/libs/includes/ErrorTypes.h new file mode 100644 index 0000000000000000000000000000000000000000..27cf13986fa6a5c0cbe45a32a7456ff42f5f7e67 --- /dev/null +++ b/client/libs/includes/ErrorTypes.h @@ -0,0 +1,15 @@ +// +// Created by zoe on 1/27/23. +// + +#ifndef CLIENT_SATELLITE_ERRORTYPES_H +#define CLIENT_SATELLITE_ERRORTYPES_H + +enum ERROR_TYPES { + SENSOR_DOES_NOT_RETURN_DATA = 1, + BATTERY_VOLTAGE_TOO_LOW = 2, + INVALID_VALUE = 3, + SENSOR_NOT_CONNECTED = 4, +}; + +#endif //CLIENT_SATELLITE_ERRORTYPES_H diff --git a/client/libs/includes/SensorProtocol.hpp b/client/libs/includes/SensorProtocol.hpp index 363da3bc0e4f5c85d6ffaf3824f8bbe452b407f8..17e6702e0fff4149247fe1b732cb4f7b19bd73d6 100644 --- a/client/libs/includes/SensorProtocol.hpp +++ b/client/libs/includes/SensorProtocol.hpp @@ -6,10 +6,12 @@ #define CLIENT_PROTOCOL_HPP #include <map> -enum class SensorProtocol { I2C, RS485, Analog, Mock }; +enum class SensorProtocol { I2C, RS485, Analog, Mock, NULL_PROTOCOL }; // sensorProtocol to string const static std::map<SensorProtocol, const char *> protocolToString = { - {SensorProtocol::I2C, "I2C"}, {SensorProtocol::RS485, "RS485"}, {SensorProtocol::Analog, "ANALOG"}, {SensorProtocol::Mock, "MOCK"}}; + {SensorProtocol::I2C, "I2C"}, {SensorProtocol::RS485, "RS485"}, + {SensorProtocol::Analog, "ANALOG"}, {SensorProtocol::Mock, "MOCK"}, + {SensorProtocol::NULL_PROTOCOL, "NULL"}}; #endif // CLIENT_PROTOCOL_HPP diff --git a/client/libs/mock_sensor/MockSensor.cpp b/client/libs/mock_sensor/MockSensor.cpp index 4833773e9b7e26da8ff00842e1fcee47fb613635..5273a20b7391b885ca12bd0e50fbd18d6d0e3c47 100644 --- a/client/libs/mock_sensor/MockSensor.cpp +++ b/client/libs/mock_sensor/MockSensor.cpp @@ -4,31 +4,33 @@ static const char *TAG = "MOCK"; void MockSensor::setup() { - ESP_LOGD(TAG, "MOCK Sensor initialized"); - delay(100); - channel = 0; + ESP_LOGD(TAG, "MOCK Sensor initialized"); + delay(100); + channel = 0; } float MockSensor::readData() { - // generate a random float value between 0 and 100 - float randomValue = (float)rand() / (float)RAND_MAX * 100.0; - ESP_LOGD(TAG, "MOCK Sensor read value: %f", randomValue); - return randomValue; + // generate a random float value between 0 and 100 + float randomValue = (float) rand() / (float) RAND_MAX * 100.0; + ESP_LOGD(TAG, "MOCK Sensor read value: %f", randomValue); + return randomValue; } void MockSensor::setChannel(int c) { - channel = c; + channel = c; } std::list<Message> MockSensor::buildMessages() { - std::list<Message> messages; - float data = readData(); - MeasurementData MockData{data, channel, {}, "MOCK"}; - messages.emplace_back(MockData, sensorInformation, Time::getInstance().getEpochSeconds()); - return messages; + std::list<Message> messages; + float data = readData() + static_cast<float>(DeepSleep::bootCount); + MeasurementData MockData{data, channel, {}, "MOCK"}; + messages.emplace_back(MockData, + sensorInformation, + Time::getInstance().getEpochSeconds()); + return messages; } SensorInformation MockSensor::getSensorInformation() const { - return sensorInformation; + return sensorInformation; } diff --git a/client/libs/mock_sensor/MockSensor.hpp b/client/libs/mock_sensor/MockSensor.hpp index 86cfc03bde30913532ce07e482d5d81d2c825085..d92a40db47d8c70b3d322599a3c7c6a58eb73b08 100644 --- a/client/libs/mock_sensor/MockSensor.hpp +++ b/client/libs/mock_sensor/MockSensor.hpp @@ -7,18 +7,20 @@ #include "Pinout.hpp" #include "esp_log.h" #include <Wire.h> +#include <f_deep_sleep.hpp> -class MockSensor : public ForteSensor<float> { - public: - void setup() override; - float readData() override; - void setChannel(int channel); - std::list<Message> buildMessages() override; - [[nodiscard]] SensorInformation getSensorInformation() const override; - private: - const SensorInformation sensorInformation{"MOCK", SensorProtocol::Mock}; - int channel; +class MockSensor: public ForteSensor<float> { + public: + void setup() override; + float readData() override; + void setChannel(int channel); + std::list<Message> buildMessages() override; + [[nodiscard]] SensorInformation getSensorInformation() const override; + + private: + const SensorInformation sensorInformation{"MOCK", SensorProtocol::Mock}; + int channel; }; #endif \ No newline at end of file diff --git a/host/host_central_mast/lib/Utilities/Utilities.h b/host/host_central_mast/lib/Utilities/Utilities.h index 0b7c61417991f8f45a162ad06eda93ea1e33bb2e..6cd76248b91a702495130e755c89c1834c713ee7 100644 --- a/host/host_central_mast/lib/Utilities/Utilities.h +++ b/host/host_central_mast/lib/Utilities/Utilities.h @@ -5,8 +5,8 @@ #ifndef HOST_CENTRAL_MAST_UTILITIES_H #define HOST_CENTRAL_MAST_UTILITIES_H -#include "../../../client/libs/espnow/src/CompressedDataPackage.hpp" #include "ArduinoJson.h" +#include "CompressedDataPackage.hpp" #include "SD.h" #include "SDCardException.h" #include "SDSetupException.h" @@ -35,6 +35,7 @@ String getMacAddressAsString(const uint8_t *mac); String documentToLineProtocolString(const DynamicJsonDocument &doc); DynamicJsonDocument parseReceivedJsonData(char *data); String documentToServerReadableString(const DynamicJsonDocument &doc); -String compressedDataPackageToServerReadableString(CompressedDataPackage compressedDataPackage, const String& clientMacAddress); +String compressedDataPackageToServerReadableString(CompressedDataPackage compressedDataPackage, + const String &clientMacAddress); #endif // HOST_CENTRAL_MAST_UTILITIES_H diff --git a/host/host_central_mast/platformio.ini b/host/host_central_mast/platformio.ini index f935fa80544f7810f4d3d5e7d9712f08d8551bde..3a473d3374e2808b21462880cb5368deb2d3b2e6 100644 --- a/host/host_central_mast/platformio.ini +++ b/host/host_central_mast/platformio.ini @@ -16,6 +16,8 @@ monitor_speed = 115200 lib_ldf_mode = deep monitor_port = /dev/ttyACM0 upload_port = /dev/ttyACM0 +lib_extra_dirs = + ../../shared-libs build_flags = -I include -DCORE_DEBUG_LEVEL=5 diff --git a/host/host_central_mast/src/main.cpp b/host/host_central_mast/src/main.cpp index f653905482e385958aa0c8ba695d2c126dc8ab52..8f3030f6cb68ba25c1cd82e122f92539f085e725 100644 --- a/host/host_central_mast/src/main.cpp +++ b/host/host_central_mast/src/main.cpp @@ -5,7 +5,7 @@ #define TINY_GSM_MODEM_SIM7000 -#include "../../../client/libs/espnow/src/CompressedDataPackage.hpp" +#include "CompressedDataPackage.hpp" #include "ConnectionManager.h" #include "MessageType.h" #include "SDCardLogger.h" @@ -56,15 +56,13 @@ void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status) { // go to sleep } +/** + * @brief ESPNOW callback function that is called when data is received + * @param mac + * @param incomingData + * @param len length of the incoming data in bytes + */ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) { - esp_log_write(ESP_LOG_INFO, TAG_ESPNOW, "Message recieved\n"); - // copy received data to a char array - CompressedDataPackage compressedDataPackage{}; - memcpy(&compressedDataPackage, incomingData, sizeof(CompressedDataPackage)); - // esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW, "Raw received Data: %s\n", data); - - // log received data - esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW, "Received Data: %s\n", compressedDataPackage.toString().c_str()); if (!esp_now_is_peer_exist(mac)) { esp_now_peer_info_t client = {}; @@ -78,30 +76,45 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) { } } - // TODO: Respond to the client. Maybe do that before parsing anything response response = {}; response.type = dataAck; esp_read_mac(response.mac, ESP_MAC_WIFI_STA); response.time = rtc.getEpoch(); esp_err_t success = esp_now_send(mac, (uint8_t *)&response, sizeof(response)); + esp_log_write(ESP_LOG_INFO, TAG_ESPNOW, "Message recieved\n"); esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW, (success == ESP_OK) ? "Response sent\n" : "Failed to respond\n"); + // copy received data to a char array + std::array<CompressedDataPackage, 4> compressedDataPackage{}; + memcpy(&compressedDataPackage, incomingData, sizeof(std::array<CompressedDataPackage, 4>)); + // esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW, "Raw received Data: %s\n", data); + String macAddress = getMacAddressAsString(mac); - auto doc = compressedDataPackageToServerReadableString(compressedDataPackage, macAddress); + for (auto &data : compressedDataPackage) { - // serialize json document again - std::string dataString{}; + // ignore padding messages + if (data.timestamp == NULL_TIMESTAMP && data.errorType == NULL_MESSAGE) { + continue; + } - try { - SDUtilities::saveStringToSDCard(dataString); - } catch (const std::exception &e) { - esp_log_write(ESP_LOG_ERROR, TAG_ESPNOW, "Failed to save data to SD card: %s", e.what()); - } + // log received data + esp_log_write(ESP_LOG_INFO, TAG_ESPNOW, "Received Data: %s\n", data.toString().c_str()); + auto doc = compressedDataPackageToServerReadableString(data, macAddress); - xSemaphoreTake(xMutex, portMAX_DELAY); - queue.emplace(dataString.c_str()); - xSemaphoreGive(xMutex); + // serialize json document again + std::string dataString{}; + + try { + SDUtilities::saveStringToSDCard(dataString); + } catch (const std::exception &e) { + esp_log_write(ESP_LOG_ERROR, TAG_ESPNOW, "Failed to save data to SD card: %s", e.what()); + } + + xSemaphoreTake(xMutex, portMAX_DELAY); + queue.emplace(dataString.c_str()); + xSemaphoreGive(xMutex); + } } [[noreturn]] void esp_loop() { diff --git a/client/libs/espnow/src/CompressedDataPackage.hpp b/shared-libs/DataTransfer/CompressedDataPackage.hpp similarity index 87% rename from client/libs/espnow/src/CompressedDataPackage.hpp rename to shared-libs/DataTransfer/CompressedDataPackage.hpp index ead67045edc91013a271d5d65bbb0b77558c3ab8..00774f44555aacf652e031e59af99ceed094669b 100644 --- a/client/libs/espnow/src/CompressedDataPackage.hpp +++ b/shared-libs/DataTransfer/CompressedDataPackage.hpp @@ -10,11 +10,15 @@ #include <string> #include <utility> +constexpr double ERROR_VALUE = -999.99; +constexpr unsigned long NULL_TIMESTAMP = 0; // null timestamp + enum ErrorTypes : short { SENSOR_NOT_FOUND, SENSOR_NOT_CONNECTED, NO_DATA, DATA_OK, + NULL_MESSAGE, // message that is sent as padding, should be thrown away }; struct CompressedDataPackage {