Skip to content
Snippets Groups Projects
Verified Commit 6be64b61 authored by Zoe Michaela Dietmar Pfister's avatar Zoe Michaela Dietmar Pfister :gay_pride_flag:
Browse files

Possibility to send 6 messages with one ESPNow-send action

parent 8f0a8f78
No related branches found
No related tags found
2 merge requests!39Merge Develop into Main,!27Move from json-string based transfer between client and host to C struct / class based transfer
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include "NoDataAvailableException.hpp" #include "NoDataAvailableException.hpp"
#include "f_deep_sleep.hpp" #include "f_deep_sleep.hpp"
#include <Arduino.h> #include <Arduino.h>
#include <CompressedDataPackage.hpp> #include <ClientDataPackage.hpp>
#include <soc/rtc_cntl_reg.h> #include <soc/rtc_cntl_reg.h>
...@@ -92,29 +92,30 @@ void setup() { ...@@ -92,29 +92,30 @@ void setup() {
// sizeof float // sizeof float
ESP_LOGD(TAG, "Size of float: %d", sizeof(float)); ESP_LOGD(TAG, "Size of float: %d", sizeof(float));
// list of 5 compresseddatapackage // list of 5 compresseddatapackage
CompressedDataPackage compresseddatapackage{}; ClientDataPackage compresseddatapackage{};
ESP_LOGD(TAG, ESP_LOGD(TAG,
"Size of list of 4 CompressedDataPackage: %d", "Size of list of 4 ClientDataPackage: %d",
sizeof(std::list<CompressedDataPackage>) sizeof(std::list<ClientDataPackage>)
+ (sizeof(CompressedDataPackage) * 4)); + (sizeof(ClientDataPackage) * 4));
// sizeof compresseddatapackage // sizeof compresseddatapackage
ESP_LOGD(TAG, ESP_LOGD(TAG,
"Size of CompressedDataPackage: %d", "Size of ClientDataPackage: %d",
sizeof(CompressedDataPackage)); sizeof(ClientDataPackage));
// sizeof list // sizeof list
ESP_LOGD(TAG, "Size of list: %d", sizeof(std::list<CompressedDataPackage>)); ESP_LOGD(TAG, "Size of list: %d", sizeof(std::list<ClientDataPackage>));
// sizeof vector // sizeof vector
ESP_LOGD(TAG, ESP_LOGD(TAG,
"Size of vector: %d", "Size of vector: %d",
sizeof(std::vector<CompressedDataPackage>)); sizeof(std::vector<ClientDataPackage>));
// FIXME: put this outside the try loop? // FIXME: put this outside the try loop?
ts = millis(); ts = millis();
espnow_setup(); espnow_setup();
ESP_LOGD(TAG, "EPSNow setup took %ld ms", millis() - ts); ESP_LOGD(TAG, "EPSNow setup took %ld ms", millis() - ts);
// make a list of messages // make a list of messages
std::array<Message, 4> messages = std::array<Message, 6> messages =
{messages0.front(), messages1.front(), messages2.front(), {messages0.front(), messages1.front(), messages2.front(),
Message::nullMessage(), Message::nullMessage(),
Message::nullMessage()}; Message::nullMessage()};
ts = millis(); ts = millis();
......
#include "Message.hpp" #include "Message.hpp"
#include "CompressedDataPackage.hpp"
#include "GlobalDefinitions.hpp"
static const char *TAG = "MESSAGE"; static const char *TAG = "MESSAGE";
esp_err_t Message::send() const { esp_err_t Message::send() const {
ESP_LOGD(TAG, "Sending message"); ESP_LOGD(TAG, "Sending message");
esp_err_t success; 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 // conversion from std::string to c_str adds null terminator, which is why we add 1 to message length
success = esp_now_send(recipient, success = esp_now_send(recipient,
(uint8_t *) &messageData, (uint8_t *) &clientDataPackage,
sizeof(CompressedDataPackage)); sizeof(ClientDataPackage));
if (success != ESP_OK) { if (success != ESP_OK) {
ESP_LOGE(TAG, "Error sending the data"); ESP_LOGE(TAG, "Error sending the data");
// Removed caching from here, better do this in main // Removed caching from here, better do this in main
...@@ -25,26 +22,31 @@ esp_err_t Message::send() const { ...@@ -25,26 +22,31 @@ esp_err_t Message::send() const {
return success; return success;
} }
esp_err_t Message::sendMessages(const std::array<Message, 4> &messages) { esp_err_t Message::sendMessages(const std::array<Message, 6> &messages) {
// recipient // recipient
uint8_t rec[6]{}; uint8_t rec[6]{};
get_host_mac(rec); get_host_mac(rec);
ESP_LOGD(TAG, "Sending messages"); ESP_LOGD(TAG, "Sending messages");
esp_err_t success; esp_err_t success;
// list of compressed data. Sending 4 at a time // list of compressed data. Sending 6 at a time
std::array<CompressedDataPackage, 4> compressedDataPackages{}; std::array<ClientDataPackage, 6> clientDataPackages{};
// std::array<std::optional<CompressedDataPackage>, 4> cpd{}; // max 6 messages
// max 4 messages int i = 0;
for (int i = 0; i < 4; i++) { for (const auto &message : messages) {
compressedDataPackages[i] = messages[i].getCompressedDataPackage(); if (i >= 6) {
if (messages[i].clientDataPackage.getTimestamp() == NULL_TIMESTAMP) { ESP_LOGE(TAG, "Too many messages to send");
compressedDataPackages[i].errorType = ErrorTypes::NULL_MESSAGE; break;
}
clientDataPackages[i] = message.getClientDataPackage();
if (message.clientDataPackage.getTimestamp() == NULL_TIMESTAMP) {
clientDataPackages[i].setErrorType(ErrorType::NULL_MESSAGE);
} }
i++;
} }
// conversion from std::string to c_str adds null terminator, which is why we add 1 to message length // 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, success = esp_now_send(rec, (uint8_t *) &clientDataPackages,
sizeof(std::array<CompressedDataPackage, 4>)); sizeof(std::array<ClientDataPackage, 6>));
if (success != ESP_OK) { if (success != ESP_OK) {
ESP_LOGE(TAG, "Error sending the data"); ESP_LOGE(TAG, "Error sending the data");
// Removed caching from here, better do this in main // Removed caching from here, better do this in main
...@@ -71,11 +73,7 @@ std::string Message::getMessageAsMinifiedJsonString() const { ...@@ -71,11 +73,7 @@ std::string Message::getMessageAsMinifiedJsonString() const {
return clientDataPackage.getDataPackageAsMinifiedJsonString(); return clientDataPackage.getDataPackageAsMinifiedJsonString();
} }
CompressedDataPackage Message::getCompressedDataPackage() const { Message::Message(ClientDataPackage data) : clientDataPackage(data) {
return clientDataPackage.getCompressedDataPackage();
}
Message::Message(ClientDataPackage data) : clientDataPackage(std::move(data)) {
// check for existing host mac address, use broadcast otherwise // check for existing host mac address, use broadcast otherwise
get_host_mac(recipient); get_host_mac(recipient);
} }
...@@ -83,8 +81,11 @@ Message::Message(ClientDataPackage data) : clientDataPackage(std::move(data)) { ...@@ -83,8 +81,11 @@ Message::Message(ClientDataPackage data) : clientDataPackage(std::move(data)) {
Message::Message(MeasurementData const &data, Message::Message(MeasurementData const &data,
const SensorInformation &information, const SensorInformation &information,
unsigned long timestamp) unsigned long timestamp)
: clientDataPackage(data, information, timestamp) { : clientDataPackage(data, information, ErrorType::DATA_OK, timestamp) {
// check for existing host mac address, use broadcast otherwise // check for existing host mac address, use broadcast otherwise
get_host_mac(recipient); get_host_mac(recipient);
} }
const ClientDataPackage &Message::getClientDataPackage() const {
return clientDataPackage;
}
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
#include "ESPNow.hpp" #include "ESPNow.hpp"
#include "Time.hpp" #include "Time.hpp"
#include "esp_log.h" #include "esp_log.h"
#include "CompressedDataPackage.hpp"
#include "GlobalDefinitions.hpp" #include "GlobalDefinitions.hpp"
#include <Arduino.h> #include <Arduino.h>
#include <ArduinoJson.h> #include <ArduinoJson.h>
...@@ -34,11 +33,11 @@ class Message { ...@@ -34,11 +33,11 @@ class Message {
NULL_TIMESTAMP}; NULL_TIMESTAMP};
} }
static esp_err_t sendMessages(const std::array<Message, 4> &messages); static esp_err_t sendMessages(const std::array<Message, 6> &messages);
[[nodiscard]] const ClientDataPackage &getClientDataPackage() const;
private: private:
ClientDataPackage clientDataPackage; ClientDataPackage clientDataPackage;
uint8_t recipient[6]{}; uint8_t recipient[6]{};
CompressedDataPackage getCompressedDataPackage() const;
}; };
//
// 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
...@@ -305,7 +305,7 @@ String documentToServerReadableString(const DynamicJsonDocument &doc) { ...@@ -305,7 +305,7 @@ String documentToServerReadableString(const DynamicJsonDocument &doc) {
return serverString; return serverString;
} }
String compressedDataPackageToServerReadableString(CompressedDataPackage compressedDataPackage, String compressedDataPackageToServerReadableString(ClientDataPackage clientDataPackage,
const String &clientMacAddress) { const String &clientMacAddress) {
StaticJsonDocument<300> serverDoc; StaticJsonDocument<300> serverDoc;
String hostMacAddressString = WiFi.macAddress(); String hostMacAddressString = WiFi.macAddress();
...@@ -314,16 +314,16 @@ String compressedDataPackageToServerReadableString(CompressedDataPackage compres ...@@ -314,16 +314,16 @@ String compressedDataPackageToServerReadableString(CompressedDataPackage compres
serverDoc["host"] = hostMacAddressString; serverDoc["host"] = hostMacAddressString;
serverDoc["client"] = clientMacAddress; serverDoc["client"] = clientMacAddress;
serverDoc["sensorProtocol"] = compressedDataPackage.sensorProtocol; serverDoc["sensorProtocol"] = clientDataPackage.getSensorInformation().getProtocolString();
serverDoc["protocolAddress"] = compressedDataPackage.channel; serverDoc["protocolAddress"] = clientDataPackage.getMeasurementData().getChannel();
serverDoc["i2cAddress"] = compressedDataPackage.i2cAddress; serverDoc["i2cAddress"] = clientDataPackage.getMeasurementData().getI2CAddress();
serverDoc["hardwareName"] = compressedDataPackage.hardwareName; serverDoc["hardwareName"] = clientDataPackage.getSensorInformation().getHardwareNameString();
// each value is a element in the readigs array // each value is a element in the readigs array
JsonArray readings = serverDoc.createNestedArray("readings"); JsonArray readings = serverDoc.createNestedArray("readings");
JsonObject reading = readings.createNestedObject(); JsonObject reading = readings.createNestedObject();
reading["name"] = compressedDataPackage.measurementType; reading["name"] = clientDataPackage.getMeasurementData().getMeasurementTypeString();
reading["value"] = compressedDataPackage.value; reading["value"] = clientDataPackage.getMeasurementData().getValue();
serverDoc["time"] = compressedDataPackage.timestamp; serverDoc["time"] = clientDataPackage.getTimestamp();
String serverString; String serverString;
serializeJson(serverDoc, serverString); serializeJson(serverDoc, serverString);
......
...@@ -6,12 +6,12 @@ ...@@ -6,12 +6,12 @@
#define HOST_CENTRAL_MAST_UTILITIES_H #define HOST_CENTRAL_MAST_UTILITIES_H
#include "ArduinoJson.h" #include "ArduinoJson.h"
#include "CompressedDataPackage.hpp"
#include "SD.h" #include "SD.h"
#include "SDCardException.h" #include "SDCardException.h"
#include "SDSetupException.h" #include "SDSetupException.h"
#include "WiFi.h" #include "WiFi.h"
#include <Arduino.h> #include <Arduino.h>
#include <ClientDataPackage.hpp>
#include <Definitions.h> #include <Definitions.h>
#include <WString.h> #include <WString.h>
#include <list> #include <list>
...@@ -35,7 +35,6 @@ String getMacAddressAsString(const uint8_t *mac); ...@@ -35,7 +35,6 @@ String getMacAddressAsString(const uint8_t *mac);
String documentToLineProtocolString(const DynamicJsonDocument &doc); String documentToLineProtocolString(const DynamicJsonDocument &doc);
DynamicJsonDocument parseReceivedJsonData(char *data); DynamicJsonDocument parseReceivedJsonData(char *data);
String documentToServerReadableString(const DynamicJsonDocument &doc); String documentToServerReadableString(const DynamicJsonDocument &doc);
String compressedDataPackageToServerReadableString(CompressedDataPackage compressedDataPackage, String compressedDataPackageToServerReadableString(ClientDataPackage clientDataPackage, const String &clientMacAddress);
const String &clientMacAddress);
#endif // HOST_CENTRAL_MAST_UTILITIES_H #endif // HOST_CENTRAL_MAST_UTILITIES_H
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#define TINY_GSM_MODEM_SIM7000 #define TINY_GSM_MODEM_SIM7000
#include "CompressedDataPackage.hpp" #include "ClientDataPackage.hpp"
#include "ConnectionManager.h" #include "ConnectionManager.h"
#include "MessageType.h" #include "MessageType.h"
#include "SDCardLogger.h" #include "SDCardLogger.h"
...@@ -81,12 +81,13 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) { ...@@ -81,12 +81,13 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) {
esp_read_mac(response.mac, ESP_MAC_WIFI_STA); esp_read_mac(response.mac, ESP_MAC_WIFI_STA);
response.time = rtc.getEpoch(); response.time = rtc.getEpoch();
esp_err_t success = esp_now_send(mac, (uint8_t *)&response, sizeof(response)); 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_INFO, TAG_ESPNOW, "Message recieved\n");
esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW, (success == ESP_OK) ? "Response sent\n" : "Failed to respond\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 // copy received data to a char array
std::array<CompressedDataPackage, 4> compressedDataPackage{}; std::array<ClientDataPackage, 6> compressedDataPackage{};
memcpy(&compressedDataPackage, incomingData, sizeof(std::array<CompressedDataPackage, 4>)); memcpy(&compressedDataPackage, incomingData, sizeof(std::array<ClientDataPackage, 6>));
// esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW, "Raw received Data: %s\n", data); // esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW, "Raw received Data: %s\n", data);
String macAddress = getMacAddressAsString(mac); String macAddress = getMacAddressAsString(mac);
...@@ -94,13 +95,14 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) { ...@@ -94,13 +95,14 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) {
for (auto &data : compressedDataPackage) { for (auto &data : compressedDataPackage) {
// ignore padding messages // ignore padding messages
if (data.timestamp == NULL_TIMESTAMP && data.errorType == NULL_MESSAGE) { if (data.getTimestamp() == NULL_TIMESTAMP && data.getErrorType() == ErrorType::NULL_MESSAGE) {
continue; continue;
} }
// log received data
esp_log_write(ESP_LOG_INFO, TAG_ESPNOW, "Received Data: %s\n", data.toString().c_str());
auto doc = compressedDataPackageToServerReadableString(data, macAddress); auto doc = compressedDataPackageToServerReadableString(data, macAddress);
// log received data
esp_log_write(ESP_LOG_INFO, TAG_ESPNOW, "Received Data: %s\n",
data.getDataPackageAsMinifiedJsonString().c_str());
// serialize json document again // serialize json document again
std::string dataString{}; std::string dataString{};
......
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
#include "MeasurementData.hpp" #include "MeasurementData.hpp"
#include "SensorProtocol.hpp" #include "SensorProtocol.hpp"
#include "SensorInformation.hpp" #include "SensorInformation.hpp"
#include "CompressedDataPackage.hpp"
#include <list> #include <list>
#include <optional> #include <optional>
#include <string> #include <string>
#include <utility> #include <utility>
#include <ErrorTypes.h>
// having the data be a struct of basic types makes sending easier, // having the data be a struct of basic types makes sending easier,
// otherwise we would have to serialize the data before sending // otherwise we would have to serialize the data before sending
...@@ -16,14 +16,27 @@ class ClientDataPackage { ...@@ -16,14 +16,27 @@ class ClientDataPackage {
private: private:
MeasurementData measurementData; MeasurementData measurementData;
SensorInformation sensorInformation; SensorInformation sensorInformation;
ErrorType errorType;
unsigned long timestamp; // maybe make this array unsigned long timestamp; // maybe make this array
public: public:
ClientDataPackage(MeasurementData value, SensorInformation sensorInformation, ClientDataPackage(MeasurementData value,
SensorInformation sensorInformation,
ErrorType errorType,
unsigned long timestamp) unsigned long timestamp)
: measurementData(value), : measurementData(value),
sensorInformation(sensorInformation), sensorInformation(sensorInformation),
timestamp(timestamp) { timestamp(timestamp),
errorType(errorType) {
}
[[nodiscard]] ErrorType getErrorType() const {
return errorType;
}
void setErrorType(ErrorType error) {
ClientDataPackage::errorType = error;
} }
[[nodiscard]] const MeasurementData & [[nodiscard]] const MeasurementData &
...@@ -55,18 +68,10 @@ class ClientDataPackage { ...@@ -55,18 +68,10 @@ class ClientDataPackage {
return jsonString; return jsonString;
} }
[[nodiscard]] CompressedDataPackage getCompressedDataPackage() const { ClientDataPackage() : measurementData(MeasurementData(ERROR_VALUE,
CompressedDataPackage compressedDataPackage{}; MeasurementType::TEMPERATURE)),
compressedDataPackage.channel = measurementData.getChannel(); sensorInformation(SensorInformation(HardwareName::NONE,
compressedDataPackage.i2cAddress = measurementData.getI2CAddress(); SensorProtocol::NULL_PROTOCOL)),
compressedDataPackage.value = measurementData.getValue(); timestamp(0),
compressedDataPackage.timestamp = timestamp; errorType(ErrorType::NO_DATA) {}
compressedDataPackage.errorType = ErrorTypes::DATA_OK;
compressedDataPackage.hardwareName = sensorInformation.getHardwareName();
compressedDataPackage.sensorProtocol = sensorInformation.getProtocol();
compressedDataPackage.measurementType =
measurementData.getMeasurementType();
return compressedDataPackage;
}
}; };
//
// Created by cynthya on 1/27/23.
//
#ifndef CLIENT_MOCK_COMPRESSEDDATAPACKAGE_HPP
#define CLIENT_MOCK_COMPRESSEDDATAPACKAGE_HPP
#include <ArduinoJson.h>
#include <list>
#include <string>
#include <utility>
#include "ErrorTypes.h"
// null timestamp
struct CompressedDataPackage {
int channel; // can this be short?
int i2cAddress; // can this be short?
double value;
unsigned long timestamp;
ErrorTypes errorType;
HardwareName hardwareName;
SensorProtocol sensorProtocol;
MeasurementType measurementType;
// same could be done for hardwarename and sensorprotocol
// tostring
[[nodiscard]] std::string toString() const {
StaticJsonDocument<250> document; // 250 byte is the max send size of espnow
document["hardwareName"] =
HardwareNames::hardwareNameToString(hardwareName);
document["timestamp"] = timestamp;
document["sensorProtocol"] =
SensorProtocols::sensorProtocolToString(sensorProtocol);
document["value"] = value;
if (channel != -1) {
document["channel"] = channel;
}
if (i2cAddress != -1) {
document["i2cAddress"] = i2cAddress;
}
document["measurementType"] =
MeasurementTypes::measurementTypeToString(measurementType);
std::string jsonString;
serializeJson(document, jsonString);
return jsonString;
}
};
#endif // CLIENT_MOCK_COMPRESSEDDATAPACKAGE_HPP
...@@ -6,12 +6,15 @@ ...@@ -6,12 +6,15 @@
#define CLIENT_MOCK_ERRORTYPES_H #define CLIENT_MOCK_ERRORTYPES_H
enum class ErrorTypes: char { enum class ErrorType: char {
SENSOR_NOT_FOUND, SENSOR_NOT_FOUND,
SENSOR_NOT_CONNECTED, SENSOR_NOT_CONNECTED,
NO_DATA, NO_DATA,
DATA_OK, DATA_OK,
NULL_MESSAGE, // message that is sent as padding, should be thrown away NULL_MESSAGE, // message that is sent as padding, should be thrown away
SENSOR_DOES_NOT_RETURN_DATA,
BATTERY_VOLTAGE_TOO_LOW,
INVALID_VALUE,
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment