From c685f3d6a19c5f6351761f77fbc794527e2451c0 Mon Sep 17 00:00:00 2001 From: Michael Keller Date: Tue, 14 Jan 2025 00:23:13 +1300 Subject: [PATCH] Import: Fix the Handling of ppO2 Sensor IDs. Instead of assigning sensor ids in the order that values are reported, actually use the sensor ids reported by libdivecomputer. This will fix the problem that for some dive computers (e.g. Shearwater) the dive computer calculated ppO2 is currently reported first, thus pushing out all actual sensor values. A new fixed id (7) outside of the range of currently supported sensor IDs is used for these dive computer calculated values. Signed-off-by: Michael Keller --- core/libdivecomputer.cpp | 28 ++++++++++++++++------------ core/load-git.cpp | 4 ++++ core/parse-xml.cpp | 2 ++ core/profile.cpp | 6 +++--- core/sample.h | 3 ++- core/save-git.cpp | 5 +++++ core/save-xml.cpp | 5 +++++ profile-widget/profilescene.cpp | 2 +- 8 files changed, 38 insertions(+), 17 deletions(-) diff --git a/core/libdivecomputer.cpp b/core/libdivecomputer.cpp index fd587b93d..c3f681557 100644 --- a/core/libdivecomputer.cpp +++ b/core/libdivecomputer.cpp @@ -379,7 +379,6 @@ static void handle_gasmix(struct divecomputer *dc, const struct sample &sample, void sample_cb(dc_sample_type_t type, const dc_sample_value_t *pvalue, void *userdata) { - static unsigned int nsensor = 0; struct divecomputer *dc = (divecomputer *)userdata; dc_sample_value_t value = *pvalue; @@ -388,8 +387,6 @@ sample_cb(dc_sample_type_t type, const dc_sample_value_t *pvalue, void *userdata * Other types fill in an existing sample. */ if (type == DC_SAMPLE_TIME) { - nsensor = 0; - // Create a new sample. // Mark depth as negative struct sample *sample = prepare_sample(dc); @@ -456,16 +453,23 @@ sample_cb(dc_sample_type_t type, const dc_sample_value_t *pvalue, void *userdata /* for us a setpoint means constant pO2 from here */ sample.setpoint.mbar = po2 = lrint(value.setpoint * 1000); break; - case DC_SAMPLE_PPO2: - if (nsensor < MAX_O2_SENSORS) - sample.o2sensor[nsensor].mbar = lrint(value.ppo2.value * 1000); - else - report_error("%d is more o2 sensors than we can handle", nsensor); - nsensor++; - // Set the amount of detected o2 sensors - if (nsensor > dc->no_o2sensors) - dc->no_o2sensors = nsensor; + case DC_SAMPLE_PPO2: { + unsigned int sensor_id = value.ppo2.sensor; + if (sensor_id == DC_SENSOR_NONE) { + sample.o2sensor[DC_REPORTED_PPO2].mbar = lrint(value.ppo2.value * 1000); + } else if (sensor_id >= MAX_O2_SENSORS) { + report_error("%d is more o2 sensors than we can handle", sensor_id + 1); + + break; + } else { + sample.o2sensor[sensor_id].mbar = lrint(value.ppo2.value * 1000); + + // Set the amount of detected o2 sensors + if (sensor_id + 1 > dc->no_o2sensors) + dc->no_o2sensors = sensor_id + 1; + } break; + } case DC_SAMPLE_CNS: sample.cns = cns = lrint(value.cns * 100); break; diff --git a/core/load-git.cpp b/core/load-git.cpp index d7233e768..f1ec41528 100644 --- a/core/load-git.cpp +++ b/core/load-git.cpp @@ -585,6 +585,10 @@ static void parse_sample_keyvalue(void *_sample, const char *key, const std::str sample->o2sensor[5] = get_o2pressure(value.c_str()); return; } + if (!strcmp(key, "sensor7")) { + sample->o2sensor[6] = get_o2pressure(value.c_str()); + return; + } if (!strcmp(key, "o2pressure")) { sample->pressure[1] = get_pressure(value.c_str()); return; diff --git a/core/parse-xml.cpp b/core/parse-xml.cpp index 7905336fa..933247cfb 100644 --- a/core/parse-xml.cpp +++ b/core/parse-xml.cpp @@ -931,6 +931,8 @@ static void try_to_fill_sample(struct sample *sample, const char *name, char *bu return; if (MATCH("sensor6.sample", double_to_o2pressure, &sample->o2sensor[5])) // up to 6 CCR sensors return; + if (MATCH("sensor7.sample", double_to_o2pressure, &sample->o2sensor[6])) // the dive computer calculated ppO2 + return; if (MATCH("po2.sample", double_to_o2pressure, &sample->setpoint)) return; if (MATCH("heartbeat", get_uint8, &sample->heartbeat)) diff --git a/core/profile.cpp b/core/profile.cpp index fb2320c2e..062457a97 100644 --- a/core/profile.cpp +++ b/core/profile.cpp @@ -1030,7 +1030,7 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_ /* Sort the o2 pressure values. There are so few that a simple bubble sort * will do */ -void sort_o2_pressures(int *sensorn, int np, const struct plot_data &entry) +static void sort_o2_pressures(int *sensorn, int np, const struct plot_data &entry) { int smallest, position, old; @@ -1196,9 +1196,9 @@ static void debug_print_profiledata(struct plot_info &pi) fprintf(f1, "id t1 gas gasint t2 t3 dil dilint t4 t5 setpoint sensor1 sensor2 sensor3 t6 po2 fo2\n"); for (i = 0; i < pi.nr; i++) { struct plot_data &entry = pi.entry[i]; - fprintf(f1, "%d gas=%8d %8d ; dil=%8d %8d ; o2_sp= %d %d %d %d PO2= %f\n", i, get_plot_sensor_pressure(pi, i), + fprintf(f1, "%d gas=%8d %8d ; dil=%8d %8d ; o2_sp= %d %d %d %d %d %d %d PO2= %f\n", i, get_plot_sensor_pressure(pi, i), get_plot_interpolated_pressure(pi, i), O2CYLINDER_PRESSURE(entry), INTERPOLATED_O2CYLINDER_PRESSURE(entry), - entry.o2pressure.mbar, entry.o2sensor[0].mbar, entry.o2sensor[1].mbar, entry.o2sensor[2].mbar, entry.pressures.o2); + entry.o2pressure.mbar, entry.o2sensor[0].mbar, entry.o2sensor[1].mbar, entry.o2sensor[2].mbar, entry.o2sensor[3].mbar, entry.o2sensor[4].mbar, entry.o2sensor[5].mbar, entry.pressures.o2); } fclose(f1); } diff --git a/core/sample.h b/core/sample.h index 8b517a149..a91c6d0cc 100644 --- a/core/sample.h +++ b/core/sample.h @@ -6,6 +6,7 @@ #define MAX_SENSORS 2 #define MAX_O2_SENSORS 6 +#define DC_REPORTED_PPO2 MAX_O2_SENSORS #define NO_SENSOR -1 struct sample // BASE TYPE BYTES UNITS RANGE DESCRIPTION @@ -20,7 +21,7 @@ struct sample // BASE TYPE BYTES UNITS RANGE temperature_t temperature; // uint32_t 4 mK (0-4 MK) ambient temperature pressure_t pressure[MAX_SENSORS]; // int32_t 2x4 mbar (0-2 Mbar) cylinder pressures (main and CCR o2) o2pressure_t setpoint; // uint16_t 2 mbar (0-65 bar) O2 partial pressure (will be setpoint) - o2pressure_t o2sensor[MAX_O2_SENSORS];// uint16_t 6x2 mbar (0-65 bar) Up to 6 PO2 sensor values (rebreather) + o2pressure_t o2sensor[MAX_O2_SENSORS + 1]; // uint16_t 6x2 mbar (0-65 bar) Up to 6 PO2 sensor values (rebreather) bearing_t bearing = { .degrees = -1 };// int16_t 2 degrees (-1 no val, 0-360 deg) compass bearing int16_t sensor[MAX_SENSORS] = {}; // int16_t 2x2 sensorID (0-16k) ID of cylinder pressure sensor uint16_t cns = 0; // uint16_t 2 % (0-64k %) cns% accumulated diff --git a/core/save-git.cpp b/core/save-git.cpp index 8ab233f9c..bc78445d5 100644 --- a/core/save-git.cpp +++ b/core/save-git.cpp @@ -342,6 +342,11 @@ static void save_sample(struct membuffer *b, const struct sample &sample, struct old.o2sensor[5] = sample.o2sensor[5]; } + if ((sample.o2sensor[6].mbar) && (sample.o2sensor[6].mbar != old.o2sensor[6].mbar)) { + put_milli(b, " sensor7=", sample.o2sensor[6].mbar, "bar"); + old.o2sensor[6] = sample.o2sensor[6]; + } + if (sample.setpoint.mbar != old.setpoint.mbar) { put_milli(b, " po2=", sample.setpoint.mbar, "bar"); old.setpoint = sample.setpoint; diff --git a/core/save-xml.cpp b/core/save-xml.cpp index 500c4bfbe..1a3c76545 100644 --- a/core/save-xml.cpp +++ b/core/save-xml.cpp @@ -327,6 +327,11 @@ static void save_sample(struct membuffer *b, const struct sample &sample, struct old.o2sensor[5] = sample.o2sensor[5]; } + if ((sample.o2sensor[6].mbar) && (sample.o2sensor[6].mbar != old.o2sensor[6].mbar)) { + put_milli(b, " sensor7='", sample.o2sensor[6].mbar, " bar'"); + old.o2sensor[6] = sample.o2sensor[6]; + } + if (sample.setpoint.mbar != old.setpoint.mbar) { put_milli(b, " po2='", sample.setpoint.mbar, " bar'"); old.setpoint = sample.setpoint; diff --git a/profile-widget/profilescene.cpp b/profile-widget/profilescene.cpp index 7c99b1fc7..d4acfd448 100644 --- a/profile-widget/profilescene.cpp +++ b/profile-widget/profilescene.cpp @@ -234,7 +234,7 @@ void ProfileScene::updateVisibility(bool diveHasHeartBeat, bool simplified) o2SetpointGasItem->setVisible(ppGraphs && prefs.show_ccr_setpoint); ccrsensor1GasItem->setVisible(ppGraphs && prefs.show_ccr_sensors); ccrsensor2GasItem->setVisible(ppGraphs && prefs.show_ccr_sensors && (currentdc->no_o2sensors > 1)); - ccrsensor3GasItem->setVisible(ppGraphs && prefs.show_ccr_sensors && (currentdc->no_o2sensors > 1)); + ccrsensor3GasItem->setVisible(ppGraphs && prefs.show_ccr_sensors && (currentdc->no_o2sensors > 2)); ocpo2GasItem->setVisible((currentdc->divemode == PSCR) && prefs.show_scr_ocpo2); // No point to show the gradient factor if we're not showing the calculated ceiling that is derived from it decoModelParameters->setVisible(prefs.calcceiling);