@@ -34,10 +34,11 @@ ArduinoOcppTask::~ArduinoOcppTask() {
3434 instance = NULL ;
3535}
3636
37- void ArduinoOcppTask::begin (EvseManager &evse, LcdTask &lcd) {
37+ void ArduinoOcppTask::begin (EvseManager &evse, LcdTask &lcd, EventLog &eventLog ) {
3838
3939 this ->evse = &evse;
4040 this ->lcd = &lcd;
41+ this ->eventLog = &eventLog;
4142
4243 initializeArduinoOcpp ();
4344 loadEvseBehavior ();
@@ -79,7 +80,7 @@ void ArduinoOcppTask::initializeArduinoOcpp() {
7980 if (!updateUserNotified && index > 0) {
8081 updateUserNotified = true;
8182
82- DEBUG_PORT.printf ("Update via OCPP start\n");
83+ DBUG ("Update via OCPP start\n");
8384
8485 lcd->display(F("Updating WiFi"), 0, 0, 10 * 1000, LCD_CLEAR_LINE | LCD_DISPLAY_NOW);
8586 lcd->display(F(""), 0, 1, 10 * 1000, LCD_CLEAR_LINE | LCD_DISPLAY_NOW);
@@ -95,7 +96,7 @@ void ArduinoOcppTask::initializeArduinoOcpp() {
9596 DBUGVAR(percent);
9697 String text = String(percent) + F("%");
9798 if (lcd) lcd->display(text, 0, 1, 10 * 1000, LCD_DISPLAY_NOW);
98- DEBUG_PORT.printf ("Update: %d%%\n", percent);
99+ DBUGF ("Update: %d%%\n", percent);
99100 } else {
100101 lcd->display(F("Complete"), 0, 1, 10 * 1000, LCD_CLEAR_LINE | LCD_DISPLAY_NOW);
101102 }
@@ -109,7 +110,7 @@ void ArduinoOcppTask::initializeArduinoOcpp() {
109110// });
110111
111112#endif
112- DEBUG_PORT. println (F (" [ocpp] FW download not implemented yet! Ignore request" ));
113+ DBUGLN (F (" [ocpp] FW download not implemented yet! Ignore request" ));
113114
114115 return true ;
115116 });
@@ -137,18 +138,98 @@ void ArduinoOcppTask::initializeArduinoOcpp() {
137138 unsigned int port_i = 0 ;
138139 struct mg_str scheme, query, fragment;
139140 if (mg_parse_uri (mg_mk_str (location.c_str ()), &scheme, NULL , NULL , &port_i, NULL , &query, &fragment)) {
140- DEBUG_PORT.print (F (" [ocpp] Diagnostics upload, invalid URL: " ));
141- DEBUG_PORT.print (location);
141+ DBUG (F (" [ocpp] Diagnostics upload, invalid URL: " ));
142+ DBUGLN (location);
143+ diagFailure = true ;
144+ return false ;
145+ }
146+
147+ if (eventLog == NULL ) {
142148 diagFailure = true ;
143149 return false ;
144150 }
145151
146152 // create file to upload
147-
153+ #define BOUNDARY_STRING " -----------------------------WebKitFormBoundary7MA4YWxkTrZu0gW025636501"
154+ const char *bodyPrefix PROGMEM = BOUNDARY_STRING " \r\n "
155+ " Content-Disposition: form-data; name=\" file\" ; filename=\" diagnostics.log\"\r\n "
156+ " Content-Type: application/octet-stream\r\n\r\n " ;
157+ const char *bodySuffix PROGMEM = " \r\n\r\n " BOUNDARY_STRING " --\r\n " ;
158+ const char *overflowMsg PROGMEM = " {\" diagnosticsMsg\" :\" requested search period exceeds maximum diagnostics upload size\" }" ;
159+
160+ const size_t MAX_BODY_SIZE = 10000 ; // limit length of message
161+ String body = String (' \0 ' );
162+ body.reserve (MAX_BODY_SIZE);
163+ body += bodyPrefix;
164+ body += " [" ;
165+ const size_t SUFFIX_RESERVED_AREA = MAX_BODY_SIZE - strlen (bodySuffix) - strlen (overflowMsg) - 2 ;
166+
167+ bool firstEntry = true ;
168+ bool overflow = false ;
169+ for (uint32_t i = 0 ; i <= (eventLog->getMaxIndex () - eventLog->getMinIndex ()) && !overflow; i++) {
170+ uint32_t index = eventLog->getMinIndex () + i;
171+
172+ eventLog->enumerate(index, [this , startTime, stopTime, &body, SUFFIX_RESERVED_AREA, &firstEntry, &overflow] (String time, EventType type, const String &logEntry, EvseState managerState, uint8_t evseState, uint32_t evseFlags, uint32_t pilot, double energy, uint32_t elapsed, double temperature, double temperatureMax, uint8_t divertMode) {
173+ if (overflow) return ;
174+ ArduinoOcpp::OcppTimestamp timestamp = ArduinoOcpp::OcppTimestamp ();
175+ if (!timestamp.setTime (time.c_str ())) {
176+ DBUG (F (" [ocpp] Diagnostics upload, cannot parse timestamp format: " ));
177+ DBUGLN (time);
178+ return ;
179+ }
148180
181+ if (timestamp < startTime || timestamp > stopTime) {
182+ return ;
183+ }
149184
150- diagClient.post (" abc" , " def" , " ghj" );
151-
185+ if (body.length () + logEntry.length () + 10 < SUFFIX_RESERVED_AREA) {
186+ if (firstEntry)
187+ firstEntry = false ;
188+ else
189+ body += " ," ;
190+
191+ body += logEntry;
192+ body += " \n " ;
193+ } else {
194+ overflow = true ;
195+ return ;
196+ }
197+ });
198+
199+ }
200+
201+ if (overflow) {
202+ if (!firstEntry)
203+ body += " ,\r\n " ;
204+ body += overflowMsg;
205+ }
206+
207+ body += " ]" ;
208+
209+ body += bodySuffix;
210+
211+ DBUG (F (" [ocpp] POST diagnostics file to " ));
212+ DBUGLN (location);
213+
214+ MongooseHttpClientRequest *request =
215+ diagClient.beginRequest (location.c_str ());
216+ request->setMethod (HTTP_POST);
217+ request->addHeader (" Content-Type" , " multipart/form-data; boundary=" BOUNDARY_STRING);
218+ request->setContent (body.c_str ());
219+ request->onResponse ([this ] (MongooseHttpClientResponse *response) {
220+ if (response->respCode () == 200 ) {
221+ diagSuccess = true ;
222+ } else {
223+ diagFailure = true ;
224+ }
225+ });
226+ request->onClose ([this ] (MongooseHttpClientResponse *response) {
227+ if (!diagSuccess) {
228+ // triggered onClose before onResponse
229+ diagFailure = true ;
230+ }
231+ });
232+ diagClient.send (request);
152233
153234 return true ;
154235 });
0 commit comments