RFC: support for deco algorith and parameter fields

Dirk Hohndel dirk at hohndel.org
Thu Oct 16 06:24:31 PDT 2014


Hi Jef,

as "promised", here's another little feature that I frequently get asked
about by some tech divers: show which algorithm / which paramters where
used on a dive. There are quite a few dive computers for which we can
return at least some viable data (I almost apologize for the last patch in
the series... technically it is correct, and I think adding it makes it
simpler for consumers of libdivecomputer to use this API).

I'm calling this an RFC because I want feedback if this is the right API...
this was straight forward to do, but I wonder if you would prefer a complex
data structure and a single API entry point:

DC_FIELD_DECO_INFO

and

struct dc_deco_information_t {
	unsigned int algo;
	unsigned int param1; /* e.g. GFhigh or GFS */
	unsigned int param2; /* e.g. GFlow */
	unsigned int param3; /* currently unused */
};

/D

-------------- next part --------------
>From 75a158f57d221d43c506af62cdb6d84fbd0be110 Mon Sep 17 00:00:00 2001
From: Dirk Hohndel <dirk at hohndel.org>
Date: Thu, 16 Oct 2014 15:04:20 +0200
Subject: [PATCH 1/5] Add support for deco algorithm and parameters fields

This is fairly frequently requested by tech divers. Some of the tech dive
computers (Shearwater, OSTC) and even some more recreationally targeted
dive computers like the Aeris A300CS allow us to learn which deco
algorithm was used during a dive and return that information (and in some
cases even further parameters for these algorithms).

Signed-off-by: Dirk Hohndel <dirk at hohndel.org>
---
 include/libdivecomputer/parser.h | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/include/libdivecomputer/parser.h b/include/libdivecomputer/parser.h
index 65b18c9bb2fe..3a93268b5703 100644
--- a/include/libdivecomputer/parser.h
+++ b/include/libdivecomputer/parser.h
@@ -53,7 +53,10 @@ typedef enum dc_field_type_t {
 	DC_FIELD_GASMIX_COUNT,
 	DC_FIELD_GASMIX,
 	DC_FIELD_SALINITY,
-	DC_FIELD_ATMOSPHERIC
+	DC_FIELD_ATMOSPHERIC,
+	DC_FIELD_DECO_ALG,
+	DC_FIELD_DECO_GFLOW,
+	DC_FIELD_DECO_GFHIGH,
 } dc_field_type_t;
 
 typedef enum parser_sample_event_t {
@@ -117,6 +120,16 @@ typedef enum dc_deco_type_t {
 	DC_DECO_DEEPSTOP
 } dc_deco_type_t;
 
+typedef enum dc_deco_alg_t {
+	DC_DECO_ALG_UNKNOWN,
+	DC_DECO_ALG_BZH,    /* Buehlmann ZH, no GF */
+	DC_DECO_ALG_BZHGF,  /* Buehlmann ZH, with GF */
+	DC_DECO_ALG_VPM,    /* VPM */
+	DC_DECO_ALG_VPMGFS, /* VPM with GF surface */
+	DC_DECO_ALG_DSAT,   /* Aeris DSAT */
+	DC_DECO_RGBM,       /* Suunto fused RGBM */
+} dc_deco_alg_t;
+
 typedef struct dc_salinity_t {
 	dc_water_t type;
 	double density;
-- 
1.8.0.rc0.18.gf84667d

-------------- next part --------------
>From 995ed21f525ec9156f1f41cb0612b7c1e428548e Mon Sep 17 00:00:00 2001
From: Dirk Hohndel <dirk at hohndel.org>
Date: Thu, 16 Oct 2014 15:06:21 +0200
Subject: [PATCH 2/5] Implement deco algorithm and parameter fields for
 OSTC2/3

Signed-off-by: Dirk Hohndel <dirk at hohndel.org>
---
 src/hw_ostc_parser.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/src/hw_ostc_parser.c b/src/hw_ostc_parser.c
index 8fb8875e85fb..b279040b0f60 100644
--- a/src/hw_ostc_parser.c
+++ b/src/hw_ostc_parser.c
@@ -53,6 +53,9 @@ typedef struct hw_ostc_layout_t {
 	unsigned int atmospheric;
 	unsigned int salinity;
 	unsigned int duration;
+	unsigned int deco_alg;
+	unsigned int gflow;
+	unsigned int gfhigh;
 } hw_ostc_layout_t;
 
 typedef struct hw_ostc_gasmix_t {
@@ -82,6 +85,9 @@ static const hw_ostc_layout_t hw_ostc_layout_ostc = {
 	15, /* atmospheric */
 	43, /* salinity */
 	47, /* duration */
+	51, /* deco alg */
+	49, /* GF low */
+	50, /* GF high */
 };
 
 static const hw_ostc_layout_t hw_ostc_layout_frog = {
@@ -91,6 +97,9 @@ static const hw_ostc_layout_t hw_ostc_layout_frog = {
 	21, /* atmospheric */
 	43, /* salinity */
 	47, /* duration */
+	-1, /* deco alg */
+	-1, /* GF low */
+	-1, /* GF high */
 };
 
 static const hw_ostc_layout_t hw_ostc_layout_ostc3 = {
@@ -100,6 +109,9 @@ static const hw_ostc_layout_t hw_ostc_layout_ostc3 = {
 	24, /* atmospheric */
 	70, /* salinity */
 	75, /* duration */
+	79, /* deco alg */
+	77, /* GF low */
+	78, /* GF high */
 };
 
 dc_status_t
@@ -259,7 +271,10 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
 
 	dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
 	dc_salinity_t *water = (dc_salinity_t *) value;
+	dc_deco_alg_t *deco_alg = (dc_deco_alg_t *) value;
+	unsigned int *gf = (unsigned int *) value;
 	unsigned int salinity = data[layout->salinity];
+	unsigned char alg;
 	if (version == 0x23)
 		salinity += 100;
 
@@ -306,6 +321,45 @@ 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_DECO_ALG:
+			if (layout->deco_alg == -1 || header ==47)
+				return DC_STATUS_UNSUPPORTED;
+			alg = data[layout->deco_alg];
+			if (header == 57) {
+				if (alg == 0 || alg == 2)
+					*deco_alg = DC_DECO_ALG_BZH;
+				else if (alg == 4 || alg == 5)
+					*deco_alg = DC_DECO_ALG_BZHGF;
+				else if (alg == 1 || alg == 3)
+					*deco_alg = DC_DECO_ALG_UNKNOWN;
+				else
+					return DC_STATUS_DATAFORMAT;
+			} else if (header == 256) { // this is just the OSTC3 - Frog had deco_alg == -1
+				if (alg == 0)
+					*deco_alg = DC_DECO_ALG_BZH;
+				else if (alg == 1)
+					*deco_alg = DC_DECO_ALG_BZHGF;
+				else
+					return DC_STATUS_DATAFORMAT;
+			} else {
+				return DC_STATUS_UNSUPPORTED;
+			}
+			break;
+		case DC_FIELD_DECO_GFLOW:
+		case DC_FIELD_DECO_GFHIGH:
+			if (layout->deco_alg == -1 || header ==47)
+				return DC_STATUS_UNSUPPORTED;
+			alg = data[layout->deco_alg];
+			if ((header == 57 && (alg == 4 || alg == 5)) ||
+			    (header == 256 && alg == 1)) {
+				if (type == DC_FIELD_DECO_GFLOW)
+					*gf = data[layout->gflow];
+				else
+					*gf = data[layout->gfhigh];
+			} else {
+				return DC_STATUS_UNSUPPORTED;
+			}
+			break;
 		default:
 			return DC_STATUS_UNSUPPORTED;
 		}
-- 
1.8.0.rc0.18.gf84667d

-------------- next part --------------
>From e4ef3931a664bc38477ecf4e2a9490ff7c0a1ddd Mon Sep 17 00:00:00 2001
From: Dirk Hohndel <dirk at hohndel.org>
Date: Thu, 16 Oct 2014 15:06:59 +0200
Subject: [PATCH 3/5] Implement deco algorithm and parameter fields for
 Shearwater

Signed-off-by: Dirk Hohndel <dirk at hohndel.org>
---
 src/shearwater_predator_parser.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c
index 62d94bbacd37..0f0b0cde747f 100644
--- a/src/shearwater_predator_parser.c
+++ b/src/shearwater_predator_parser.c
@@ -190,6 +190,8 @@ shearwater_predator_parser_get_field (dc_parser_t *abstract, dc_field_type_t typ
 	dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
 	dc_salinity_t *water = (dc_salinity_t *) value;
 	unsigned int density = 0;
+	dc_deco_alg_t *deco_alg = (dc_deco_alg_t *) value;
+	unsigned int *gf = (unsigned int *) value;
 
 	if (value) {
 		switch (type) {
@@ -221,6 +223,35 @@ shearwater_predator_parser_get_field (dc_parser_t *abstract, dc_field_type_t typ
 		case DC_FIELD_ATMOSPHERIC:
 			*((double *) value) = array_uint16_be (data + 47) / 1000.0;
 			break;
+		case DC_FIELD_DECO_ALG:
+			switch(data[67]) {
+			case 0:
+				*deco_alg = DC_DECO_ALG_BZHGF;
+				break;
+			case 1:
+				*deco_alg = DC_DECO_ALG_VPM;
+				break;
+			case 2:
+				*deco_alg = DC_DECO_ALG_VPMGFS;
+				break;
+			default:
+				return DC_STATUS_DATAFORMAT;
+			}
+			break;
+		case DC_FIELD_DECO_GFHIGH:
+			if (data[67] == 0)
+				*gf = data[5];
+			else if (data[67] == 2)
+				*gf = data[85];
+			else
+				return DC_STATUS_UNSUPPORTED;
+			break;
+		case DC_FIELD_DECO_GFLOW:
+			if (data[67] == 0)
+				*gf = data[4];
+			else
+				return DC_STATUS_UNSUPPORTED;
+			break;
 		default:
 			return DC_STATUS_UNSUPPORTED;
 		}
-- 
1.8.0.rc0.18.gf84667d

-------------- next part --------------
>From c32d5379e017cd7854937036f8fbc8808bdff39c Mon Sep 17 00:00:00 2001
From: Dirk Hohndel <dirk at hohndel.org>
Date: Thu, 16 Oct 2014 15:07:43 +0200
Subject: [PATCH 4/5] Implement deco algorithm field for Aeris A300CS

Signed-off-by: Dirk Hohndel <dirk at hohndel.org>
---
 src/oceanic_atom2_parser.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c
index baf137439a84..1ab16782094e 100644
--- a/src/oceanic_atom2_parser.c
+++ b/src/oceanic_atom2_parser.c
@@ -409,6 +409,16 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns
 				return DC_STATUS_UNSUPPORTED;
 			}
 			break;
+		case DC_FIELD_DECO_ALG:
+			if (parser->model == A300CS) {
+				if (data[0x18] & 0x20)
+					*((unsigned int *) value) = DC_DECO_ALG_BZH;
+				else
+					*((unsigned int *) value) = DC_DECO_ALG_DSAT;
+			} else {
+				return DC_STATUS_UNSUPPORTED;
+			}
+			break;
 		default:
 			return DC_STATUS_UNSUPPORTED;
 		}
-- 
1.8.0.rc0.18.gf84667d

-------------- next part --------------
>From c6e045bb7060b421adbf2b44388ebe72229b68d8 Mon Sep 17 00:00:00 2001
From: Dirk Hohndel <dirk at hohndel.org>
Date: Thu, 16 Oct 2014 15:16:15 +0200
Subject: [PATCH 5/5] Implement deco algorithm field for Suunto dive computers

All Suunto dive computers use RGBM.
Arguably this is slightly redundant - but it should make things easier for
an aplication trying to display the deco algorithm used.

Signed-off-by: Dirk Hohndel <dirk at hohndel.org>
---
 src/suunto_d9_parser.c       | 3 +++
 src/suunto_eon_parser.c      | 3 +++
 src/suunto_solution_parser.c | 3 +++
 src/suunto_vyper_parser.c    | 3 +++
 4 files changed, 12 insertions(+)

diff --git a/src/suunto_d9_parser.c b/src/suunto_d9_parser.c
index 63c6d0cbbdfd..1782618534cb 100644
--- a/src/suunto_d9_parser.c
+++ b/src/suunto_d9_parser.c
@@ -326,6 +326,9 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
 			gasmix->oxygen = parser->oxygen[flags] / 100.0;
 			gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
 			break;
+		case DC_FIELD_DECO_ALG:
+			*((unsigned int *) value) = DC_DECO_RGBM;
+			break;
 		default:
 			return DC_STATUS_UNSUPPORTED;
 		}
diff --git a/src/suunto_eon_parser.c b/src/suunto_eon_parser.c
index f89fe2aeef2c..a2301f28b82e 100644
--- a/src/suunto_eon_parser.c
+++ b/src/suunto_eon_parser.c
@@ -197,6 +197,9 @@ suunto_eon_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
 				gasmix->oxygen = 0.21;
 			gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
 			break;
+		case DC_FIELD_DECO_ALG:
+			*((unsigned int *) value) = DC_DECO_RGBM;
+			break;
 		default:
 			return DC_STATUS_UNSUPPORTED;
 		}
diff --git a/src/suunto_solution_parser.c b/src/suunto_solution_parser.c
index 0d9e9783259f..4f8af99dbfa8 100644
--- a/src/suunto_solution_parser.c
+++ b/src/suunto_solution_parser.c
@@ -163,6 +163,9 @@ suunto_solution_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, u
 			gasmix->oxygen = 0.21;
 			gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
 			break;
+		case DC_FIELD_DECO_ALG:
+			*((unsigned int *) value) = DC_DECO_RGBM;
+			break;
 		default:
 			return DC_STATUS_UNSUPPORTED;
 		}
diff --git a/src/suunto_vyper_parser.c b/src/suunto_vyper_parser.c
index b42a24dad4b5..efb02a7362a9 100644
--- a/src/suunto_vyper_parser.c
+++ b/src/suunto_vyper_parser.c
@@ -187,6 +187,9 @@ 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_DECO_ALG:
+			*((unsigned int *) value) = DC_DECO_RGBM;
+			break;
 		default:
 			return DC_STATUS_UNSUPPORTED;
 		}
-- 
1.8.0.rc0.18.gf84667d



More information about the devel mailing list