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 @@
#include "NoDataAvailableException.hpp"
#include "f_deep_sleep.hpp"
#include <Arduino.h>
#include <CompressedDataPackage.hpp>
#include <ClientDataPackage.hpp>
#include <soc/rtc_cntl_reg.h>
......@@ -92,29 +92,30 @@ void setup() {
// sizeof float
ESP_LOGD(TAG, "Size of float: %d", sizeof(float));
// list of 5 compresseddatapackage
CompressedDataPackage compresseddatapackage{};
ClientDataPackage compresseddatapackage{};
ESP_LOGD(TAG,
"Size of list of 4 CompressedDataPackage: %d",
sizeof(std::list<CompressedDataPackage>)
+ (sizeof(CompressedDataPackage) * 4));
"Size of list of 4 ClientDataPackage: %d",
sizeof(std::list<ClientDataPackage>)
+ (sizeof(ClientDataPackage) * 4));
// sizeof compresseddatapackage
ESP_LOGD(TAG,
"Size of CompressedDataPackage: %d",
sizeof(CompressedDataPackage));
"Size of ClientDataPackage: %d",
sizeof(ClientDataPackage));
// 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
ESP_LOGD(TAG,
"Size of vector: %d",
sizeof(std::vector<CompressedDataPackage>));
sizeof(std::vector<ClientDataPackage>));
// 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 =
std::array<Message, 6> messages =
{messages0.front(), messages1.front(), messages2.front(),
Message::nullMessage(), Message::nullMessage(),
Message::nullMessage()};
ts = millis();
......
#include "Message.hpp"
#include "CompressedDataPackage.hpp"
#include "GlobalDefinitions.hpp"
static const char *TAG = "MESSAGE";
esp_err_t Message::send() const {
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));
(uint8_t *) &clientDataPackage,
sizeof(ClientDataPackage));
if (success != ESP_OK) {
ESP_LOGE(TAG, "Error sending the data");
// Removed caching from here, better do this in main
......@@ -25,26 +22,31 @@ esp_err_t Message::send() const {
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
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{};
// std::array<std::optional<CompressedDataPackage>, 4> cpd{};
// 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;
// list of compressed data. Sending 6 at a time
std::array<ClientDataPackage, 6> clientDataPackages{};
// max 6 messages
int i = 0;
for (const auto &message : messages) {
if (i >= 6) {
ESP_LOGE(TAG, "Too many messages to send");
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
success = esp_now_send(rec, (uint8_t *) &compressedDataPackages,
sizeof(std::array<CompressedDataPackage, 4>));
success = esp_now_send(rec, (uint8_t *) &clientDataPackages,
sizeof(std::array<ClientDataPackage, 6>));
if (success != ESP_OK) {
ESP_LOGE(TAG, "Error sending the data");
// Removed caching from here, better do this in main
......@@ -71,11 +73,7 @@ std::string Message::getMessageAsMinifiedJsonString() const {
return clientDataPackage.getDataPackageAsMinifiedJsonString();
}
CompressedDataPackage Message::getCompressedDataPackage() const {
return clientDataPackage.getCompressedDataPackage();
}
Message::Message(ClientDataPackage data) : clientDataPackage(std::move(data)) {
Message::Message(ClientDataPackage data) : clientDataPackage(data) {
// check for existing host mac address, use broadcast otherwise
get_host_mac(recipient);
}
......@@ -83,8 +81,11 @@ Message::Message(ClientDataPackage data) : clientDataPackage(std::move(data)) {
Message::Message(MeasurementData const &data,
const SensorInformation &information,
unsigned long timestamp)
: clientDataPackage(data, information, timestamp) {
: clientDataPackage(data, information, ErrorType::DATA_OK, timestamp) {
// check for existing host mac address, use broadcast otherwise
get_host_mac(recipient);
}
const ClientDataPackage &Message::getClientDataPackage() const {
return clientDataPackage;
}
......@@ -4,7 +4,6 @@
#include "ESPNow.hpp"
#include "Time.hpp"
#include "esp_log.h"
#include "CompressedDataPackage.hpp"
#include "GlobalDefinitions.hpp"
#include <Arduino.h>
#include <ArduinoJson.h>
......@@ -34,11 +33,11 @@ class Message {
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:
ClientDataPackage clientDataPackage;
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) {
return serverString;
}
String compressedDataPackageToServerReadableString(CompressedDataPackage compressedDataPackage,
String compressedDataPackageToServerReadableString(ClientDataPackage clientDataPackage,
const String &clientMacAddress) {
StaticJsonDocument<300> serverDoc;
String hostMacAddressString = WiFi.macAddress();
......@@ -314,16 +314,16 @@ String compressedDataPackageToServerReadableString(CompressedDataPackage compres
serverDoc["host"] = hostMacAddressString;
serverDoc["client"] = clientMacAddress;
serverDoc["sensorProtocol"] = compressedDataPackage.sensorProtocol;
serverDoc["protocolAddress"] = compressedDataPackage.channel;
serverDoc["i2cAddress"] = compressedDataPackage.i2cAddress;
serverDoc["hardwareName"] = compressedDataPackage.hardwareName;
serverDoc["sensorProtocol"] = clientDataPackage.getSensorInformation().getProtocolString();
serverDoc["protocolAddress"] = clientDataPackage.getMeasurementData().getChannel();
serverDoc["i2cAddress"] = clientDataPackage.getMeasurementData().getI2CAddress();
serverDoc["hardwareName"] = clientDataPackage.getSensorInformation().getHardwareNameString();
// each value is a element in the readigs array
JsonArray readings = serverDoc.createNestedArray("readings");
JsonObject reading = readings.createNestedObject();
reading["name"] = compressedDataPackage.measurementType;
reading["value"] = compressedDataPackage.value;
serverDoc["time"] = compressedDataPackage.timestamp;
reading["name"] = clientDataPackage.getMeasurementData().getMeasurementTypeString();
reading["value"] = clientDataPackage.getMeasurementData().getValue();
serverDoc["time"] = clientDataPackage.getTimestamp();
String serverString;
serializeJson(serverDoc, serverString);
......
......@@ -6,12 +6,12 @@
#define HOST_CENTRAL_MAST_UTILITIES_H
#include "ArduinoJson.h"
#include "CompressedDataPackage.hpp"
#include "SD.h"
#include "SDCardException.h"
#include "SDSetupException.h"
#include "WiFi.h"
#include <Arduino.h>
#include <ClientDataPackage.hpp>
#include <Definitions.h>
#include <WString.h>
#include <list>
......@@ -35,7 +35,6 @@ 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(ClientDataPackage clientDataPackage, const String &clientMacAddress);
#endif // HOST_CENTRAL_MAST_UTILITIES_H
......@@ -5,7 +5,7 @@
#define TINY_GSM_MODEM_SIM7000
#include "CompressedDataPackage.hpp"
#include "ClientDataPackage.hpp"
#include "ConnectionManager.h"
#include "MessageType.h"
#include "SDCardLogger.h"
......@@ -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);
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>));
std::array<ClientDataPackage, 6> compressedDataPackage{};
memcpy(&compressedDataPackage, incomingData, sizeof(std::array<ClientDataPackage, 6>));
// esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW, "Raw received Data: %s\n", data);
String macAddress = getMacAddressAsString(mac);
......@@ -94,13 +95,14 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) {
for (auto &data : compressedDataPackage) {
// ignore padding messages
if (data.timestamp == NULL_TIMESTAMP && data.errorType == NULL_MESSAGE) {
if (data.getTimestamp() == NULL_TIMESTAMP && data.getErrorType() == ErrorType::NULL_MESSAGE) {
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);
// log received data
esp_log_write(ESP_LOG_INFO, TAG_ESPNOW, "Received Data: %s\n",
data.getDataPackageAsMinifiedJsonString().c_str());
// serialize json document again
std::string dataString{};
......
......@@ -4,11 +4,11 @@
#include "MeasurementData.hpp"
#include "SensorProtocol.hpp"
#include "SensorInformation.hpp"
#include "CompressedDataPackage.hpp"
#include <list>
#include <optional>
#include <string>
#include <utility>
#include <ErrorTypes.h>
// having the data be a struct of basic types makes sending easier,
// otherwise we would have to serialize the data before sending
......@@ -16,14 +16,27 @@ class ClientDataPackage {
private:
MeasurementData measurementData;
SensorInformation sensorInformation;
ErrorType errorType;
unsigned long timestamp; // maybe make this array
public:
ClientDataPackage(MeasurementData value, SensorInformation sensorInformation,
ClientDataPackage(MeasurementData value,
SensorInformation sensorInformation,
ErrorType errorType,
unsigned long timestamp)
: measurementData(value),
sensorInformation(sensorInformation),
timestamp(timestamp) {
timestamp(timestamp),
errorType(errorType) {
}
[[nodiscard]] ErrorType getErrorType() const {
return errorType;
}
void setErrorType(ErrorType error) {
ClientDataPackage::errorType = error;
}
[[nodiscard]] const MeasurementData &
......@@ -55,18 +68,10 @@ class ClientDataPackage {
return jsonString;
}
[[nodiscard]] CompressedDataPackage getCompressedDataPackage() const {
CompressedDataPackage compressedDataPackage{};
compressedDataPackage.channel = measurementData.getChannel();
compressedDataPackage.i2cAddress = measurementData.getI2CAddress();
compressedDataPackage.value = measurementData.getValue();
compressedDataPackage.timestamp = timestamp;
compressedDataPackage.errorType = ErrorTypes::DATA_OK;
compressedDataPackage.hardwareName = sensorInformation.getHardwareName();
compressedDataPackage.sensorProtocol = sensorInformation.getProtocol();
compressedDataPackage.measurementType =
measurementData.getMeasurementType();
return compressedDataPackage;
}
ClientDataPackage() : measurementData(MeasurementData(ERROR_VALUE,
MeasurementType::TEMPERATURE)),
sensorInformation(SensorInformation(HardwareName::NONE,
SensorProtocol::NULL_PROTOCOL)),
timestamp(0),
errorType(ErrorType::NO_DATA) {}
};
//
// 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 @@
#define CLIENT_MOCK_ERRORTYPES_H
enum class ErrorTypes: char {
enum class ErrorType: char {
SENSOR_NOT_FOUND,
SENSOR_NOT_CONNECTED,
NO_DATA,
DATA_OK,
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