Add a usage field to the tank and gas mix

For gas consumption calculations it's very convenient to know whether a
tank is used for example in a sidemount configuration, or as
oxygen/diluent tank on a rebreather.

For rebreather dives, it's convenient to know whether a gas mix is used
as a closed-circuit mix (oxygen/diluent) or as an open circuit mix
(bailout).
This commit is contained in:
Jef Driesen 2021-06-14 20:58:14 +02:00
parent 4b383a778e
commit becb8bd36e
31 changed files with 95 additions and 4 deletions

View File

@ -338,11 +338,19 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u
"<gasmix>\n"
" <he>%.1f</he>\n"
" <o2>%.1f</o2>\n"
" <n2>%.1f</n2>\n"
"</gasmix>\n",
" <n2>%.1f</n2>\n",
gasmix.helium * 100.0,
gasmix.oxygen * 100.0,
gasmix.nitrogen * 100.0);
if (gasmix.usage) {
const char *usage[] = {"none", "oxygen", "diluent", "sidemount"};
fprintf (output->ostream,
" <usage>%s</usage>\n",
usage[gasmix.usage]);
}
fprintf (output->ostream,
"</gasmix>\n");
}
// Parse the tanks.
@ -370,6 +378,12 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u
" <gasmix>%u</gasmix>\n",
tank.gasmix);
}
if (tank.usage) {
const char *usage[] = {"none", "oxygen", "diluent", "sidemount"};
fprintf (output->ostream,
" <usage>%s</usage>\n",
usage[tank.usage]);
}
if (tank.type != DC_TANKVOLUME_NONE) {
fprintf (output->ostream,
" <type>%s</type>\n"

View File

@ -141,10 +141,18 @@ typedef struct dc_salinity_t {
double density;
} dc_salinity_t;
typedef enum dc_usage_t {
DC_USAGE_NONE,
DC_USAGE_OXYGEN,
DC_USAGE_DILUENT,
DC_USAGE_SIDEMOUNT,
} dc_usage_t;
typedef struct dc_gasmix_t {
double helium;
double oxygen;
double nitrogen;
dc_usage_t usage;
} dc_gasmix_t;
#define DC_SENSOR_NONE 0xFFFFFFFF
@ -186,6 +194,7 @@ typedef struct dc_tank_t {
double workpressure; /* Work pressure (bar) */
double beginpressure; /* Begin pressure (bar) */
double endpressure; /* End pressure (bar) */
dc_usage_t usage;
} dc_tank_t;
typedef enum dc_decomodel_type_t {

View File

@ -171,6 +171,7 @@ atomics_cobalt_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un
*((unsigned int *) value) = p[0x2a];
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = p[SZ_HEADER + SZ_GASMIX * flags + 5] / 100.0;
gasmix->oxygen = p[SZ_HEADER + SZ_GASMIX * flags + 4] / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@ -202,6 +203,7 @@ atomics_cobalt_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un
tank->gasmix = flags;
tank->beginpressure = array_uint16_le(p + 6) * PSI / BAR;
tank->endpressure = array_uint16_le(p + 14) * PSI / BAR;
tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_DIVEMODE:
switch(p[0x24]) {

View File

@ -514,6 +514,7 @@ cochran_commander_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
// Gas percentages are decimal and encoded as
// highbyte = integer portion
// lowbyte = decimal portion, divide by 256 to get decimal value
gasmix->usage = DC_USAGE_NONE;
gasmix->oxygen = array_uint16_le (data + layout->oxygen + 2 * flags) / 256.0 / 100;
if (layout->helium == UNSUPPORTED) {
gasmix->helium = 0;

View File

@ -152,6 +152,7 @@ cressi_edy_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
*((unsigned int *) value) = cressi_edy_parser_count_gasmixes(p);
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
gasmix->oxygen = bcd2dec (p[0x17 - flags]) / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;

View File

@ -250,6 +250,7 @@ cressi_goa_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
*((unsigned int *) value) = ngasmixes;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
gasmix->oxygen = data[layout->gasmix + 2 * flags + 1] / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;

View File

@ -146,6 +146,7 @@ cressi_leonardo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, u
}
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
gasmix->oxygen = data[0x19] / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;

View File

@ -151,6 +151,7 @@ deepblu_cosmiq_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un
*((unsigned int *) value) = mode == SCUBA;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->oxygen = data[3] / 100.0;
gasmix->helium = 0.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;

View File

@ -322,6 +322,7 @@ deepsix_excursion_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
gasmix->helium = parser->gasmix[flags].helium / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;

View File

@ -161,6 +161,7 @@ diverite_nitekq_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, u
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = parser->he[flags] / 100.0;
gasmix->oxygen = parser->o2[flags] / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;

View File

@ -838,6 +838,13 @@ divesoft_freedom_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
if (parser->gasmix[flags].type == OXYGEN) {
gasmix->usage = DC_USAGE_OXYGEN;
} else if (parser->gasmix[flags].type == DILUENT) {
gasmix->usage = DC_USAGE_DILUENT;
} else {
gasmix->usage = DC_USAGE_NONE;
}
gasmix->helium = parser->gasmix[flags].helium / 100.0;
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@ -859,6 +866,7 @@ divesoft_freedom_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
tank->beginpressure = parser->tank[flags].beginpressure * 2.0;
tank->endpressure = parser->tank[flags].endpressure * 2.0;
tank->gasmix = flags;
tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_DECOMODEL:
if (parser->vpm) {

View File

@ -317,6 +317,7 @@ divesystem_idive_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = parser->gasmix[flags].helium / 100.0;
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@ -331,6 +332,7 @@ divesystem_idive_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
tank->beginpressure = parser->tank[flags].beginpressure;
tank->endpressure = parser->tank[flags].endpressure;
tank->gasmix = DC_GASMIX_UNKNOWN;
tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_ATMOSPHERIC:
if (ISIX3M(parser->model)) {

View File

@ -552,6 +552,8 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
gasmix->usage = parser->gasmix[flags].diluent ?
DC_USAGE_DILUENT : DC_USAGE_NONE;
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
gasmix->helium = parser->gasmix[flags].helium / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;

View File

@ -315,6 +315,7 @@ liquivision_lynx_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = parser->gasmix[flags].helium / 100.0;
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@ -329,6 +330,7 @@ liquivision_lynx_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
tank->beginpressure = parser->tank[flags].beginpressure / 100.0;
tank->endpressure = parser->tank[flags].endpressure / 100.0;
tank->gasmix = DC_GASMIX_UNKNOWN;
tank->usage = DC_USAGE_NONE;
break;
default:
return DC_STATUS_UNSUPPORTED;

View File

@ -159,6 +159,7 @@ mares_darwin_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
}
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
if (mode == NITROX) {
gasmix->oxygen = p[0x0E] / 100.0;
@ -185,6 +186,7 @@ mares_darwin_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
tank->gasmix = 0;
tank->beginpressure = array_uint16_be (p + 0x17);
tank->endpressure = array_uint16_be (p + 0x19);
tank->usage = DC_USAGE_NONE;
} else {
return DC_STATUS_UNSUPPORTED;
}

View File

@ -830,6 +830,7 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
gasmix->helium = parser->gasmix[flags].helium / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@ -857,6 +858,7 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
} else {
tank->gasmix = DC_GASMIX_UNKNOWN;
}
tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_ATMOSPHERIC:
*((double *) value) = array_uint16_le (p + parser->layout->atmospheric) / (1000.0 * parser->layout->atmospheric_divisor);

View File

@ -251,6 +251,7 @@ mares_nemo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
}
gasmix->helium = 0.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
gasmix->usage = DC_USAGE_NONE;
break;
case DC_FIELD_TANK_COUNT:
if (parser->extra)
@ -290,6 +291,7 @@ mares_nemo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
} else {
tank->gasmix = DC_GASMIX_UNKNOWN;
}
tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_TEMPERATURE_MINIMUM:
*((double *) value) = (signed char) p[53 - 11];

View File

@ -221,6 +221,7 @@ mclean_extreme_parser_get_field(dc_parser_t *abstract, dc_field_type_t type, uns
*((unsigned int *)value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.01 * abstract->data[0x0001 + 1 + 2 * parser->gasmix[flags]];
gasmix->oxygen = 0.01 * abstract->data[0x0001 + 0 + 2 * parser->gasmix[flags]];
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;

View File

@ -516,6 +516,7 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->oxygen = parser->oxygen[flags] / 100.0;
gasmix->helium = parser->helium[flags] / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;

View File

@ -170,6 +170,7 @@ oceanic_veo250_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un
*((unsigned int *) value) = 1;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
if (data[footer + 6])
gasmix->oxygen = data[footer + 6] / 100.0;

View File

@ -200,6 +200,7 @@ oceanic_vtpro_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns
*((unsigned int *) value) = 1;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
if (oxygen)
gasmix->oxygen = oxygen / 100.0;
@ -220,6 +221,7 @@ oceanic_vtpro_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns
tank->gasmix = flags;
tank->beginpressure = beginpressure * 2 * PSI / BAR;
tank->endpressure = endpressure * 2 * PSI / BAR;
tank->usage = DC_USAGE_NONE;
break;
default:
return DC_STATUS_UNSUPPORTED;

View File

@ -166,6 +166,7 @@ oceans_s1_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
*((unsigned int *) value) = parser->divemode == SCUBA;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
gasmix->oxygen = parser->oxygen / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;

View File

@ -239,6 +239,7 @@ seac_screen_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsig
*((unsigned int *)value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
gasmix->oxygen = parser->oxygen[flags] / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;

View File

@ -774,6 +774,7 @@ shearwater_predator_parser_get_field (dc_parser_t *abstract, dc_field_type_t typ
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
gasmix->usage = parser->gasmix[flags].diluent ? DC_USAGE_DILUENT : DC_USAGE_NONE;
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
gasmix->helium = parser->gasmix[flags].helium / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@ -788,6 +789,22 @@ shearwater_predator_parser_get_field (dc_parser_t *abstract, dc_field_type_t typ
tank->beginpressure = parser->tank[flags].beginpressure * 2 * PSI / BAR;
tank->endpressure = parser->tank[flags].endpressure * 2 * PSI / BAR;
tank->gasmix = DC_GASMIX_UNKNOWN;
switch (parser->tank[flags].name[0]) {
case 'S':
tank->usage = DC_USAGE_SIDEMOUNT;
break;
case 'O':
tank->usage = DC_USAGE_OXYGEN;
break;
case 'D':
tank->usage = DC_USAGE_DILUENT;
break;
case 'T':
case 'B':
default:
tank->usage = DC_USAGE_NONE;
break;
}
break;
case DC_FIELD_SALINITY:
if (parser->density == 1000)

View File

@ -388,6 +388,7 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = parser->helium[flags] / 100.0;
gasmix->oxygen = parser->oxygen[flags] / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;

View File

@ -225,6 +225,7 @@ suunto_eon_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
*((unsigned int *) value) = 1;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
gasmix->oxygen = oxygen / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@ -242,6 +243,7 @@ suunto_eon_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
tank->gasmix = 0;
tank->beginpressure = beginpressure;
tank->endpressure = endpressure;
tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_TEMPERATURE_MINIMUM:
if (parser->spyder)

View File

@ -88,6 +88,7 @@ typedef struct suunto_eonsteel_parser_t {
double highsetpoint;
double customsetpoint;
dc_tankvolume_t tankinfo[MAXGASES];
dc_usage_t tankusage[MAXGASES];
double tanksize[MAXGASES];
double tankworkingpressure[MAXGASES];
dc_decomodel_t decomodel;
@ -1097,6 +1098,7 @@ suunto_eonsteel_parser_get_field(dc_parser_t *parser, dc_field_type_t type, unsi
if (fabs(tank->volume - rint(tank->volume)) > 0.001)
tank->type = DC_TANKVOLUME_IMPERIAL;
}
tank->usage = eon->cache.tankusage[flags];
break;
case DC_FIELD_DECOMODEL:
field_value(value, eon->cache.decomodel);
@ -1160,6 +1162,7 @@ static int add_gas_type(suunto_eonsteel_parser_t *eon, const struct type_desc *d
{
int idx = eon->cache.ngases;
dc_tankvolume_t tankinfo = DC_TANKVOLUME_METRIC;
dc_usage_t usage = DC_USAGE_NONE;
char *name;
if (idx >= MAXGASES)
@ -1170,15 +1173,17 @@ static int add_gas_type(suunto_eonsteel_parser_t *eon, const struct type_desc *d
if (!name)
DEBUG(eon->base.context, "Unable to look up gas type %u in %s", type, desc->format);
else if (!strcasecmp(name, "Diluent"))
;
usage = DC_USAGE_DILUENT;
else if (!strcasecmp(name, "Oxygen"))
;
usage = DC_USAGE_OXYGEN;
else if (!strcasecmp(name, "None"))
tankinfo = DC_TANKVOLUME_NONE;
else if (strcasecmp(name, "Primary"))
DEBUG(eon->base.context, "Unknown gas type %u (%s)", type, name);
eon->cache.tankinfo[idx] = tankinfo;
eon->cache.tankusage[idx] = usage;
eon->cache.gasmix[idx].usage = usage;
eon->cache.initialized |= 1 << DC_FIELD_GASMIX_COUNT;
eon->cache.initialized |= 1 << DC_FIELD_TANK_COUNT;

View File

@ -151,6 +151,7 @@ suunto_solution_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, u
*((unsigned int *) value) = 1;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
gasmix->oxygen = 0.21;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;

View File

@ -267,6 +267,7 @@ suunto_vyper_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
gas->usage = DC_USAGE_NONE;
gas->helium = 0.0;
gas->oxygen = parser->oxygen[flags] / 100.0;
gas->nitrogen = 1.0 - gas->oxygen - gas->helium;
@ -287,6 +288,7 @@ suunto_vyper_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
tank->gasmix = 0;
tank->beginpressure = beginpressure;
tank->endpressure = endpressure;
tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_TEMPERATURE_SURFACE:
*((double *) value) = (signed char) data[8];

View File

@ -166,6 +166,7 @@ uwatec_memomouse_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
*((unsigned int *) value) = 1;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
if (size >= header + 18) {
if (is_oxygen)
@ -197,6 +198,7 @@ uwatec_memomouse_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
}
tank->endpressure = 0.0;
tank->gasmix = 0;
tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_TEMPERATURE_MINIMUM:
*((double *) value) = (signed char) data[15] / 4.0;

View File

@ -807,6 +807,7 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
gasmix->usage = DC_USAGE_NONE;
gasmix->helium = parser->gasmix[flags].helium / 100.0;
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@ -821,6 +822,7 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
tank->beginpressure = parser->tank[flags].beginpressure / 128.0;
tank->endpressure = parser->tank[flags].endpressure / 128.0;
tank->gasmix = parser->tank[flags].gasmix;
tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_TEMPERATURE_MINIMUM:
*((double *) value) = (signed short) array_uint16_le (data + table->temp_minimum) / 10.0;