Skip to content

Commit 01403c6

Browse files
Added possibility to transfer data via LoRaWAN
1 parent e2cf62b commit 01403c6

File tree

16 files changed

+433
-302
lines changed

16 files changed

+433
-302
lines changed

.gitmodules

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,3 @@
1313
[submodule "code/components/RadioLib"]
1414
path = code/components/RadioLib
1515
url = https://github.com/jgromes/RadioLib
16-
[submodule "code/components/CayenneLPP"]
17-
path = code/components/CayenneLPP
18-
url = https://github.com/argetlam-coder/CayenneLPP.git

code/components/CayenneLPP

Lines changed: 0 additions & 1 deletion
This file was deleted.

code/components/jomjol_flowcontroll/ClassFlowControll.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,9 @@ ClassFlow* ClassFlowControll::CreateClassFlow(std::string _type)
275275
}
276276
#endif //ENABLE_MQTT
277277
#ifdef ENABLE_LORAWAN
278-
if (toUpper(_type).compare("[LoRaWAN]") == 0)
278+
if (toUpper(_type).compare("[LORAWAN]") == 0) {
279279
cfc = new ClassFlowLoRaWAN(&FlowControll);
280+
}
280281
#endif //ENABLE_LORAWAN
281282
#ifdef ENABLE_INFLUXDB
282283
if (toUpper(_type).compare("[INFLUXDB]") == 0) {

code/components/jomjol_flowcontroll/ClassFlowLoRaWAN.cpp

Lines changed: 82 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,21 @@ void ClassFlowLoRaWAN::SetInitialParameter(void)
3232
// OTAA parameters
3333
joinEUI = NULL;
3434
devEUI = NULL;
35-
nwkKey[16] = NULL;
36-
appKey[16] = NULL;
35+
nwkKey = NULL;
36+
appKey = NULL;
3737
// ABP parameters
3838
devAddr = NULL;
39-
fNwkSIntKey[16] = NULL;
40-
sNwkSIntKey[16] = NULL;
41-
nwkSEncKey[16] = NULL;
42-
appSKey[16] = NULL;
39+
fNwkSIntKey = NULL;
40+
sNwkSIntKey = NULL;
41+
nwkSEncKey = NULL;
42+
appSKey = NULL;
43+
44+
OldValue = "";
45+
flowpostprocessing = NULL;
46+
previousElement = NULL;
47+
ListFlowControll = NULL;
48+
disabled = false;
49+
LoRaWANenable = false;
4350
}
4451

4552
ClassFlowLoRaWAN::ClassFlowLoRaWAN()
@@ -77,18 +84,38 @@ ClassFlowLoRaWAN::ClassFlowLoRaWAN(std::vector<ClassFlow*>* lfc, ClassFlow *_pre
7784
}
7885
}
7986

87+
88+
std::vector<uint8_t> hexStringToByteArray(const std::string& hexString)
89+
{
90+
std::vector<uint8_t> byteArray;
91+
92+
// Loop through the hex string, two characters at a time
93+
for (size_t i = 0; i < hexString.length(); i += 2) {
94+
// Extract two characters representing a byte
95+
std::string byteString = hexString.substr(i, 2);
96+
97+
// Convert the byte string to a uint8_t value
98+
uint8_t byteValue = static_cast<uint8_t>(
99+
stoi(byteString, nullptr, 16));
100+
101+
// Add the byte to the byte array
102+
byteArray.push_back(byteValue);
103+
}
104+
105+
return byteArray;
106+
}
107+
80108
bool ClassFlowLoRaWAN::ReadParameter(FILE* pfile, string& aktparamgraph)
81109
{
82110
std::vector<string> splitted;
83111

84112
aktparamgraph = trim(aktparamgraph);
85-
printf("akt param: %s\n", aktparamgraph.c_str());
86113

87114
if (aktparamgraph.size() == 0)
88115
if (!this->GetNextParagraph(pfile, aktparamgraph))
89116
return false;
90117

91-
if (toUpper(aktparamgraph).compare("[LoRaWAN]") != 0)
118+
if (toUpper(aktparamgraph).compare("[LORAWAN]") != 0)
92119
return false;
93120

94121
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
@@ -197,11 +224,13 @@ bool ClassFlowLoRaWAN::ReadParameter(FILE* pfile, string& aktparamgraph)
197224
if ((toUpper(_param) == "NWKKEY") && (splitted.size() > 1))
198225
{
199226
std::vector<uint8_t> nwkKeyVector = hexStringToByteArray(splitted[1]);
227+
this->nwkKey = new uint8_t[16];
200228
copy(nwkKeyVector.begin(), nwkKeyVector.end(), this->nwkKey);
201229
}
202230
if ((toUpper(_param) == "APPKEY") && (splitted.size() > 1))
203231
{
204232
std::vector<uint8_t> appKeyVector = hexStringToByteArray(splitted[1]);
233+
this->appKey = new uint8_t[16];
205234
copy(appKeyVector.begin(), appKeyVector.end(), this->appKey);
206235
}
207236
// ABP parameters
@@ -236,136 +265,76 @@ bool ClassFlowLoRaWAN::ReadParameter(FILE* pfile, string& aktparamgraph)
236265

237266
bool ClassFlowLoRaWAN::Start(float AutoInterval)
238267
{
239-
// std::stringstream stream;
240-
// stream << std::fixed << std::setprecision(1) << "Digitizer interval is " << roundInterval <<
241-
// " minutes => setting MQTT LWT timeout to " << ((float)keepAlive/60) << " minutes.";
242-
// LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, stream.str());
268+
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Starting LoRaWAN communication");
243269

244-
// mqttServer_setParameter(flowpostprocessing->GetNumbers(), keepAlive, roundInterval);
245-
246-
// bool MQTTConfigCheck = MQTT_Configure(uri, clientname, user, password, maintopic, LWT_TOPIC, LWT_CONNECTED,
247-
// LWT_DISCONNECTED, caCertFilename, clientCertFilename, clientKeyFilename,
248-
// keepAlive, SetRetainFlag, (void *)&GotConnected);
249-
250-
// if (!MQTTConfigCheck) {
251-
// return false;
252-
// }
253-
254-
// return (MQTT_Init() == 1);
255-
uint16_t LoRaWANInitializeCheck = LoRaWAN_Init(region, subBand, uplinkInterval, initialDatarate, ADRActive,
270+
roundInterval = AutoInterval; // Minutes
271+
uint16_t LoRaWANInitializeCheck = LoRaWAN_Init(region, subBand, roundInterval, uplinkInterval, initialDatarate, ADRActive,
256272
CSMAActive, CSMAMaxChanges, CSMABackoffMax, CSMADifsSlots,
257273
dutyCycleLimitsActive, dutyCycleMsPerHour, dwellTimeLimitsActive, dwellTimeMsPerUplink,
258274
deviceActivationMethod,
259275
joinEUI, devEUI, nwkKey, appKey,
260276
devAddr, fNwkSIntKey, sNwkSIntKey, nwkSEncKey, appSKey);
277+
278+
if (LoRaWANInitializeCheck != 0) {
279+
return false;
280+
}
281+
282+
LoRaWANenable = true;
283+
261284
return true;
262285
}
263286

264287
bool ClassFlowLoRaWAN::doFlow(string zwtime)
265288
{
266-
bool success;
289+
if (!LoRaWANenable)
290+
return true;
291+
267292
std::string result;
268293
std::string resulterror = "";
294+
uint8_t resulterrorCode = 0;
269295
std::string resultraw = "";
270296
std::string resultpre = "";
271297
std::string resultrate = ""; // Always Unit / Minute
272298
std::string resultRatePerTimeUnit = ""; // According to selection
273-
std::string resulttimestamp = "";
274299
std::string resultchangabs = "";
275-
string zw = "";
300+
std::string resulttimestamp = "";
301+
time_t resulttimeutc = 0;
276302
string namenumber = "";
277-
int qos = 1;
278-
279-
/* Send the the Homeassistant Discovery and the Static Topics in case they where scheduled */
280-
// sendDiscovery_and_static_Topics();
281-
282-
// success = publishSystemData(qos);
283-
284-
// if (flowpostprocessing && getMQTTisConnected())
285-
// {
286-
// std::vector<NumberPost*>* NUMBERS = flowpostprocessing->GetNumbers();
287-
288-
// LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Publishing MQTT topics...");
289-
290-
// for (int i = 0; i < (*NUMBERS).size(); ++i)
291-
// {
292-
// result = (*NUMBERS)[i]->ReturnValue;
293-
// resultraw = (*NUMBERS)[i]->ReturnRawValue;
294-
// resultpre = (*NUMBERS)[i]->ReturnPreValue;
295-
// resulterror = (*NUMBERS)[i]->ErrorMessageText;
296-
// resultrate = (*NUMBERS)[i]->ReturnRateValue; // Unit per minutes
297-
// resultchangabs = (*NUMBERS)[i]->ReturnChangeAbsolute; // Units per round
298-
// resulttimestamp = (*NUMBERS)[i]->timeStamp;
299-
300-
// namenumber = (*NUMBERS)[i]->name;
301-
// if (namenumber == "default")
302-
// namenumber = maintopic + "/";
303-
// else
304-
// namenumber = maintopic + "/" + namenumber + "/";
305-
306-
307-
// if (result.length() > 0)
308-
// success |= MQTTPublish(namenumber + "value", result, qos, SetRetainFlag);
309-
310-
// if (resulterror.length() > 0)
311-
// success |= MQTTPublish(namenumber + "error", resulterror, qos, SetRetainFlag);
312-
313-
// if (resultrate.length() > 0) {
314-
// success |= MQTTPublish(namenumber + "rate", resultrate, qos, SetRetainFlag);
315-
316-
// std::string resultRatePerTimeUnit;
317-
// if (getTimeUnit() == "h") { // Need conversion to be per hour
318-
// resultRatePerTimeUnit = resultRatePerTimeUnit = to_string((*NUMBERS)[i]->FlowRateAct * 60); // per minutes => per hour
319-
// }
320-
// else { // Keep per minute
321-
// resultRatePerTimeUnit = resultrate;
322-
// }
323-
// success |= MQTTPublish(namenumber + "rate_per_time_unit", resultRatePerTimeUnit, qos, SetRetainFlag);
324-
// }
325-
326-
// if (resultchangabs.length() > 0) {
327-
// success |= MQTTPublish(namenumber + "changeabsolut", resultchangabs, qos, SetRetainFlag); // Legacy API
328-
// success |= MQTTPublish(namenumber + "rate_per_digitalization_round", resultchangabs, qos, SetRetainFlag);
329-
// }
330-
331-
// if (resultraw.length() > 0)
332-
// success |= MQTTPublish(namenumber + "raw", resultraw, qos, SetRetainFlag);
333-
334-
// if (resulttimestamp.length() > 0)
335-
// success |= MQTTPublish(namenumber + "timestamp", resulttimestamp, qos, SetRetainFlag);
336-
337-
// std::string json = flowpostprocessing->getJsonFromNumber(i, "\n");
338-
// success |= MQTTPublish(namenumber + "json", json, qos, SetRetainFlag);
339-
// }
340-
// }
341-
342-
// OldValue = result;
343303

344-
// if (!success) {
345-
// LogFile.WriteToFile(ESP_LOG_WARN, TAG, "One or more MQTT topics failed to be published!");
346-
// }
347-
348-
return true;
349-
}
304+
if (flowpostprocessing && getLoRaWANisSessionActive())
305+
{
306+
std::vector<NumberPost*>* NUMBERS = flowpostprocessing->GetNumbers();
350307

351-
std::vector<uint8_t> hexStringToByteArray(const std::string& hexString)
352-
{
353-
std::vector<uint8_t> byteArray;
308+
for (int i = 0; i < (*NUMBERS).size(); ++i)
309+
{
310+
result = (*NUMBERS)[i]->ReturnValue;
311+
resultraw = (*NUMBERS)[i]->ReturnRawValue;
312+
resulterror = (*NUMBERS)[i]->ErrorMessageText;
313+
resultrate = (*NUMBERS)[i]->ReturnRateValue; // Unit per minutes
314+
resulttimeutc = (*NUMBERS)[i]->timeStampTimeUTC;
354315

355-
// Loop through the hex string, two characters at a time
356-
for (size_t i = 0; i < hexString.length(); i += 2) {
357-
// Extract two characters representing a byte
358-
std::string byteString = hexString.substr(i, 2);
316+
namenumber = (*NUMBERS)[i]->name;
359317

360-
// Convert the byte string to a uint8_t value
361-
uint8_t byteValue = static_cast<uint8_t>(
362-
stoi(byteString, nullptr, 16));
318+
if (resulterror == "no error") {
319+
resulterrorCode = 0;
320+
}
321+
else{
322+
if (resulterror.rfind("Neg. Rate", 0) == 0){
323+
resulterrorCode = 1;
324+
}
325+
if (resulterror.rfind("Rate too high", 0) == 0){
326+
resulterrorCode = 2;
327+
}
328+
}
363329

364-
// Add the byte to the byte array
365-
byteArray.push_back(byteValue);
330+
if (result.length() > 0) {}
331+
LoRaWANQueueMessage(i, resulttimeutc, std::stod(result), std::stod(resultrate), resulterrorCode);
332+
}
366333
}
367-
368-
return byteArray;
334+
335+
OldValue = result;
336+
337+
return true;
369338
}
370339

371340
#endif //ENABLE_LORAWAN

code/components/jomjol_flowcontroll/ClassFlowLoRaWAN.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class ClassFlowLoRaWAN :
2121
protected:
2222
LoRaWANBand_t region;
2323
uint8_t subBand;
24+
float roundInterval; // Minutes
2425
uint32_t uplinkInterval;
2526
uint8_t initialDatarate;
2627
bool ADRActive;
@@ -36,15 +37,17 @@ class ClassFlowLoRaWAN :
3637
// OTAA parameters
3738
uint64_t joinEUI;
3839
uint64_t devEUI;
39-
uint8_t nwkKey[16];
40-
uint8_t appKey[16];
40+
uint8_t *nwkKey;
41+
uint8_t *appKey;
4142
// ABP parameters
4243
uint32_t devAddr;
43-
uint8_t fNwkSIntKey[16];
44-
uint8_t sNwkSIntKey[16];
45-
uint8_t nwkSEncKey[16];
46-
uint8_t appSKey[16];
44+
uint8_t *fNwkSIntKey;
45+
uint8_t *sNwkSIntKey;
46+
uint8_t *nwkSEncKey;
47+
uint8_t *appSKey;
48+
std::string OldValue;
4749
ClassFlowPostProcessing* flowpostprocessing;
50+
bool LoRaWANenable;
4851

4952
void SetInitialParameter(void);
5053

code/components/jomjol_helper/Helper.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ extern "C"
3131
#include "ClassLogFile.h"
3232

3333
#include "esp_vfs_fat.h"
34-
#include "../sdmmc_common.h"
34+
#include "esp_private/sdmmc_common.h"
3535

3636
#ifdef CONFIG_SOC_TEMP_SENSOR_SUPPORTED
3737
#include "driver/temperature_sensor.h"

code/components/jomjol_lorawan/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
22

33
idf_component_register(SRCS ${app_sources}
44
INCLUDE_DIRS "."
5-
REQUIRES CayenneLPP RadioLib jomjol_wlan)
5+
REQUIRES RadioLib driver esp_timer esp_wifi nvs_flash jomjol_flowcontroll)

code/components/jomjol_lorawan/RadioLibEspHal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
// include RadioLib
66
#include <RadioLib.h>
7-
#include "driver/spi_common.h"
7+
#include <driver/spi_common.h>
88

99
// this example only works on ESP32 and is unlikely to work on ESP32S2/S3 etc.
1010
// if you need high portability, you should probably use Arduino anyway ...

0 commit comments

Comments
 (0)