From cdbc0cd9bd1b29b23cd08ffa844be074300d6c6b Mon Sep 17 00:00:00 2001 From: Calle Gunnarsson Date: Fri, 22 Aug 2014 12:06:24 +0200 Subject: [PATCH 1/4] Added support for parsing temperature in the dive header Devices that only reports a single temperature in the header will now be able to report it as well when they implement this. Signed-off-by: Calle Gunnarsson --- examples/universal.c | 15 +++++++++++++++ include/libdivecomputer/parser.h | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/examples/universal.c b/examples/universal.c index 1e0307b..c90fe5b 100644 --- a/examples/universal.c +++ b/examples/universal.c @@ -361,6 +361,21 @@ doparse (FILE *fp, dc_device_t *device, const unsigned char data[], unsigned int fprintf (fp, "%02u:%02u\n", divetime / 60, divetime % 60); + // Parse the temperature. + message ("Parsing the temperature.\n"); + double temperature = 0.0; + rc = dc_parser_get_field (parser, DC_FIELD_TEMPERATURE, 0, &temperature); + if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { + WARNING ("Error parsing the temperature."); + dc_parser_destroy (parser); + return rc; + } + + if (rc != DC_STATUS_UNSUPPORTED) { + fprintf (fp, "%.1f\n", + temperature); + } + // Parse the maxdepth. message ("Parsing the maxdepth.\n"); double maxdepth = 0.0; diff --git a/include/libdivecomputer/parser.h b/include/libdivecomputer/parser.h index 65b18c9..a1919a9 100644 --- a/include/libdivecomputer/parser.h +++ b/include/libdivecomputer/parser.h @@ -53,7 +53,8 @@ typedef enum dc_field_type_t { DC_FIELD_GASMIX_COUNT, DC_FIELD_GASMIX, DC_FIELD_SALINITY, - DC_FIELD_ATMOSPHERIC + DC_FIELD_ATMOSPHERIC, + DC_FIELD_TEMPERATURE } dc_field_type_t; typedef enum parser_sample_event_t { From a4e5d4234c4d3e410ab6fdd1e3eee1b9a6726bee Mon Sep 17 00:00:00 2001 From: Calle Gunnarsson Date: Fri, 22 Aug 2014 12:11:05 +0200 Subject: [PATCH 2/4] Cressi Leonardo now reports temperature from dive header Signed-off-by: Calle Gunnarsson --- src/cressi_leonardo_parser.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cressi_leonardo_parser.c b/src/cressi_leonardo_parser.c index db2d3f0..f79723f 100644 --- a/src/cressi_leonardo_parser.c +++ b/src/cressi_leonardo_parser.c @@ -139,6 +139,9 @@ cressi_leonardo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, u gasmix->oxygen = data[0x19] / 100.0; gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium; break; + case DC_FIELD_TEMPERATURE: + *((double *) value) = data[0x22]; + break; default: return DC_STATUS_UNSUPPORTED; } From 693a452250c7c9df17c94fbec26d62369cc42ee9 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 20 Oct 2014 22:12:58 +0200 Subject: [PATCH 3/4] Extend temperature with surface, min and max values. --- examples/universal.c | 27 +++++++++++++++++---------- include/libdivecomputer/parser.h | 4 +++- src/cressi_leonardo_parser.c | 2 +- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/examples/universal.c b/examples/universal.c index c90fe5b..9d07088 100644 --- a/examples/universal.c +++ b/examples/universal.c @@ -363,17 +363,24 @@ doparse (FILE *fp, dc_device_t *device, const unsigned char data[], unsigned int // Parse the temperature. message ("Parsing the temperature.\n"); - double temperature = 0.0; - rc = dc_parser_get_field (parser, DC_FIELD_TEMPERATURE, 0, &temperature); - if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { - WARNING ("Error parsing the temperature."); - dc_parser_destroy (parser); - return rc; - } + for (unsigned int i = 0; i < 3; ++i) { + dc_field_type_t fields[] = {DC_FIELD_TEMPERATURE_SURFACE, + DC_FIELD_TEMPERATURE_MINIMUM, + DC_FIELD_TEMPERATURE_MAXIMUM}; + const char *names[] = {"surface", "minimum", "maximum"}; - if (rc != DC_STATUS_UNSUPPORTED) { - fprintf (fp, "%.1f\n", - temperature); + double temperature = 0.0; + rc = dc_parser_get_field (parser, fields[i], 0, &temperature); + if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { + WARNING ("Error parsing the temperature."); + dc_parser_destroy (parser); + return rc; + } + + if (rc != DC_STATUS_UNSUPPORTED) { + fprintf (fp, "%.1f\n", + names[i], temperature); + } } // Parse the maxdepth. diff --git a/include/libdivecomputer/parser.h b/include/libdivecomputer/parser.h index a1919a9..526173a 100644 --- a/include/libdivecomputer/parser.h +++ b/include/libdivecomputer/parser.h @@ -54,7 +54,9 @@ typedef enum dc_field_type_t { DC_FIELD_GASMIX, DC_FIELD_SALINITY, DC_FIELD_ATMOSPHERIC, - DC_FIELD_TEMPERATURE + DC_FIELD_TEMPERATURE_SURFACE, + DC_FIELD_TEMPERATURE_MINIMUM, + DC_FIELD_TEMPERATURE_MAXIMUM } dc_field_type_t; typedef enum parser_sample_event_t { diff --git a/src/cressi_leonardo_parser.c b/src/cressi_leonardo_parser.c index f79723f..b01a37a 100644 --- a/src/cressi_leonardo_parser.c +++ b/src/cressi_leonardo_parser.c @@ -139,7 +139,7 @@ cressi_leonardo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, u gasmix->oxygen = data[0x19] / 100.0; gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium; break; - case DC_FIELD_TEMPERATURE: + case DC_FIELD_TEMPERATURE_MINIMUM: *((double *) value) = data[0x22]; break; default: From 52cac91b18e23489a6d840e0d974f22a2ac04faa Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 21 Oct 2014 21:21:46 +0200 Subject: [PATCH 4/4] Implement the temperature support for several devices. The new temperature fields are now supported by devices from these manufacturers: * Atomic Aquatics * Heinrichs Weikamp * Mares * Suunto * Uwatec --- src/atomics_cobalt_parser.c | 3 +++ src/hw_ostc_parser.c | 7 +++++ src/mares_darwin_parser.c | 3 +++ src/mares_iconhd_parser.c | 6 +++++ src/mares_nemo_parser.c | 6 +++++ src/suunto_vyper_parser.c | 11 ++++++++ src/uwatec_memomouse_parser.c | 3 +++ src/uwatec_smart_parser.c | 48 ++++++++++++++++++++++++++++++----- 8 files changed, 81 insertions(+), 6 deletions(-) diff --git a/src/atomics_cobalt_parser.c b/src/atomics_cobalt_parser.c index bd41914..fdf918c 100644 --- a/src/atomics_cobalt_parser.c +++ b/src/atomics_cobalt_parser.c @@ -173,6 +173,9 @@ atomics_cobalt_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un gasmix->oxygen = p[SZ_HEADER + SZ_GASMIX * flags + 4] / 100.0; gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium; break; + case DC_FIELD_TEMPERATURE_SURFACE: + *((double *) value) = (p[0x1B] - 32.0) * (5.0 / 9.0); + break; default: return DC_STATUS_UNSUPPORTED; } diff --git a/src/hw_ostc_parser.c b/src/hw_ostc_parser.c index 10cae80..ac42219 100644 --- a/src/hw_ostc_parser.c +++ b/src/hw_ostc_parser.c @@ -53,6 +53,7 @@ typedef struct hw_ostc_layout_t { unsigned int atmospheric; unsigned int salinity; unsigned int duration; + unsigned int temperature; } hw_ostc_layout_t; typedef struct hw_ostc_gasmix_t { @@ -82,6 +83,7 @@ static const hw_ostc_layout_t hw_ostc_layout_ostc = { 15, /* atmospheric */ 43, /* salinity */ 47, /* duration */ + 13, /* temperature */ }; static const hw_ostc_layout_t hw_ostc_layout_frog = { @@ -91,6 +93,7 @@ static const hw_ostc_layout_t hw_ostc_layout_frog = { 21, /* atmospheric */ 43, /* salinity */ 47, /* duration */ + 19, /* temperature */ }; static const hw_ostc_layout_t hw_ostc_layout_ostc3 = { @@ -100,6 +103,7 @@ static const hw_ostc_layout_t hw_ostc_layout_ostc3 = { 24, /* atmospheric */ 70, /* salinity */ 75, /* duration */ + 22, /* temperature */ }; dc_status_t @@ -316,6 +320,9 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned case DC_FIELD_ATMOSPHERIC: *((double *) value) = array_uint16_le (data + layout->atmospheric) / 1000.0; break; + case DC_FIELD_TEMPERATURE_MINIMUM: + *((double *) value) = (signed short) array_uint16_le (data + layout->temperature) / 10.0; + break; default: return DC_STATUS_UNSUPPORTED; } diff --git a/src/mares_darwin_parser.c b/src/mares_darwin_parser.c index 4235f40..183df48 100644 --- a/src/mares_darwin_parser.c +++ b/src/mares_darwin_parser.c @@ -156,6 +156,9 @@ mares_darwin_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi gasmix->oxygen = 0.21; gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium; break; + case DC_FIELD_TEMPERATURE_MINIMUM: + *((double *) value) = (signed char) p[0x0A]; + break; default: return DC_STATUS_UNSUPPORTED; } diff --git a/src/mares_iconhd_parser.c b/src/mares_iconhd_parser.c index af4744c..6016e44 100644 --- a/src/mares_iconhd_parser.c +++ b/src/mares_iconhd_parser.c @@ -252,6 +252,12 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi // Pressure (1/8 millibar) *((double *) value) = array_uint16_le (p + 0x26) / 8000.0; break; + case DC_FIELD_TEMPERATURE_MINIMUM: + *((double *) value) = (signed short) array_uint16_le (p + 0x46) / 10.0; + break; + case DC_FIELD_TEMPERATURE_MAXIMUM: + *((double *) value) = (signed short) array_uint16_le (p + 0x48) / 10.0; + break; default: return DC_STATUS_UNSUPPORTED; } diff --git a/src/mares_nemo_parser.c b/src/mares_nemo_parser.c index 3ec39e1..e226ce6 100644 --- a/src/mares_nemo_parser.c +++ b/src/mares_nemo_parser.c @@ -253,6 +253,9 @@ 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; break; + case DC_FIELD_TEMPERATURE_MINIMUM: + *((double *) value) = (signed char) p[53 - 11]; + break; default: return DC_STATUS_UNSUPPORTED; } @@ -272,6 +275,9 @@ mares_nemo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign case DC_FIELD_GASMIX_COUNT: *((unsigned int *) value) = 0; break; + case DC_FIELD_TEMPERATURE_MINIMUM: + *((double *) value) = (signed char) p[28 - 11]; + break; default: return DC_STATUS_UNSUPPORTED; } diff --git a/src/suunto_vyper_parser.c b/src/suunto_vyper_parser.c index b42a24d..f1dc6ce 100644 --- a/src/suunto_vyper_parser.c +++ b/src/suunto_vyper_parser.c @@ -37,6 +37,7 @@ struct suunto_vyper_parser_t { unsigned int cached; unsigned int divetime; unsigned int maxdepth; + unsigned int marker; }; static dc_status_t suunto_vyper_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size); @@ -75,6 +76,7 @@ suunto_vyper_parser_create (dc_parser_t **out, dc_context_t *context) parser->cached = 0; parser->divetime = 0; parser->maxdepth = 0; + parser->marker = 0; *out = (dc_parser_t*) parser; @@ -101,6 +103,7 @@ suunto_vyper_parser_set_data (dc_parser_t *abstract, const unsigned char *data, parser->cached = 0; parser->divetime = 0; parser->maxdepth = 0; + parser->marker = 0; return DC_STATUS_SUCCESS; } @@ -138,6 +141,7 @@ suunto_vyper_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi if (size < 18) return DC_STATUS_DATAFORMAT; + if (!parser->cached) { unsigned int interval = data[3]; unsigned int nsamples = 0; @@ -161,6 +165,7 @@ suunto_vyper_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi parser->cached = 1; parser->divetime = nsamples * interval; parser->maxdepth = maxdepth; + parser->marker = marker; } dc_gasmix_t *gas = (dc_gasmix_t *) value; @@ -187,6 +192,12 @@ suunto_vyper_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi gas->oxygen = 0.21; gas->nitrogen = 1.0 - gas->oxygen; break; + case DC_FIELD_TEMPERATURE_SURFACE: + *((double *) value) = (signed char) data[8]; + break; + case DC_FIELD_TEMPERATURE_MINIMUM: + *((double *) value) = (signed char) data[parser->marker + 1]; + break; default: return DC_STATUS_UNSUPPORTED; } diff --git a/src/uwatec_memomouse_parser.c b/src/uwatec_memomouse_parser.c index c65cd1a..aa0a432 100644 --- a/src/uwatec_memomouse_parser.c +++ b/src/uwatec_memomouse_parser.c @@ -167,6 +167,9 @@ uwatec_memomouse_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, } gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium; break; + case DC_FIELD_TEMPERATURE_MINIMUM: + *((double *) value) = (signed char) data[15] / 4.0; + break; default: return DC_STATUS_UNSUPPORTED; } diff --git a/src/uwatec_smart_parser.c b/src/uwatec_smart_parser.c index 717688b..37cfa1b 100644 --- a/src/uwatec_smart_parser.c +++ b/src/uwatec_smart_parser.c @@ -46,6 +46,8 @@ #define SMARTZ 0x1C #define MERIDIAN 0x20 +#define UNSUPPORTED 0xFFFFFFFF + typedef enum { PRESSURE_DEPTH, RBT, @@ -65,6 +67,9 @@ typedef struct uwatec_smart_header_info_t { unsigned int divetime; unsigned int gasmix; unsigned int ngases; + unsigned int temp_minimum; + unsigned int temp_maximum; + unsigned int temp_surface; } uwatec_smart_header_info_t; typedef struct uwatec_smart_sample_info_t { @@ -108,42 +113,60 @@ static const uwatec_smart_header_info_t uwatec_smart_pro_header = { 18, 20, - 24, 1 + 24, 1, + 22, /* temp_minimum */ + UNSUPPORTED, /* temp_maximum */ + UNSUPPORTED, /* temp_surface */ }; static const uwatec_smart_header_info_t uwatec_smart_galileo_header = { 22, 26, - 44, 3 + 44, 3, + 30, /* temp_minimum */ + 28, /* temp_maximum */ + 32, /* temp_surface */ }; static const uwatec_smart_header_info_t uwatec_smart_aladin_tec_header = { 22, 24, - 30, 1 + 30, 1, + 26, /* temp_minimum */ + 28, /* temp_maximum */ + 32, /* temp_surface */ }; static const uwatec_smart_header_info_t uwatec_smart_aladin_tec2g_header = { 22, 26, - 34, 3 + 34, 3, + 30, /* temp_minimum */ + 28, /* temp_maximum */ + 32, /* temp_surface */ }; static const uwatec_smart_header_info_t uwatec_smart_com_header = { 18, 20, - 24, 1 + 24, 1, + 22, /* temp_minimum */ + UNSUPPORTED, /* temp_maximum */ + UNSUPPORTED, /* temp_surface */ }; static const uwatec_smart_header_info_t uwatec_smart_tec_header = { 18, 20, - 28, 3 + 28, 3, + 22, /* temp_minimum */ + UNSUPPORTED, /* temp_maximum */ + UNSUPPORTED, /* temp_surface */ }; static const @@ -384,6 +407,19 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi gasmix->oxygen = data[table->gasmix + flags * 2] / 100.0; gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium; break; + case DC_FIELD_TEMPERATURE_MINIMUM: + *((double *) value) = (signed short) array_uint16_le (data + table->temp_minimum) / 10.0; + break; + case DC_FIELD_TEMPERATURE_MAXIMUM: + if (table->temp_maximum == UNSUPPORTED) + return DC_STATUS_UNSUPPORTED; + *((double *) value) = (signed short) array_uint16_le (data + table->temp_maximum) / 10.0; + break; + case DC_FIELD_TEMPERATURE_SURFACE: + if (table->temp_surface == UNSUPPORTED) + return DC_STATUS_UNSUPPORTED; + *((double *) value) = (signed short) array_uint16_le (data + table->temp_surface) / 10.0; + break; default: return DC_STATUS_UNSUPPORTED; }