@@ -406,15 +406,13 @@ bool ws_sdcard::parseConfigFile() {
406406 return false ;
407407 }
408408
409- // Configure the status LED
410- float brightness = exportedFromDevice[" statusLEDBrightness" ];
411- setStatusLEDBrightness (brightness);
412-
413409 // Mock the check-in process using the JSON's values
414410 CheckIn (exportedFromDevice[" totalGPIOPins" ],
415411 exportedFromDevice[" totalAnalogPins" ],
416412 exportedFromDevice[" referenceVoltage" ]);
417413
414+ setStatusLEDBrightness (exportedFromDevice[" statusLEDBrightness" ]);
415+
418416 // Initialize and configure RTC
419417 const char *json_rtc = exportedFromDevice[" rtc" ];
420418 if (json_rtc == nullptr ) {
@@ -427,6 +425,23 @@ bool ws_sdcard::parseConfigFile() {
427425 return false ;
428426 }
429427
428+ // Create new logging file on device from the RTC's timestamp
429+ #ifndef OFFLINE_MODE_DEBUG
430+ // TODO: Refactor this out into a func
431+ // TODO: Implement a counter within the log funcs to track # of lines in the
432+ // file and implement a MAX_LINE cutoff
433+ String logFilename = " log_" + String (GetTimestamp ()) + " .json" ;
434+ _log_filename = logFilename.c_str ();
435+ File32 file;
436+ if (!file.open (_log_filename, FILE_WRITE)) {
437+ WS_DEBUG_PRINTLN (
438+ " [SD] FATAL - Failed to create initial logging file on SD card!" );
439+ return false ;
440+ }
441+ WS_DEBUG_PRINT (" [SD] Created new log file on SD card: " );
442+ WS_DEBUG_PRINTLN (_log_filename);
443+ #endif
444+
430445 // Parse the "components" array into a JsonObject
431446 JsonArray components_ar = doc[" components" ].as <JsonArray>();
432447 if (components_ar.isNull ()) {
@@ -522,7 +537,6 @@ bool ws_sdcard::parseConfigFile() {
522537*/
523538/* *************************************************************************/
524539uint32_t ws_sdcard::GetTimestamp () {
525- // Obtain RTC timestamp (TODO - refactor this out)
526540 DateTime now;
527541 if (_rtc_ds3231 != nullptr )
528542 now = _rtc_ds3231->now ();
@@ -531,7 +545,7 @@ uint32_t ws_sdcard::GetTimestamp() {
531545 else if (_rtc_pcf8523 != nullptr )
532546 now = _rtc_pcf8523->now ();
533547 else {
534- // TODO! implement software millis() version of now() and unixtime()
548+ now = _rtc_soft-> now ();
535549 }
536550
537551 if (_wokwi_runner)
@@ -629,6 +643,30 @@ const char *SensorTypeToString(wippersnapper_sensor_SensorType sensorType) {
629643 }
630644}
631645
646+ void ws_sdcard::BuildJSONDoc (JsonDocument &doc, const char *pin, float value,
647+ wippersnapper_sensor_SensorType read_type) {
648+ doc[" timestamp" ] = GetTimestamp ();
649+ doc[" pin" ] = pin;
650+ doc[" value" ] = value;
651+ doc[" si_unit" ] = SensorTypeToString (read_type);
652+ }
653+
654+ void ws_sdcard::BuildJSONDoc (JsonDocument &doc, const char *pin, uint16_t value,
655+ wippersnapper_sensor_SensorType read_type) {
656+ doc[" timestamp" ] = GetTimestamp ();
657+ doc[" pin" ] = pin;
658+ doc[" value" ] = value;
659+ doc[" si_unit" ] = SensorTypeToString (read_type);
660+ }
661+
662+ void ws_sdcard::BuildJSONDoc (JsonDocument &doc, const char *pin, bool value,
663+ wippersnapper_sensor_SensorType read_type) {
664+ doc[" timestamp" ] = GetTimestamp ();
665+ doc[" pin" ] = pin;
666+ doc[" value" ] = value;
667+ doc[" si_unit" ] = SensorTypeToString (read_type);
668+ }
669+
632670/* *************************************************************************/
633671/* !
634672 @brief Logs a GPIO sensor event to the SD card.
@@ -644,20 +682,29 @@ const char *SensorTypeToString(wippersnapper_sensor_SensorType sensorType) {
644682bool ws_sdcard::LogGPIOSensorEventToSD (
645683 uint8_t pin, float value, wippersnapper_sensor_SensorType read_type) {
646684 // Get the pin name in the correct format ("A0", "A1", etc.)
685+ // TODO: Maybe send c_pin_name to sprintf and include A/D specifier from here?
647686 char c_pin_name[12 ];
648687 sprintf (c_pin_name, " A%d" , pin);
649688
650- // Get the RTC's timestamp
651- uint32_t timestamp = GetTimestamp ();
652-
653689 // Create the JSON document
654690 JsonDocument doc;
691+ BuildJSONDoc (doc, c_pin_name, value, read_type);
655692
656- doc[" timestamp" ] = timestamp;
657- doc[" pin" ] = c_pin_name;
658- doc[" value" ] = value;
659- doc[" si_unit" ] = SensorTypeToString (read_type);
660- serializeJson (doc, Serial);
693+ // Serialize the JSON document
694+ #ifndef OFFLINE_MODE_DEBUG
695+ // TODO: Make this an attempt to open and return false on failure
696+ File32 file = _sd.open (" log.json" , FILE_WRITE);
697+ BufferingPrint bufferedFile (file, 64 ); // Add buffering to the file
698+ serializeJson (doc, file); // Serialize the JSON to the file in 64-byte chunks
699+ // TODO: I am not sure if this works, consult PDF ch 4.7
700+ bufferedFile.print (" \n " );
701+ bufferedFile.flush (); // Send the remaining bytes
702+ #else
703+ serializeJson (doc, Serial); // TODO: Add buffering here, too?
704+ Serial.print (" \n " ); // JSON requires a newline at the end of each log line
705+ #endif
706+
707+ // TODO: Does this need to be a boolean?
661708 return true ;
662709}
663710
@@ -679,17 +726,25 @@ bool ws_sdcard::LogGPIOSensorEventToSD(
679726 char c_pin_name[12 ];
680727 sprintf (c_pin_name, " A%d" , pin);
681728
682- // Get the RTC's timestamp
683- uint32_t timestamp = GetTimestamp ();
684-
685- // Append to the file in JSONL format
729+ // Create the JSON document
686730 JsonDocument doc;
687- doc[" timestamp" ] = timestamp;
688- doc[" pin" ] = c_pin_name;
689- doc[" value" ] = value;
690- doc[" si_unit" ] = SensorTypeToString (read_type);
691- serializeJson (doc, Serial);
692- Serial.println (" " ); // JSON requires a newline at the end of each log line
731+ BuildJSONDoc (doc, c_pin_name, value, read_type);
732+
733+ // Serialize the JSON document
734+ #ifndef OFFLINE_MODE_DEBUG
735+ // TODO: Make this an attempt to open and return false on failure
736+ File32 file = _sd.open (" log.json" , FILE_WRITE);
737+ BufferingPrint bufferedFile (file, 64 ); // Add buffering to the file
738+ serializeJson (doc, file); // Serialize the JSON to the file in 64-byte chunks
739+ // TODO: I am not sure if this works, consult PDF ch 4.7
740+ bufferedFile.print (" \n " );
741+ bufferedFile.flush (); // Send the remaining bytes
742+ #else
743+ serializeJson (doc, Serial); // TODO: Add buffering here, too?
744+ Serial.print (" \n " ); // JSON requires a newline at the end of each log line
745+ #endif
746+
747+ // TODO: Does this need to be a boolean?
693748 return true ;
694749}
695750
@@ -709,19 +764,30 @@ bool ws_sdcard::LogGPIOSensorEventToSD(
709764 uint8_t pin, bool value, wippersnapper_sensor_SensorType read_type) {
710765 // Get the pin name in the correct format ("A0", "A1", etc.)
711766 char c_pin_name[12 ];
712- sprintf (c_pin_name, " A%d" , pin);
713-
714- // Get the RTC's timestamp
715- uint32_t timestamp = GetTimestamp ();
767+ sprintf (c_pin_name, " D%d" , pin);
716768
717769 // Create the JSON document
718770 JsonDocument doc;
719- doc[" timestamp" ] = timestamp;
720- doc[" pin" ] = c_pin_name;
721- doc[" value" ] = value;
722- doc[" si_unit" ] = SensorTypeToString (read_type);
723- serializeJson (doc, Serial);
724- Serial.println (" " );
771+ BuildJSONDoc (doc, c_pin_name, value, read_type);
772+
773+ // Serialize the JSON document
774+ #ifndef OFFLINE_MODE_DEBUG
775+ // TODO: Make this an attempt to open and return false on failure
776+ File32 file;
777+ if (!_sd.open (" log.json" , FILE_WRITE)) {
778+ WS_DEBUG_PRINTLN (" [SD] FATAL Error - Unable to open JSON log file!" );
779+ }
780+ BufferingPrint bufferedFile (file, 64 ); // Add buffering to the file
781+ serializeJson (doc, file); // Serialize the JSON to the file in 64-byte chunks
782+ // TODO: I am not sure if this works, consult PDF ch 4.7
783+ bufferedFile.print (" \n " );
784+ bufferedFile.flush (); // Send the remaining bytes
785+ #else
786+ serializeJson (doc, Serial); // TODO: Add buffering here, too?
787+ Serial.print (" \n " ); // JSON requires a newline at the end of each log line
788+ #endif
789+
790+ // TODO: Does this need to be a boolean?
725791 return true ;
726792}
727793
0 commit comments