From b1ff2c6a8ed903229a1381eb45027ac1b2f382b9 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 22 Apr 2021 20:33:54 +0200 Subject: [PATCH] Add the sensor index to the ppO2 sample Rebreathers typically support multiple ppO2 sensors as a safety measure in case a sensor fails during the dive. The current api can already report multiple ppO2 values per sample, but it does not provide any information about which sensor the measurement is from. The new sensor index provides this info, and can also be used to distinguish between the average/voted ppO2 value using the special value DC_SENSOR_NONE. --- examples/output_xml.c | 6 +++++- include/libdivecomputer/parser.h | 6 +++++- src/diverite_nitekq_parser.c | 3 ++- src/divesoft_freedom_parser.c | 9 ++++++--- src/hw_ostc_parser.c | 3 ++- src/shearwater_predator_parser.c | 16 +++++++++------- src/tecdiving_divecomputereu_parser.c | 3 ++- 7 files changed, 31 insertions(+), 15 deletions(-) diff --git a/examples/output_xml.c b/examples/output_xml.c index 882680a..f4c312d 100644 --- a/examples/output_xml.c +++ b/examples/output_xml.c @@ -157,7 +157,11 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata) fprintf (sampledata->ostream, " %.2f\n", value.setpoint); break; case DC_SAMPLE_PPO2: - fprintf (sampledata->ostream, " %.2f\n", value.ppo2); + if (value.ppo2.sensor != DC_SENSOR_NONE) { + fprintf (sampledata->ostream, " %.2f\n", value.ppo2.sensor, value.ppo2.value); + } else { + fprintf (sampledata->ostream, " %.2f\n", value.ppo2.value); + } break; case DC_SAMPLE_CNS: fprintf (sampledata->ostream, " %.1f\n", value.cns * 100.0); diff --git a/include/libdivecomputer/parser.h b/include/libdivecomputer/parser.h index de1bbc1..c4d0a72 100644 --- a/include/libdivecomputer/parser.h +++ b/include/libdivecomputer/parser.h @@ -147,6 +147,7 @@ typedef struct dc_gasmix_t { double nitrogen; } dc_gasmix_t; +#define DC_SENSOR_NONE 0xFFFFFFFF #define DC_GASMIX_UNKNOWN 0xFFFFFFFF typedef enum dc_tankvolume_t { @@ -247,7 +248,10 @@ typedef union dc_sample_value_t { const void *data; } vendor; double setpoint; - double ppo2; + struct { + unsigned int sensor; + double value; + } ppo2; double cns; struct { unsigned int type; diff --git a/src/diverite_nitekq_parser.c b/src/diverite_nitekq_parser.c index dec8204..6cfd9bc 100644 --- a/src/diverite_nitekq_parser.c +++ b/src/diverite_nitekq_parser.c @@ -293,7 +293,8 @@ diverite_nitekq_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callbac if (offset + 1 > size) return DC_STATUS_DATAFORMAT; unsigned int ppo2 = data[offset]; - sample.ppo2 = ppo2 / 100.0; + sample.ppo2.sensor = DC_SENSOR_NONE; + sample.ppo2.value = ppo2 / 100.0; if (callback) callback (DC_SAMPLE_PPO2, sample, userdata); offset++; } diff --git a/src/divesoft_freedom_parser.c b/src/divesoft_freedom_parser.c index 6280dbf..1f0b7b3 100644 --- a/src/divesoft_freedom_parser.c +++ b/src/divesoft_freedom_parser.c @@ -946,7 +946,8 @@ divesoft_freedom_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba if (callback) callback(DC_SAMPLE_DEPTH, sample, userdata); if (ppo2) { - sample.ppo2 = ppo2 * 10.0 / BAR; + sample.ppo2.sensor = DC_SENSOR_NONE; + sample.ppo2.value = ppo2 * 10.0 / BAR; if (callback) callback(DC_SAMPLE_PPO2, sample, userdata); } @@ -1045,7 +1046,8 @@ divesoft_freedom_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba unsigned int ppo2 = array_uint16_le (data + offset + 4 + i * 2); if (ppo2 == 0 || ppo2 == 0xFFFF) continue; - sample.ppo2 = ppo2 * 10.0 / BAR; + sample.ppo2.sensor = i; + sample.ppo2.value = ppo2 * 10.0 / BAR; if (callback) callback(DC_SAMPLE_PPO2, sample, userdata); } } else if (id == MEASURE_ID_OXYGEN_MV) { @@ -1055,7 +1057,8 @@ divesoft_freedom_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba if (!parser->calibrated || state == SENSTAT_UNCALIBRATED || state == SENSTAT_NOT_EXIST) continue; - sample.ppo2 = value / 100.0 * parser->calibration[i] / BAR; + sample.ppo2.sensor = i; + sample.ppo2.value = value / 100.0 * parser->calibration[i] / BAR; if (callback) callback(DC_SAMPLE_PPO2, sample, userdata); } } diff --git a/src/hw_ostc_parser.c b/src/hw_ostc_parser.c index de354df..0ee02ac 100644 --- a/src/hw_ostc_parser.c +++ b/src/hw_ostc_parser.c @@ -1067,7 +1067,8 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call } if (count) { for (unsigned int j = 0; j < 3; ++j) { - sample.ppo2 = ppo2[j] / 100.0; + sample.ppo2.sensor = i; + sample.ppo2.value = ppo2[j] / 100.0; if (callback) callback (DC_SAMPLE_PPO2, sample, userdata); } } diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c index 0975ff9..ab7752f 100644 --- a/src/shearwater_predator_parser.c +++ b/src/shearwater_predator_parser.c @@ -927,19 +927,21 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal if (ccr) { // PPO2 if ((status & PPO2_EXTERNAL) == 0) { -#ifdef SENSOR_AVERAGE - sample.ppo2 = data[offset + pnf + 6] / 100.0; + sample.ppo2.sensor = DC_SENSOR_NONE; + sample.ppo2.value = data[offset + pnf + 6] / 100.0; if (callback) callback (DC_SAMPLE_PPO2, sample, userdata); -#else - sample.ppo2 = data[offset + pnf + 12] * parser->calibration[0]; + + sample.ppo2.sensor = 0; + sample.ppo2.value = data[offset + pnf + 12] * parser->calibration[0]; if (callback && (parser->calibrated & 0x01)) callback (DC_SAMPLE_PPO2, sample, userdata); - sample.ppo2 = data[offset + pnf + 14] * parser->calibration[1]; + sample.ppo2.sensor = 1; + sample.ppo2.value = data[offset + pnf + 14] * parser->calibration[1]; if (callback && (parser->calibrated & 0x02)) callback (DC_SAMPLE_PPO2, sample, userdata); - sample.ppo2 = data[offset + pnf + 15] * parser->calibration[2]; + sample.ppo2.sensor = 2; + sample.ppo2.value = data[offset + pnf + 15] * parser->calibration[2]; if (callback && (parser->calibrated & 0x04)) callback (DC_SAMPLE_PPO2, sample, userdata); -#endif } // Setpoint diff --git a/src/tecdiving_divecomputereu_parser.c b/src/tecdiving_divecomputereu_parser.c index bf134eb..ccfbb05 100644 --- a/src/tecdiving_divecomputereu_parser.c +++ b/src/tecdiving_divecomputereu_parser.c @@ -174,7 +174,8 @@ tecdiving_divecomputereu_parser_samples_foreach (dc_parser_t *abstract, dc_sampl // ppO2 unsigned int ppo2 = data[offset + 1]; - sample.ppo2 = ppo2 / 10.0; + sample.ppo2.sensor = DC_SENSOR_NONE; + sample.ppo2.value = ppo2 / 10.0; if (callback) callback (DC_SAMPLE_PPO2, sample, userdata); // Setpoint