Skip to content

Commit 0582410

Browse files
committed
test and fix Diag uploads
1 parent 61007b9 commit 0582410

4 files changed

Lines changed: 103 additions & 23 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
- Provide ChargePointStatus in API ([#309](https://github.com/matth-x/MicroOcpp/pull/309))
1313
- Built-in OTA over FTP ([#313](https://github.com/matth-x/MicroOcpp/pull/313))
14+
- Built-in Diagnostics over FTP ([#313](https://github.com/matth-x/MicroOcpp/pull/313))
1415

1516
### Removed
1617

src/MicroOcpp.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,16 @@ void mocpp_initialize(Connection& connection, const char *bootNotificationCreden
345345
#endif //MO_PLATFORM
346346
#endif //!defined(MO_CUSTOM_UPDATER)
347347

348+
#if !defined(MO_CUSTOM_DIAGNOSTICS)
349+
#if MO_PLATFORM == MO_PLATFORM_ARDUINO && defined(ESP32) && MO_ENABLE_MBEDTLS
350+
model.setDiagnosticsService(
351+
makeDefaultDiagnosticsService(*context, filesystem)); //instantiate Diag service + ESP hardware diagnostics
352+
#elif MO_ENABLE_MBEDTLS
353+
model.setDiagnosticsService(
354+
makeDefaultDiagnosticsService(*context, filesystem)); //instantiate Diag service
355+
#endif //MO_PLATFORM
356+
#endif //!defined(MO_CUSTOM_DIAGNOSTICS)
357+
348358
#if MO_PLATFORM == MO_PLATFORM_ARDUINO && (defined(ESP32) || defined(ESP8266))
349359
setOnResetExecute(makeDefaultResetFn());
350360
#endif

src/MicroOcpp/Model/Diagnostics/DiagnosticsService.cpp

Lines changed: 84 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,20 @@ DiagnosticsService::~DiagnosticsService() {
3838
}
3939

4040
void DiagnosticsService::loop() {
41+
42+
if (ftpUpload && ftpUpload->isActive()) {
43+
ftpUpload->loop();
44+
}
45+
46+
if (ftpUpload) {
47+
if (ftpUpload->isActive()) {
48+
ftpUpload->loop();
49+
} else {
50+
MO_DBG_DEBUG("Deinit FTP upload");
51+
ftpUpload.reset();
52+
}
53+
}
54+
4155
auto notification = getDiagnosticsStatusNotification();
4256
if (notification) {
4357
context.initiateRequest(std::move(notification));
@@ -51,10 +65,12 @@ void DiagnosticsService::loop() {
5165
MO_DBG_DEBUG("Call onUpload");
5266
onUpload(location.c_str(), startTime, stopTime);
5367
uploadIssued = true;
68+
uploadFailure = false;
5469
} else {
5570
MO_DBG_ERR("onUpload must be set! (see setOnUpload). Will abort");
5671
retries = 0;
5772
uploadIssued = false;
73+
uploadFailure = true;
5874
}
5975
}
6076

@@ -88,6 +104,11 @@ void DiagnosticsService::loop() {
88104
nextTry += retryInterval;
89105
}
90106
retries--;
107+
108+
if (retries == 0) {
109+
MO_DBG_DEBUG("end upload routine (no more retry)");
110+
uploadFailure = true;
111+
}
91112
}
92113
}
93114
} //end if (uploadIssued)
@@ -96,10 +117,26 @@ void DiagnosticsService::loop() {
96117

97118
//timestamps before year 2021 will be treated as "undefined"
98119
std::string DiagnosticsService::requestDiagnosticsUpload(const char *location, unsigned int retries, unsigned int retryInterval, Timestamp startTime, Timestamp stopTime) {
99-
if (onUpload == nullptr) //maybe add further plausibility checks
120+
if (onUpload == nullptr) {
100121
return std::string{};
101-
122+
}
123+
124+
std::string fileName;
125+
if (refreshFilename) {
126+
fileName = refreshFilename();
127+
} else {
128+
fileName = "diagnostics.log";
129+
}
130+
131+
this->location.reserve(strlen(location) + 1 + fileName.size());
132+
102133
this->location = location;
134+
135+
if (!this->location.empty() && this->location.back() != '/') {
136+
this->location.append("/");
137+
}
138+
this->location.append(fileName.c_str());
139+
103140
this->retries = retries;
104141
this->retryInterval = retryInterval;
105142
this->startTime = startTime;
@@ -146,16 +183,14 @@ std::string DiagnosticsService::requestDiagnosticsUpload(const char *location, u
146183
}
147184
#endif
148185

149-
std::string fileName;
150-
if (refreshFilename) {
151-
fileName = refreshFilename();
152-
} else {
153-
fileName = "diagnostics.log";
154-
}
155186
return fileName;
156187
}
157188

158189
DiagnosticsStatus DiagnosticsService::getDiagnosticsStatus() {
190+
if (uploadFailure) {
191+
return DiagnosticsStatus::UploadFailed;
192+
}
193+
159194
if (uploadIssued) {
160195
if (uploadStatusInput != nullptr) {
161196
switch (uploadStatusInput()) {
@@ -255,7 +290,7 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
255290
fwVersion.empty() ? "" : " - v. ", fwVersion.c_str(),
256291
jsonDate);
257292

258-
if (ret < 0 || ret >= diagPreambleSize) {
293+
if (ret < 0 || (size_t)ret >= diagPreambleSize) {
259294
MO_DBG_ERR("snprintf: %i", ret);
260295
this->ftpUploadStatus = UploadStatus::UploadFailed;
261296
free(diagPreamble);
@@ -306,13 +341,13 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
306341
context.getConnection().getLastConnected() / 1000UL,
307342
context.getConnection().getLastRecv() / 1000UL,
308343
connector1 ? "\ncId1_hasTx=" : "", connector1 ? (connector1Tx ? "1" : "0") : "",
309-
connector1 ? "\ncId1_txActive=" : "", connector1Tx ? (connector1Tx->isActive() ? "1" : "0") : "",
310-
connector1 ? "\ncId1_hasStarted=" : "", connector1Tx ? (connector1Tx->getStartSync().isRequested() ? "1" : "0") : "",
311-
connector1 ? "\ncId1_hasStopped=" : "", connector1Tx ? (connector1Tx->getStopSync().isRequested() ? "1" : "0") : "",
312-
connector2 ? "\ncId1_hasTx=" : "", connector2 ? (connector2Tx ? "1" : "0") : "",
313-
connector2 ? "\ncId1_txActive=" : "", connector2Tx ? (connector2Tx->isActive() ? "1" : "0") : "",
314-
connector2 ? "\ncId1_hasStarted=" : "", connector2Tx ? (connector2Tx->getStartSync().isRequested() ? "1" : "0") : "",
315-
connector2 ? "\ncId1_hasStopped=" : "", connector2Tx ? (connector2Tx->getStopSync().isRequested() ? "1" : "0") : "",
344+
connector1Tx ? "\ncId1_txActive=" : "", connector1Tx ? (connector1Tx->isActive() ? "1" : "0") : "",
345+
connector1Tx ? "\ncId1_txHasStarted=" : "", connector1Tx ? (connector1Tx->getStartSync().isRequested() ? "1" : "0") : "",
346+
connector1Tx ? "\ncId1_txHasStopped=" : "", connector1Tx ? (connector1Tx->getStopSync().isRequested() ? "1" : "0") : "",
347+
connector2 ? "\ncId2_hasTx=" : "", connector2 ? (connector2Tx ? "1" : "0") : "",
348+
connector2Tx ? "\ncId2_txActive=" : "", connector2Tx ? (connector2Tx->isActive() ? "1" : "0") : "",
349+
connector2Tx ? "\ncId2_txHasStarted=" : "", connector2Tx ? (connector2Tx->getStartSync().isRequested() ? "1" : "0") : "",
350+
connector2Tx ? "\ncId2_txHasStopped=" : "", connector2Tx ? (connector2Tx->getStopSync().isRequested() ? "1" : "0") : "",
316351
MO_ENABLE_CONNECTOR_LOCK,
317352
MO_ENABLE_FILE_INDEX,
318353
MO_ENABLE_V201
@@ -334,6 +369,8 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
334369
diagFileList.emplace_back(fname);
335370
return 0;
336371
});
372+
373+
MO_DBG_DEBUG("discovered %zu files", diagFileList.size());
337374
}
338375

339376
if (ret >= 0 && (size_t)ret + diagPostambleLen < diagPostambleSize) {
@@ -356,7 +393,7 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
356393
written += writeLen;
357394
}
358395

359-
if (written < size && diagReaderHasData) {
396+
if (written < size && diagReaderHasData && diagnosticsReader) {
360397
size_t writeLen = diagnosticsReader((char*)buf, size);
361398
if (writeLen == 0) {
362399
diagReaderHasData = false;
@@ -391,8 +428,10 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
391428
diagFileList.pop_front();
392429
continue;
393430
}
394-
if (ret2 + written > size) {
395-
//heading doesn't fit anymore, return with a bit unused buffer space and print heading the next time
431+
if (ret2 + written > size || //heading doesn't fit anymore, return with a bit unused buffer space and print heading the next time
432+
ret2 + written == size) { //filling the buffer up exactly would mean that no file payload is written and this head gets printed again
433+
434+
MO_DBG_DEBUG("upload diag chunk (%zuB)", written);
396435
return written;
397436
}
398437

@@ -401,7 +440,7 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
401440
}
402441

403442
file->seek(diagFilesFrontTransferred);
404-
size_t writeLen = file->read((char*)buf, size - written);
443+
size_t writeLen = file->read((char*)buf + written, size - written);
405444

406445
if (writeLen < size - written) {
407446
diagFileList.pop_front();
@@ -413,6 +452,7 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
413452
}
414453
}
415454

455+
MO_DBG_DEBUG("upload diag chunk (%zuB)", written);
416456
return written;
417457
},
418458
[this, onClose] (MO_FtpCloseReason reason) -> void {
@@ -428,7 +468,9 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
428468
free(diagPostamble);
429469
diagFileList.clear();
430470

431-
onClose();
471+
if (onClose) {
472+
onClose();
473+
}
432474
});
433475

434476
if (this->ftpUpload) {
@@ -448,3 +490,24 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
448490
void DiagnosticsService::setFtpServerCert(const char *cert) {
449491
this->ftpServerCert = cert;
450492
}
493+
494+
#if !defined(MO_CUSTOM_DIAGNOSTICS)
495+
496+
#if MO_PLATFORM == MO_PLATFORM_ARDUINO && defined(ESP32) && MO_ENABLE_MBEDTLS
497+
498+
std::unique_ptr<DiagnosticsService> MicroOcpp::makeDefaultDiagnosticsService(Context& context, std::shared_ptr<FilesystemAdapter> filesystem) {
499+
500+
}
501+
502+
#elif MO_ENABLE_MBEDTLS
503+
504+
std::unique_ptr<DiagnosticsService> MicroOcpp::makeDefaultDiagnosticsService(Context& context, std::shared_ptr<FilesystemAdapter> filesystem) {
505+
std::unique_ptr<DiagnosticsService> diagService = std::unique_ptr<DiagnosticsService>(new DiagnosticsService(context));
506+
507+
diagService->setDiagnosticsReader(nullptr, nullptr, filesystem); //report the built-in MO defaults
508+
509+
return diagService;
510+
}
511+
512+
#endif //MO_PLATFORM
513+
#endif //!defined(MO_CUSTOM_DIAGNOSTICS)

src/MicroOcpp/Model/Diagnostics/DiagnosticsService.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ class DiagnosticsService {
4141
std::function<bool(const char *location, Timestamp &startTime, Timestamp &stopTime)> onUpload;
4242
std::function<UploadStatus()> uploadStatusInput;
4343
bool uploadIssued = false;
44+
bool uploadFailure = false;
4445

4546
std::unique_ptr<FtpUpload> ftpUpload;
4647
UploadStatus ftpUploadStatus = UploadStatus::NotUploaded;
4748
const char *ftpServerCert = nullptr;
48-
std::shared_ptr<FilesystemAdapter> filesystem;
4949
char *diagPreamble = nullptr;
5050
size_t diagPreambleLen = 0;
5151
size_t diagPreambleTransferred = 0;
@@ -109,7 +109,13 @@ class DiagnosticsService {
109109
#if MO_PLATFORM == MO_PLATFORM_ARDUINO && defined(ESP32) && MO_ENABLE_MBEDTLS
110110

111111
namespace MicroOcpp {
112-
std::unique_ptr<DiagnosticsService> makeDefaultDiagnosticsService(Context& Context);
112+
std::unique_ptr<DiagnosticsService> makeDefaultDiagnosticsService(Context& context, std::shared_ptr<FilesystemAdapter> filesystem);
113+
}
114+
115+
#elif MO_ENABLE_MBEDTLS
116+
117+
namespace MicroOcpp {
118+
std::unique_ptr<DiagnosticsService> makeDefaultDiagnosticsService(Context& context, std::shared_ptr<FilesystemAdapter> filesystem);
113119
}
114120

115121
#endif //MO_PLATFORM == MO_PLATFORM_ARDUINO && defined(ESP32) && MO_ENABLE_MBEDTLS

0 commit comments

Comments
 (0)