Introduce surface samples for the pressure and temperature data.

The Suunto Vyper, Spyder and Eon store a surface event after the last
depth sample. Adding an artificial zero depth sample avoids the problem
of having an incomplete sample without a depth measurement.

Because these devices also store the tank pressure and/or the
temperature at the begin/end of the dive, these measurements are
associated with the new surface samples.
This commit is contained in:
Jef Driesen 2010-05-22 22:11:52 +02:00
parent fd9390e8a8
commit d7c2fbbf18
2 changed files with 135 additions and 7 deletions

View File

@ -141,6 +141,8 @@ suunto_eon_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime)
static parser_status_t
suunto_eon_parser_samples_foreach (parser_t *abstract, sample_callback_t callback, void *userdata)
{
suunto_eon_parser_t *parser = (suunto_eon_parser_t *) abstract;
if (! parser_is_suunto_eon (abstract))
return PARSER_STATUS_TYPE_MISMATCH;
@ -150,11 +152,44 @@ suunto_eon_parser_samples_foreach (parser_t *abstract, sample_callback_t callbac
if (size < 13)
return PARSER_STATUS_ERROR;
unsigned int time = 0, depth = 0;
// Find the maximum depth.
unsigned int depth = 0, maxdepth = 0;
unsigned int offset = 11;
while (offset < size && data[offset] != 0x80) {
unsigned char value = data[offset++];
if (value < 0x7d || value > 0x82) {
depth += (signed char) value;
if (depth > maxdepth)
maxdepth = depth;
}
}
// Store the offset to the end marker.
unsigned int marker = offset;
if (marker + 2 >= size || data[marker] != 0x80)
return PARSER_STATUS_ERROR;
unsigned int time = 0;
unsigned int interval = data[3];
unsigned int complete = 1;
unsigned int offset = 11;
parser_sample_value_t sample = {0};
// Time
sample.time = time;
if (callback) callback (SAMPLE_TYPE_TIME, sample, userdata);
// Tank Pressure (2 bar)
sample.pressure.tank = 0;
sample.pressure.value = data[5] * 2;
if (callback) callback (SAMPLE_TYPE_PRESSURE, sample, userdata);
// Depth (0 ft)
sample.depth = 0;
if (callback) callback (SAMPLE_TYPE_DEPTH, sample, userdata);
depth = 0;
offset = 11;
while (offset < size && data[offset] != 0x80) {
parser_sample_value_t sample = {0};
unsigned char value = data[offset++];
@ -168,10 +203,22 @@ suunto_eon_parser_samples_foreach (parser_t *abstract, sample_callback_t callbac
}
if (value < 0x7d || value > 0x82) {
// Depth (ft).
// Delta depth.
depth += (signed char) value;
// Temperature at maximum depth (°C)
if (depth == maxdepth) {
if (parser->spyder)
sample.temperature = data[marker + 1];
else
sample.temperature = data[marker + 1] - 40;
if (callback) callback (SAMPLE_TYPE_TEMPERATURE, sample, userdata);
}
// Depth (ft).
sample.depth = depth * FEET;
if (callback) callback (SAMPLE_TYPE_DEPTH, sample, userdata);
complete = 1;
} else {
// Event.
@ -200,5 +247,21 @@ suunto_eon_parser_samples_foreach (parser_t *abstract, sample_callback_t callbac
}
}
// Time
if (complete) {
time += interval;
sample.time = time;
if (callback) callback (SAMPLE_TYPE_TIME, sample, userdata);
}
// Tank Pressure (2 bar)
sample.pressure.tank = 0;
sample.pressure.value = data[offset + 2] * 2;
if (callback) callback (SAMPLE_TYPE_PRESSURE, sample, userdata);
// Depth (0 ft)
sample.depth = 0;
if (callback) callback (SAMPLE_TYPE_DEPTH, sample, userdata);
return PARSER_STATUS_SUCCESS;
}

View File

@ -135,13 +135,49 @@ suunto_vyper_parser_samples_foreach (parser_t *abstract, sample_callback_t callb
if (size < 18)
return PARSER_STATUS_ERROR;
unsigned int time = 0, depth = 0;
// Find the maximum depth.
unsigned int depth = 0, maxdepth = 0;
unsigned int offset = 14;
while (offset < size && data[offset] != 0x80) {
unsigned char value = data[offset++];
if (value < 0x79 || value > 0x87) {
depth += (signed char) value;
if (depth > maxdepth)
maxdepth = depth;
}
}
// Store the offset to the end marker.
unsigned int marker = offset;
if (marker + 4 >= size || data[marker] != 0x80)
return PARSER_STATUS_ERROR;
unsigned int time = 0;
unsigned int interval = data[3];
unsigned int complete = 1;
unsigned int offset = 14;
parser_sample_value_t sample = {0};
// Time
sample.time = time;
if (callback) callback (SAMPLE_TYPE_TIME, sample, userdata);
// Temperature (°C)
sample.temperature = data[8];
if (callback) callback (SAMPLE_TYPE_TEMPERATURE, sample, userdata);
// Tank Pressure (2 bar)
sample.pressure.tank = 0;
sample.pressure.value = data[5] * 2;
if (callback) callback (SAMPLE_TYPE_PRESSURE, sample, userdata);
// Depth (0 ft)
sample.depth = 0;
if (callback) callback (SAMPLE_TYPE_DEPTH, sample, userdata);
depth = 0;
offset = 14;
while (offset < size && data[offset] != 0x80) {
parser_sample_value_t sample = {0};
unsigned char value = data[offset++];
if (complete) {
@ -153,10 +189,19 @@ suunto_vyper_parser_samples_foreach (parser_t *abstract, sample_callback_t callb
}
if (value < 0x79 || value > 0x87) {
// Depth (ft).
// Delta depth.
depth += (signed char) value;
// Temperature at maximum depth (°C)
if (depth == maxdepth) {
sample.temperature = data[marker + 1];
if (callback) callback (SAMPLE_TYPE_TEMPERATURE, sample, userdata);
}
// Depth (ft).
sample.depth = depth * FEET;
if (callback) callback (SAMPLE_TYPE_DEPTH, sample, userdata);
complete = 1;
} else {
// Event.
@ -199,5 +244,25 @@ suunto_vyper_parser_samples_foreach (parser_t *abstract, sample_callback_t callb
}
}
// Time
if (complete) {
time += interval;
sample.time = time;
if (callback) callback (SAMPLE_TYPE_TIME, sample, userdata);
}
// Temperature (°C)
sample.temperature = data[offset + 2];
if (callback) callback (SAMPLE_TYPE_TEMPERATURE, sample, userdata);
// Tank Pressure (2 bar)
sample.pressure.tank = 0;
sample.pressure.value = data[offset + 3] * 2;
if (callback) callback (SAMPLE_TYPE_PRESSURE, sample, userdata);
// Depth (0 ft)
sample.depth = 0;
if (callback) callback (SAMPLE_TYPE_DEPTH, sample, userdata);
return PARSER_STATUS_SUCCESS;
}