Skip to content

Commit 4794bcd

Browse files
committed
[SD] Refactor all parsing
1 parent a81fa03 commit 4794bcd

File tree

3 files changed

+144
-166
lines changed

3 files changed

+144
-166
lines changed

src/Wippersnapper_demo_wokwi.ino.cpp

Lines changed: 0 additions & 37 deletions
This file was deleted.

src/provisioning/sdcard/ws_sdcard.cpp

Lines changed: 130 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,98 @@ void ws_sdcard::CheckIn(uint8_t max_digital_pins, uint8_t max_analog_pins,
157157
WsV2.analogio_controller->SetRefVoltage(ref_voltage);
158158
}
159159

160+
bool ws_sdcard::ParseDigitalIOAdd(
161+
wippersnapper_digitalio_DigitalIOAdd &msg_DigitalIOAdd, const char *pin,
162+
float period, bool value, const char *sample_mode, const char *direction,
163+
const char *pull) {
164+
bool rc = true;
165+
strcpy(msg_DigitalIOAdd.pin_name, pin);
166+
msg_DigitalIOAdd.period = period;
167+
msg_DigitalIOAdd.value = value;
168+
// Determine the sample mode
169+
if (strcmp(sample_mode, "TIMER") == 0) {
170+
msg_DigitalIOAdd.sample_mode =
171+
wippersnapper_digitalio_DigitalIOSampleMode_DIGITAL_IO_SAMPLE_MODE_TIMER;
172+
} else if (strcmp(sample_mode, "EVENT") == 0) {
173+
msg_DigitalIOAdd.sample_mode =
174+
wippersnapper_digitalio_DigitalIOSampleMode_DIGITAL_IO_SAMPLE_MODE_EVENT;
175+
} else {
176+
WS_DEBUG_PRINTLN("[SD] Parsing Error: Unknown sample mode found: " +
177+
String(sample_mode));
178+
}
179+
180+
// Determine the pin direction and pull
181+
if (strcmp(direction, "INPUT") == 0) {
182+
if (pull != nullptr) {
183+
msg_DigitalIOAdd.gpio_direction =
184+
wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_INPUT_PULL_UP;
185+
} else {
186+
msg_DigitalIOAdd.gpio_direction =
187+
wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_INPUT;
188+
}
189+
} else if (strcmp(direction, "OUTPUT") == 0) {
190+
WS_DEBUG_PRINTLN(
191+
"[SD] Error - Can not set OUTPUT direction in offline mode!");
192+
rc = false;
193+
} else {
194+
WS_DEBUG_PRINTLN("[SD] Parsing Error: Unknown direction found: " +
195+
String(direction));
196+
rc = false;
197+
}
198+
return rc;
199+
}
200+
201+
wippersnapper_sensor_SensorType
202+
ws_sdcard::ParseSensorType(const char *sensor_type) {
203+
if (strcmp(sensor_type, "PIN_VALUE") == 0) {
204+
return wippersnapper_sensor_SensorType_SENSOR_TYPE_RAW;
205+
} else if (strcmp(sensor_type, "VOLTAGE") == 0) {
206+
return wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE;
207+
} else if (strcmp(sensor_type, "ambient-temp-fahrenheit") == 0) {
208+
return wippersnapper_sensor_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE_FAHRENHEIT;
209+
} else if (strcmp(sensor_type, "ambient-temp") == 0) {
210+
return wippersnapper_sensor_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE;
211+
} else {
212+
return wippersnapper_sensor_SensorType_SENSOR_TYPE_UNSPECIFIED;
213+
}
214+
}
215+
216+
bool ws_sdcard::ParseAnalogIOAdd(
217+
wippersnapper_analogio_AnalogIOAdd &msg_AnalogIOAdd, const char *pin,
218+
float period, const char *mode) {
219+
strcpy(msg_AnalogIOAdd.pin_name, pin);
220+
msg_AnalogIOAdd.period = period;
221+
msg_AnalogIOAdd.read_mode = ParseSensorType(mode);
222+
if (msg_AnalogIOAdd.read_mode ==
223+
wippersnapper_sensor_SensorType_SENSOR_TYPE_UNSPECIFIED) {
224+
WS_DEBUG_PRINTLN("[SD] Parsing Error: Unknown read mode found: " +
225+
String(mode));
226+
return false;
227+
}
228+
return true;
229+
}
230+
231+
bool ws_sdcard::ParseDS18X20Add(
232+
wippersnapper_ds18x20_Ds18x20Add &msg_DS18X20Add, const char *pin,
233+
int resolution, float period, int num_sensors, const char *sensor_type_1,
234+
char *sensor_type_2) {
235+
strcpy(msg_DS18X20Add.onewire_pin, pin);
236+
msg_DS18X20Add.sensor_resolution = resolution;
237+
msg_DS18X20Add.period = period;
238+
msg_DS18X20Add.sensor_types_count = num_sensors;
239+
240+
WS_DEBUG_PRINT("[SD] msg_DS18X20Add.sensor_types_count: ");
241+
WS_DEBUG_PRINTLN(msg_DS18X20Add.sensor_types_count);
242+
243+
// Parse the first sensor type
244+
msg_DS18X20Add.sensor_types[0] = ParseSensorType(sensor_type_1);
245+
// Parse the second sensor type, if it exists
246+
if (num_sensors == 2) {
247+
msg_DS18X20Add.sensor_types[1] = ParseSensorType(sensor_type_2);
248+
}
249+
return true;
250+
}
251+
160252
/**************************************************************************/
161253
/*!
162254
@brief Searches for and parses the JSON configuration file and sets up
@@ -178,8 +270,7 @@ bool ws_sdcard::parseConfigFile() {
178270
if (_use_test_data == true) {
179271
WS_DEBUG_PRINTLN("[SD] Using SERIAL INPUT for JSON config...");
180272
error = deserializeJson(doc, _serialInput.c_str(), max_json_len);
181-
}
182-
else {
273+
} else {
183274
WS_DEBUG_PRINTLN("[SD] Using TEST DATA for JSON config...");
184275
error = deserializeJson(doc, json_test_data, max_json_len);
185276
}
@@ -199,6 +290,13 @@ bool ws_sdcard::parseConfigFile() {
199290
return false;
200291
}
201292

293+
// NOTE: This is only used by the CI runner, production builds do not run
294+
// this!
295+
const char *exportedBy = doc["exportedBy"];
296+
if (strcmp(exportedBy, "wokwi") == 0) {
297+
_wokwi_runner = true;
298+
}
299+
202300
// Parse the exportedFromDevice array
203301
JsonObject exportedFromDevice = doc["exportedFromDevice"];
204302
if (exportedFromDevice.isNull()) {
@@ -226,14 +324,19 @@ bool ws_sdcard::parseConfigFile() {
226324

227325
// Parse the "components" array into a JsonObject
228326
JsonArray components_ar = doc["components"].as<JsonArray>();
327+
if (components_ar.isNull()) {
328+
WS_DEBUG_PRINTLN("[SD] FATAL Parsing error - No components array found in "
329+
"JSON string!");
330+
return false;
331+
}
229332
int count = components_ar.size();
230333
WS_DEBUG_PRINTLN("[SD] Found " + String(count) + " components in JSON file!");
231334

232-
// Use the iterator feature of ArduinoJSON v7 to quickly iterate over
233-
// components[]
335+
// Parse each component from JSON->PB and push into a shared buffer
234336
for (JsonObject component : doc["components"].as<JsonArray>()) {
235-
// Create a new signal message
236-
wippersnapper_signal_BrokerToDevice msg_signal_b2d;
337+
wippersnapper_signal_BrokerToDevice msg_signal_b2d =
338+
wippersnapper_signal_BrokerToDevice_init_default;
339+
237340
// Parse the component API type
238341
const char *component_api_type = component["componentAPI"];
239342
if (component_api_type == nullptr) {
@@ -242,76 +345,40 @@ bool ws_sdcard::parseConfigFile() {
242345
return false;
243346
}
244347

245-
// This is enabled for wokwi-cli testing only
246-
const char *exportedBy = doc["exportedBy"];
247-
if (strcmp(exportedBy, "wokwi") == 0) {
248-
_wokwi_runner = true;
249-
}
250-
251348
// Determine the component type and parse it into a PB message
252349
if (strcmp(component_api_type, "digitalio") == 0) {
253350
WS_DEBUG_PRINTLN(
254351
"[SD] DigitalIO component found, decoding JSON to PB...");
255-
// Parse the JSON component's fields into a new DigitalIOAdd message
352+
353+
// Parse: JSON->DigitalIOAdd
256354
wippersnapper_digitalio_DigitalIOAdd msg_DigitalIOAdd =
257355
wippersnapper_digitalio_DigitalIOAdd_init_default;
258-
strcpy(msg_DigitalIOAdd.pin_name, component["pinName"]);
259-
msg_DigitalIOAdd.period = component["period"];
260-
msg_DigitalIOAdd.value = component["value"];
261-
// Determine the sample mode
262-
if (strcmp(component["sampleMode"], "TIMER") == 0) {
263-
msg_DigitalIOAdd.sample_mode =
264-
wippersnapper_digitalio_DigitalIOSampleMode_DIGITAL_IO_SAMPLE_MODE_TIMER;
265-
} else if (strcmp(component["sampleMode"], "EVENT") == 0) {
266-
msg_DigitalIOAdd.sample_mode =
267-
wippersnapper_digitalio_DigitalIOSampleMode_DIGITAL_IO_SAMPLE_MODE_EVENT;
268-
} else {
269-
WS_DEBUG_PRINTLN("[SD] Parsing Error: Unknown sample mode found: " +
270-
String(component["sampleMode"]));
271-
}
272-
// Determine the pin direction and pull
273-
if (strcmp(component["direction"], "INPUT") == 0) {
274-
if (component["pull"] != nullptr) {
275-
msg_DigitalIOAdd.gpio_direction =
276-
wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_INPUT_PULL_UP;
277-
} else {
278-
msg_DigitalIOAdd.gpio_direction =
279-
wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_INPUT;
280-
}
281-
} else if (strcmp(component["direction"], "OUTPUT") == 0) {
356+
if (!ParseDigitalIOAdd(msg_DigitalIOAdd, component["pinName"],
357+
component["period"], component["value"],
358+
component["sampleMode"], component["direction"],
359+
component["pull"])) {
282360
WS_DEBUG_PRINTLN(
283-
"[SD] Error - Can not set OUTPUT direction in offline mode!");
284-
return false;
285-
} else {
286-
WS_DEBUG_PRINTLN("[SD] Parsing Error: Unknown direction found: " +
287-
String(component["direction"]));
361+
"[SD] FATAL Parsing error - Unable to parse DigitalIO component!");
288362
return false;
289363
}
290364

291-
msg_signal_b2d = wippersnapper_signal_BrokerToDevice_init_zero;
365+
// Configure the signal message for the digitalio payload
292366
msg_signal_b2d.which_payload =
293367
wippersnapper_signal_BrokerToDevice_digitalio_add_tag;
294368
msg_signal_b2d.payload.digitalio_add = msg_DigitalIOAdd;
295369
} else if (strcmp(component_api_type, "analogio") == 0) {
296370
WS_DEBUG_PRINTLN("[SD] AnalogIO component found, decoding JSON to PB...");
297371
wippersnapper_analogio_AnalogIOAdd msg_AnalogIOAdd =
298372
wippersnapper_analogio_AnalogIOAdd_init_default;
299-
strcpy(msg_AnalogIOAdd.pin_name, component["pinName"]);
300-
msg_AnalogIOAdd.period = component["period"];
301-
if (strcmp(component["analogReadMode"], "PIN_VALUE") == 0) {
302-
msg_AnalogIOAdd.read_mode =
303-
wippersnapper_sensor_SensorType_SENSOR_TYPE_RAW;
304-
} else if (strcmp(component["analogReadMode"], "VOLTAGE") == 0) {
305-
msg_AnalogIOAdd.read_mode =
306-
wippersnapper_sensor_SensorType_SENSOR_TYPE_VOLTAGE;
307-
} else {
308-
// Unknown analog read mode, bail out
309-
WS_DEBUG_PRINTLN("[SD] Unknown analog read mode found: " +
310-
String(component["analogReadMode"]));
373+
374+
// Parse: JSON->AnalogIOAdd
375+
if (!ParseAnalogIOAdd(msg_AnalogIOAdd, component["pinName"],
376+
component["period"], component["analogReadMode"])) {
377+
WS_DEBUG_PRINTLN(
378+
"[SD] FATAL Parsing error - Unable to parse AnalogIO component!");
311379
return false;
312380
}
313381

314-
msg_signal_b2d = wippersnapper_signal_BrokerToDevice_init_zero;
315382
msg_signal_b2d.which_payload =
316383
wippersnapper_signal_BrokerToDevice_analogio_add_tag;
317384
msg_signal_b2d.payload.analogio_add = msg_AnalogIOAdd;
@@ -320,82 +387,19 @@ bool ws_sdcard::parseConfigFile() {
320387
// Create new DS18X20Add message
321388
wippersnapper_ds18x20_Ds18x20Add msg_DS18X20Add =
322389
wippersnapper_ds18x20_Ds18x20Add_init_default;
323-
// Parse JSON into the DS18X20Add message
324-
// TODO: This pattern should be refactored into a function like
325-
// "ParseAndAssign(component["type"], msg_field)"
326-
if (component["pinName"] != nullptr) {
327-
strcpy(msg_DS18X20Add.onewire_pin, component["pinName"]);
328-
} else {
329-
WS_DEBUG_PRINTLN(
330-
"[SD] FATAL Parsing error - No pin name found in JSON string!");
331-
return false;
332-
}
333390

334-
if (component["sensorResolution"] != nullptr) {
335-
msg_DS18X20Add.sensor_resolution = component["sensorResolution"];
336-
} else {
337-
WS_DEBUG_PRINTLN("[SD] FATAL Parsing error - No sensor resolution "
338-
"found in JSON string!");
339-
return false;
340-
}
341-
342-
if (component["period"] != nullptr) {
343-
msg_DS18X20Add.period = component["period"];
344-
} else {
391+
// Parse: JSON->DS18X20Add
392+
if (!ParseDS18X20Add(msg_DS18X20Add, component["pinName"],
393+
component["sensorResolution"], component["period"],
394+
component["sensorTypeCount"],
395+
component["sensorType1"],
396+
component["sensorType2"])) {
345397
WS_DEBUG_PRINTLN(
346-
"[SD] FATAL Parsing error - No period found in JSON string!");
398+
"[SD] FATAL Parsing error - Unable to parse DS18X20 component!");
347399
return false;
348400
}
349401

350-
if (component["sensorTypeCount"] != nullptr) {
351-
msg_DS18X20Add.sensor_types_count = component["sensorTypeCount"];
352-
} else {
353-
WS_DEBUG_PRINTLN("[SD] FATAL Parsing error - No sensor type count "
354-
"found in JSON string!");
355-
return false;
356-
}
357-
358-
WS_DEBUG_PRINT("[SD] msg_DS18X20Add.sensor_types_count: ");
359-
WS_DEBUG_PRINTLN(msg_DS18X20Add.sensor_types_count);
360-
361-
// Parse the sensor types into the DS18X20Add message
362-
// TODO: This structor needs a refactoring pass! It's too confusing
363-
if (msg_DS18X20Add.sensor_types_count == 1 ||
364-
msg_DS18X20Add.sensor_types_count == 2) {
365-
if (strcmp(component["sensorType1"], "ambient-temp-fahrenheit") == 0) {
366-
msg_DS18X20Add.sensor_types[0] =
367-
wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT;
368-
} else if (strcmp(component["sensorType1"], "ambient-temp") == 0) {
369-
msg_DS18X20Add.sensor_types[0] =
370-
wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE;
371-
} else {
372-
WS_DEBUG_PRINTLN(
373-
"[SD] FATAL Parsing error - Unsupported ds18x sensor "
374-
"type found in JSON!");
375-
return false;
376-
}
377-
}
378-
if (msg_DS18X20Add.sensor_types_count == 2) {
379-
WS_DEBUG_PRINTLN("[SD] Parsing sensor type 2...");
380-
if (component["sensorType2"] != nullptr) {
381-
if (strcmp(component["sensorType2"], "ambient-temp-fahrenheit") ==
382-
0) {
383-
msg_DS18X20Add.sensor_types[1] =
384-
wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT;
385-
} else if (strcmp(component["sensorType2"], "ambient-temp") == 0) {
386-
msg_DS18X20Add.sensor_types[1] =
387-
wippersnapper_sensor_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE;
388-
} else {
389-
WS_DEBUG_PRINTLN(
390-
"[SD] FATAL Parsing error - Unsupported ds18x sensor "
391-
"type found in JSON!");
392-
return false;
393-
}
394-
}
395-
}
396-
397402
// Configure the signal message for the ds18x20 payload
398-
msg_signal_b2d = wippersnapper_signal_BrokerToDevice_init_zero;
399403
msg_signal_b2d.which_payload =
400404
wippersnapper_signal_BrokerToDevice_ds18x20_add_tag;
401405
msg_signal_b2d.payload.ds18x20_add = msg_DS18X20Add;

src/provisioning/sdcard/ws_sdcard.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,24 @@ class ws_sdcard {
3535
~ws_sdcard();
3636
bool InitSDCard();
3737
bool ConfigureRTC(const char *rtc_type);
38-
bool parseConfigFile();
3938
bool waitForSerialConfig();
4039
bool validateJson(const char *input);
4140
bool mode_offline; // TODO: Refactor to getter/setter
4241
uint32_t GetTimestamp();
43-
// Encoders for SD card logging
44-
// GPIO (Analog and Digital Pin) Events
42+
43+
bool parseConfigFile();
44+
wippersnapper_sensor_SensorType ParseSensorType(const char *sensor_type);
45+
bool ParseDigitalIOAdd(wippersnapper_digitalio_DigitalIOAdd &msg_DigitalIOAdd,
46+
const char *pin, float period, bool value,
47+
const char *sample_mode, const char *direction,
48+
const char *pull);
49+
bool ParseAnalogIOAdd(wippersnapper_analogio_AnalogIOAdd &msg_AnalogIOAdd,
50+
const char *pin, float period, const char *mode);
51+
bool ParseDS18X20Add(wippersnapper_ds18x20_Ds18x20Add &msg_DS18X20Add,
52+
const char *pin, int resolution, float period,
53+
int num_sensors, char *sensor_type_1,
54+
char *sensor_type_2);
55+
4556
bool LogGPIOSensorEventToSD(uint8_t pin, float value,
4657
wippersnapper_sensor_SensorType read_type);
4758
bool LogGPIOSensorEventToSD(uint8_t pin, bool value,

0 commit comments

Comments
 (0)