21
21
/* *************************************************************************/
22
22
ws_sdcard::ws_sdcard () {
23
23
is_mode_offline = false ;
24
+ #ifdef OFFLINE_MODE_WOKWI
25
+ _is_using_wokwi = true ;
26
+ #else
24
27
_is_using_wokwi = false ;
28
+ #endif
25
29
_use_test_data = false ;
26
30
_sz_log_file = 0 ;
27
31
}
@@ -167,6 +171,41 @@ void ws_sdcard::CheckIn(uint8_t max_digital_pins, uint8_t max_analog_pins,
167
171
WsV2.analogio_controller ->SetRefVoltage (ref_voltage);
168
172
}
169
173
174
+ /* *************************************************************************/
175
+ /* !
176
+ @brief Parses a sensor type from the JSON configuration file.
177
+ @param sensor_type
178
+ The sensor type to parse.
179
+ @returns The parsed sensor type.
180
+ */
181
+ /* *************************************************************************/
182
+ wippersnapper_sensor_SensorType
183
+ ws_sdcard::ParseSensorType (const char *sensor_type) {
184
+ if (strcmp (sensor_type, " PIN_VALUE" ) == 0 ) {
185
+ return wippersnapper_sensor_SensorType_SENSOR_TYPE_RAW;
186
+ } else if (strcmp (sensor_type, " VOLTAGE" ) == 0 ) {
187
+ return wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE;
188
+ } else if (strcmp (sensor_type, " object-temp-fahrenheit" ) == 0 ) {
189
+ WS_DEBUG_PRINTLN (" Found object-temp-fahrenheit" );
190
+ return wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT;
191
+ } else if (strcmp (sensor_type, " object-temp" ) == 0 ) {
192
+ WS_DEBUG_PRINTLN (" Found object-temp" );
193
+ return wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE;
194
+ } else {
195
+ WS_DEBUG_PRINT (" Found unspecified sensortype - " );
196
+ WS_DEBUG_PRINTLN (sensor_type);
197
+ return wippersnapper_sensor_SensorType_SENSOR_TYPE_UNSPECIFIED;
198
+ }
199
+ }
200
+
201
+ bool ws_sdcard::ValidateJSONKey (const char *key, const char *error_msg) {
202
+ if (strcmp (key, UNKNOWN_VALUE) == 0 ) {
203
+ WS_DEBUG_PRINTLN (error_msg);
204
+ return false ;
205
+ }
206
+ return true ;
207
+ }
208
+
170
209
/* *************************************************************************/
171
210
/* !
172
211
@brief Parses a DigitalIOAdd message from the JSON configuration file.
@@ -193,10 +232,8 @@ bool ws_sdcard::ParseDigitalIOAdd(
193
232
float period, bool value, const char *sample_mode, const char *direction,
194
233
const char *pull) {
195
234
bool rc = true ;
196
- if (!strcmp (pin, UNKNOWN_VALUE) == 0 ) {
197
- WS_DEBUG_PRINTLN (" [SD] Parsing Error: Digital pin name not found!" );
235
+ if (!ValidateJSONKey (pin, " [SD] Parsing Error: Digital pin name not found!" ))
198
236
return false ;
199
- }
200
237
strcpy (msg_DigitalIOAdd.pin_name , pin);
201
238
202
239
if (period == 0.0 ) {
@@ -207,9 +244,9 @@ bool ws_sdcard::ParseDigitalIOAdd(
207
244
msg_DigitalIOAdd.value = value;
208
245
209
246
// Determine the sample mode
210
- if (strcmp (sample_mode, UNKNOWN_VALUE) == 0 ) {
211
- WS_DEBUG_PRINTLN (
212
- " [SD] Parsing Error: Digital pin's sample mode not found!" );
247
+ if (! ValidateJSONKey (
248
+ sample_mode,
249
+ " [SD] Parsing Error: Digital pin's sample mode not found!" )) {
213
250
return false ;
214
251
} else if (strcmp (sample_mode, " TIMER" ) == 0 ) {
215
252
msg_DigitalIOAdd.sample_mode =
@@ -223,8 +260,9 @@ bool ws_sdcard::ParseDigitalIOAdd(
223
260
}
224
261
225
262
// Determine the pin direction and pull
226
- if (strcmp (direction, UNKNOWN_VALUE) == 0 ) {
227
- WS_DEBUG_PRINTLN (" [SD] Parsing Error: Digital pin's direction not found!" );
263
+ if (!ValidateJSONKey (
264
+ direction,
265
+ " [SD] Parsing Error: Digital pin's direction not found!" )) {
228
266
return false ;
229
267
} else if (strcmp (direction, " INPUT" ) == 0 ) {
230
268
if (pull != nullptr ) {
@@ -246,33 +284,6 @@ bool ws_sdcard::ParseDigitalIOAdd(
246
284
return rc;
247
285
}
248
286
249
- /* *************************************************************************/
250
- /* !
251
- @brief Parses a sensor type from the JSON configuration file.
252
- @param sensor_type
253
- The sensor type to parse.
254
- @returns The parsed sensor type.
255
- */
256
- /* *************************************************************************/
257
- wippersnapper_sensor_SensorType
258
- ws_sdcard::ParseSensorType (const char *sensor_type) {
259
- if (strcmp (sensor_type, " PIN_VALUE" ) == 0 ) {
260
- return wippersnapper_sensor_SensorType_SENSOR_TYPE_RAW;
261
- } else if (strcmp (sensor_type, " VOLTAGE" ) == 0 ) {
262
- return wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE;
263
- } else if (strcmp (sensor_type, " object-temp-fahrenheit" ) == 0 ) {
264
- WS_DEBUG_PRINTLN (" Found object-temp-fahrenheit" );
265
- return wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT;
266
- } else if (strcmp (sensor_type, " object-temp" ) == 0 ) {
267
- WS_DEBUG_PRINTLN (" Found object-temp" );
268
- return wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE;
269
- } else {
270
- WS_DEBUG_PRINT (" Found unspecified sensortype - " );
271
- WS_DEBUG_PRINTLN (sensor_type);
272
- return wippersnapper_sensor_SensorType_SENSOR_TYPE_UNSPECIFIED;
273
- }
274
- }
275
-
276
287
/* *************************************************************************/
277
288
/* !
278
289
@brief Parses an AnalogIOAdd message from the JSON configuration file.
@@ -291,8 +302,21 @@ ws_sdcard::ParseSensorType(const char *sensor_type) {
291
302
bool ws_sdcard::ParseAnalogIOAdd (
292
303
wippersnapper_analogio_AnalogIOAdd &msg_AnalogIOAdd, const char *pin,
293
304
float period, const char *mode) {
305
+
306
+ if (!ValidateJSONKey (pin, " [SD] Parsing Error: Analog pin name not found!" ))
307
+ return false ;
294
308
strcpy (msg_AnalogIOAdd.pin_name , pin);
309
+
310
+ if (period == 0.0 ) {
311
+ WS_DEBUG_PRINTLN (" [SD] Parsing Error: Analog pin period less than 1.0 "
312
+ " seconds or not found!" );
313
+ return false ;
314
+ }
295
315
msg_AnalogIOAdd.period = period;
316
+
317
+ if (!ValidateJSONKey (mode,
318
+ " [SD] Parsing Error: Analog pin read mode not found!" ))
319
+ return false ;
296
320
msg_AnalogIOAdd.read_mode = ParseSensorType (mode);
297
321
if (msg_AnalogIOAdd.read_mode ==
298
322
wippersnapper_sensor_SensorType_SENSOR_TYPE_UNSPECIFIED) {
@@ -307,18 +331,47 @@ bool ws_sdcard::ParseDS18X20Add(
307
331
wippersnapper_ds18x20_Ds18x20Add &msg_DS18X20Add, const char *pin,
308
332
int resolution, float period, int num_sensors, const char *sensor_type_1,
309
333
const char *sensor_type_2) {
334
+
335
+ if (strcmp (pin, UNKNOWN_VALUE) == 0 ) {
336
+ WS_DEBUG_PRINTLN (" [SD] Parsing Error: DS18X20 pin name not found!" );
337
+ return false ;
338
+ }
310
339
strcpy (msg_DS18X20Add.onewire_pin , pin);
340
+
341
+ if (resolution == 0 ) {
342
+ WS_DEBUG_PRINTLN (
343
+ " [SD] Parsing Error: DS18X20 sensor resolution not found!" );
344
+ return false ;
345
+ }
311
346
msg_DS18X20Add.sensor_resolution = resolution;
347
+
348
+ if (period == 0.0 ) {
349
+ WS_DEBUG_PRINTLN (" [SD] Parsing Error: DS18X20 sensor period not found!" );
350
+ return false ;
351
+ }
312
352
msg_DS18X20Add.period = period;
353
+
354
+ if (num_sensors == 0 ) {
355
+ WS_DEBUG_PRINTLN (" [SD] Parsing Error: DS18X20 sensor count not found!" );
356
+ return false ;
357
+ }
313
358
msg_DS18X20Add.sensor_types_count = num_sensors;
314
359
315
360
WS_DEBUG_PRINT (" [SD] msg_DS18X20Add.sensor_types_count: " );
316
361
WS_DEBUG_PRINTLN (msg_DS18X20Add.sensor_types_count );
317
362
318
363
// Parse the first sensor type
364
+ if (strcmp (sensor_type_1, UNKNOWN_VALUE) == 0 ) {
365
+ WS_DEBUG_PRINTLN (" [SD] Parsing Error: DS18X20 sensor type 1 not found!" );
366
+ return false ;
367
+ }
319
368
msg_DS18X20Add.sensor_types [0 ] = ParseSensorType (sensor_type_1);
320
369
// Parse the second sensor type, if it exists
321
370
if (num_sensors == 2 ) {
371
+ if (strcmp (sensor_type_2, UNKNOWN_VALUE) == 0 ) {
372
+ WS_DEBUG_PRINTLN (" [SD] Parsing Error: DS18X20 sensor type 2 not found!" );
373
+ return false ;
374
+ }
322
375
msg_DS18X20Add.sensor_types [1 ] = ParseSensorType (sensor_type_2);
323
376
}
324
377
return true ;
@@ -414,8 +467,9 @@ bool ws_sdcard::parseConfigFile() {
414
467
error = deserializeJson (doc, file_config);
415
468
#else
416
469
// Test Mode - do not use the SD card, use test data instead!
417
- if (_use_test_data == true ) {
470
+ if (! _use_test_data) {
418
471
WS_DEBUG_PRINTLN (" [SD] Parsing Serial Input..." );
472
+ WS_DEBUG_PRINT (_serialInput);
419
473
error = deserializeJson (doc, _serialInput.c_str (), max_json_len);
420
474
} else {
421
475
WS_DEBUG_PRINTLN (" [SD] Parsing Test Data..." );
@@ -432,6 +486,8 @@ bool ws_sdcard::parseConfigFile() {
432
486
return false ;
433
487
}
434
488
489
+ WS_DEBUG_PRINTLN (" [SD] Successfully deserialized JSON config file!" );
490
+
435
491
// NOTE: This is only used by the CI runner, production builds do not run
436
492
// this!
437
493
const char *exportedBy = doc[" exportedBy" ];
@@ -448,25 +504,28 @@ bool ws_sdcard::parseConfigFile() {
448
504
}
449
505
450
506
// Mock the check-in process using the JSON's values
507
+ WS_DEBUG_PRINTLN (" [SD] Mocking check-in process..." );
451
508
CheckIn (exportedFromDevice[" totalGPIOPins" ] | 0 ,
452
509
exportedFromDevice[" totalAnalogPins" ] | 0 ,
453
510
exportedFromDevice[" referenceVoltage" ] | 0.0 );
454
511
512
+ WS_DEBUG_PRINTLN (" [SD] Configuring status LED..." );
455
513
setStatusLEDBrightness (exportedFromDevice[" statusLEDBrightness" ] | 0.3 );
456
514
457
- // Initialize and configure RTC
515
+ // Initialize and configure RTC
516
+ #ifndef OFFLINE_MODE_WOKWI
517
+ WS_DEBUG_PRINTLN (" [SD] Configuring RTC..." );
458
518
const char *json_rtc = exportedFromDevice[" rtc" ] | " SOFT_RTC" ;
459
- if (json_rtc == nullptr ) {
460
- WS_DEBUG_PRINTLN (" [SD] FATAL Parsing error - rtc field not found in "
461
- " configuration JSON, unable to configure RTC!" );
462
- return false ;
463
- }
464
519
if (!ConfigureRTC (json_rtc)) {
465
520
WS_DEBUG_PRINTLN (" [SD] Failed to to configure RTC!" );
466
521
return false ;
467
522
}
523
+ #else
524
+ WS_DEBUG_PRINTLN (" [SD] Skipping RTC configuration for Wokwi Simulator..." );
525
+ #endif
468
526
469
527
// Parse the "components" array into a JsonObject
528
+ WS_DEBUG_PRINTLN (" [SD] Parsing out components array..." );
470
529
JsonArray components_ar = doc[" components" ].as <JsonArray>();
471
530
if (components_ar.isNull ()) {
472
531
WS_DEBUG_PRINTLN (" [SD] FATAL Parsing error - No components array found in "
@@ -512,8 +571,10 @@ bool ws_sdcard::parseConfigFile() {
512
571
wippersnapper_analogio_AnalogIOAdd msg_AnalogIOAdd =
513
572
wippersnapper_analogio_AnalogIOAdd_init_default;
514
573
// Parse: JSON->AnalogIOAdd
515
- if (!ParseAnalogIOAdd (msg_AnalogIOAdd, component[" pinName" ],
516
- component[" period" ], component[" analogReadMode" ])) {
574
+ if (!ParseAnalogIOAdd (msg_AnalogIOAdd,
575
+ component[" pinName" ] | UNKNOWN_VALUE,
576
+ component[" period" ] | 0.0 ,
577
+ component[" analogReadMode" ] | UNKNOWN_VALUE)) {
517
578
WS_DEBUG_PRINTLN (
518
579
" [SD] FATAL Parsing error - Unable to parse AnalogIO component!" );
519
580
return false ;
@@ -526,11 +587,12 @@ bool ws_sdcard::parseConfigFile() {
526
587
wippersnapper_ds18x20_Ds18x20Add msg_DS18X20Add =
527
588
wippersnapper_ds18x20_Ds18x20Add_init_default;
528
589
// Parse: JSON->DS18X20Add
529
- if (!ParseDS18X20Add (msg_DS18X20Add, component[" pinName" ],
530
- component[" sensorResolution" ], component[" period" ],
531
- component[" sensorTypeCount" ],
532
- component[" sensorType1" ],
533
- component[" sensorType2" ])) {
590
+ if (!ParseDS18X20Add (msg_DS18X20Add, component[" pinName" ] | UNKNOWN_VALUE,
591
+ component[" sensorResolution" ] | 0 ,
592
+ component[" period" ] | 0.0 ,
593
+ component[" sensorTypeCount" ] | 0 ,
594
+ component[" sensorType1" ] | UNKNOWN_VALUE,
595
+ component[" sensorType2" ] | UNKNOWN_VALUE)) {
534
596
WS_DEBUG_PRINTLN (
535
597
" [SD] FATAL Parsing error - Unable to parse DS18X20 component!" );
536
598
return false ;
@@ -569,12 +631,11 @@ uint32_t ws_sdcard::GetTimestamp() {
569
631
now = _rtc_ds1307->now ();
570
632
else if (_rtc_pcf8523 != nullptr )
571
633
now = _rtc_pcf8523->now ();
572
- else {
634
+ else if (_rtc_soft != nullptr ) {
573
635
now = _rtc_soft->now ();
574
- }
575
-
576
- if (_is_using_wokwi)
636
+ } else { // we're either using a simulator or have undefined behavior
577
637
return 0 ;
638
+ }
578
639
579
640
return now.unixtime ();
580
641
}
@@ -683,6 +744,7 @@ void ws_sdcard::BuildJSONDoc(JsonDocument &doc, uint8_t pin, uint16_t value,
683
744
char pin_name[12 ];
684
745
sprintf (pin_name, " A%d" , pin);
685
746
doc[" timestamp" ] = GetTimestamp ();
747
+ ;
686
748
doc[" pin" ] = pin_name;
687
749
doc[" value" ] = value;
688
750
doc[" si_unit" ] = SensorTypeToString (read_type);
@@ -847,7 +909,13 @@ bool ws_sdcard::waitForSerialConfig() {
847
909
// 2. Provide a JSON string via the hardware's serial input
848
910
// 3. Use a test JSON string - for debugging purposes ONLY
849
911
850
- _use_test_data = true ;
912
+ // TODO: Redundant conditional - should this just be enabled within the class
913
+ // ctor?
914
+ if (_is_using_wokwi)
915
+ _use_test_data = false ;
916
+ else
917
+ _use_test_data = true ;
918
+
851
919
json_test_data = " {"
852
920
" \" exportVersion\" : \" 1.0.0\" ,"
853
921
" \" exportedBy\" : \" tester\" ,"
@@ -900,8 +968,8 @@ bool ws_sdcard::waitForSerialConfig() {
900
968
" \" componentAPI\" : \" ds18x20\" ,"
901
969
" \" name\" : \" DS18B20: Temperature Sensor (°F)\" ,"
902
970
" \" sensorTypeCount\" : 2,"
903
- " \" sensorType1\" : \" ambient -temp-fahrenheit\" ,"
904
- " \" sensorType2\" : \" ambient -temp\" ,"
971
+ " \" sensorType1\" : \" object -temp-fahrenheit\" ,"
972
+ " \" sensorType2\" : \" object -temp\" ,"
905
973
" \" pinName\" : \" D12\" ,"
906
974
" \" sensorResolution\" : 12,"
907
975
" \" period\" : 5"
@@ -910,8 +978,8 @@ bool ws_sdcard::waitForSerialConfig() {
910
978
" \" componentAPI\" : \" ds18x20\" ,"
911
979
" \" name\" : \" DS18B20: Temperature Sensor (°F)\" ,"
912
980
" \" sensorTypeCount\" : 2,"
913
- " \" sensorType1\" : \" ambient -temp-fahrenheit\" ,"
914
- " \" sensorType2\" : \" ambient -temp\" ,"
981
+ " \" sensorType1\" : \" object -temp-fahrenheit\" ,"
982
+ " \" sensorType2\" : \" object -temp\" ,"
915
983
" \" pinName\" : \" D25\" ,"
916
984
" \" sensorResolution\" : 12,"
917
985
" \" period\" : 5"
0 commit comments