@@ -157,6 +157,98 @@ void ws_sdcard::CheckIn(uint8_t max_digital_pins, uint8_t max_analog_pins,
157
157
WsV2.analogio_controller ->SetRefVoltage (ref_voltage);
158
158
}
159
159
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
+
160
252
/* *************************************************************************/
161
253
/* !
162
254
@brief Searches for and parses the JSON configuration file and sets up
@@ -178,8 +270,7 @@ bool ws_sdcard::parseConfigFile() {
178
270
if (_use_test_data == true ) {
179
271
WS_DEBUG_PRINTLN (" [SD] Using SERIAL INPUT for JSON config..." );
180
272
error = deserializeJson (doc, _serialInput.c_str (), max_json_len);
181
- }
182
- else {
273
+ } else {
183
274
WS_DEBUG_PRINTLN (" [SD] Using TEST DATA for JSON config..." );
184
275
error = deserializeJson (doc, json_test_data, max_json_len);
185
276
}
@@ -199,6 +290,13 @@ bool ws_sdcard::parseConfigFile() {
199
290
return false ;
200
291
}
201
292
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
+
202
300
// Parse the exportedFromDevice array
203
301
JsonObject exportedFromDevice = doc[" exportedFromDevice" ];
204
302
if (exportedFromDevice.isNull ()) {
@@ -226,14 +324,19 @@ bool ws_sdcard::parseConfigFile() {
226
324
227
325
// Parse the "components" array into a JsonObject
228
326
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
+ }
229
332
int count = components_ar.size ();
230
333
WS_DEBUG_PRINTLN (" [SD] Found " + String (count) + " components in JSON file!" );
231
334
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
234
336
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
+
237
340
// Parse the component API type
238
341
const char *component_api_type = component[" componentAPI" ];
239
342
if (component_api_type == nullptr ) {
@@ -242,76 +345,40 @@ bool ws_sdcard::parseConfigFile() {
242
345
return false ;
243
346
}
244
347
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
-
251
348
// Determine the component type and parse it into a PB message
252
349
if (strcmp (component_api_type, " digitalio" ) == 0 ) {
253
350
WS_DEBUG_PRINTLN (
254
351
" [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
256
354
wippersnapper_digitalio_DigitalIOAdd msg_DigitalIOAdd =
257
355
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" ])) {
282
360
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!" );
288
362
return false ;
289
363
}
290
364
291
- msg_signal_b2d = wippersnapper_signal_BrokerToDevice_init_zero;
365
+ // Configure the signal message for the digitalio payload
292
366
msg_signal_b2d.which_payload =
293
367
wippersnapper_signal_BrokerToDevice_digitalio_add_tag;
294
368
msg_signal_b2d.payload .digitalio_add = msg_DigitalIOAdd;
295
369
} else if (strcmp (component_api_type, " analogio" ) == 0 ) {
296
370
WS_DEBUG_PRINTLN (" [SD] AnalogIO component found, decoding JSON to PB..." );
297
371
wippersnapper_analogio_AnalogIOAdd msg_AnalogIOAdd =
298
372
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!" );
311
379
return false ;
312
380
}
313
381
314
- msg_signal_b2d = wippersnapper_signal_BrokerToDevice_init_zero;
315
382
msg_signal_b2d.which_payload =
316
383
wippersnapper_signal_BrokerToDevice_analogio_add_tag;
317
384
msg_signal_b2d.payload .analogio_add = msg_AnalogIOAdd;
@@ -320,82 +387,19 @@ bool ws_sdcard::parseConfigFile() {
320
387
// Create new DS18X20Add message
321
388
wippersnapper_ds18x20_Ds18x20Add msg_DS18X20Add =
322
389
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
- }
333
390
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" ])) {
345
397
WS_DEBUG_PRINTLN (
346
- " [SD] FATAL Parsing error - No period found in JSON string !" );
398
+ " [SD] FATAL Parsing error - Unable to parse DS18X20 component !" );
347
399
return false ;
348
400
}
349
401
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
-
397
402
// Configure the signal message for the ds18x20 payload
398
- msg_signal_b2d = wippersnapper_signal_BrokerToDevice_init_zero;
399
403
msg_signal_b2d.which_payload =
400
404
wippersnapper_signal_BrokerToDevice_ds18x20_add_tag;
401
405
msg_signal_b2d.payload .ds18x20_add = msg_DS18X20Add;
0 commit comments