Skip to content

Heinrichs Weikamp: Log the Remaining Scrubber Time on OSTC 4/5. #80

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: Subsurface-DS9
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 94 additions & 8 deletions src/hw_ostc_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <limits.h>

#ifdef _MSC_VER
#define snprintf _snprintf
Expand Down Expand Up @@ -88,6 +90,12 @@
(((micro) & 0x1F) << 1) | \
((beta) & 0x01))

#define OSTC4_COMPASS_HEADING_CLEARED_FLAG 0x8000
#define OSTC4_COMPASS_HEADING_SET_FLAG 0x4000

#define OSTC4_SCRUBBER_STATE_ERROR_FLAG 0x4000
#define OSTC4_SCRUBBER_STATE_WARNING_FLAG 0x2000

typedef struct hw_ostc_sample_info_t {
unsigned int type;
unsigned int divisor;
Expand Down Expand Up @@ -139,6 +147,10 @@ typedef struct hw_ostc_parser_t {
unsigned int initial_setpoint;
unsigned int initial_cns;
hw_ostc_gasmix_t gasmix[NGASMIXES];
int first_scrubber_time_minutes;
int last_scrubber_time_minutes;
bool scrubber_error_reported;
bool scrubber_warning_reported;
} hw_ostc_parser_t;

static dc_status_t hw_ostc_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
Expand Down Expand Up @@ -438,6 +450,10 @@ hw_ostc_parser_create_internal (dc_parser_t **out, dc_context_t *context, const
parser->gasmix[i].active = 0;
parser->gasmix[i].diluent = 0;
}
parser->first_scrubber_time_minutes = INT_MAX;
parser->last_scrubber_time_minutes = INT_MAX;
parser->scrubber_error_reported = false;
parser->scrubber_warning_reported = false;
parser->serial = serial;

*out = (dc_parser_t *) parser;
Expand Down Expand Up @@ -800,6 +816,22 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
else
return DC_STATUS_DATAFORMAT;
break;
case 6:
if (parser->first_scrubber_time_minutes == INT_MAX) {
return DC_STATUS_DATAFORMAT;
}

string->desc = "Remaining scrubber time at start [minutes]";
snprintf(buf, BUFLEN, "%d", parser->first_scrubber_time_minutes);
break;
case 7:
if (parser->last_scrubber_time_minutes == INT_MAX) {
return DC_STATUS_DATAFORMAT;
}

string->desc = "Remaining scrubber time at end [minutes]";
snprintf(buf, BUFLEN, "%d", parser->last_scrubber_time_minutes);
break;
default:
return DC_STATUS_UNSUPPORTED;
}
Expand Down Expand Up @@ -928,6 +960,7 @@ hw_ostc_parser_internal_foreach (hw_ostc_parser_t *parser, dc_sample_callback_t
unsigned int tank = parser->initial != UNDEFINED ? parser->initial - 1 : 0;

unsigned int offset = header;
char buf[BUFLEN];
if (version == 0x23 || version == 0x24)
offset += 5 + 3 * nconfig;
while (offset + 3 <= size) {
Expand Down Expand Up @@ -1135,30 +1168,83 @@ hw_ostc_parser_internal_foreach (hw_ostc_parser_t *parser, dc_sample_callback_t
// Compass heading update
if (events & 0x0200) {
if (length < 2) {
ERROR (abstract->context, "Buffer overflow detected!");
ERROR (abstract->context, "Buffer underflow detected!");
return DC_STATUS_DATAFORMAT;
}

if (callback) {
unsigned int heading = array_uint16_le(data + offset);
unsigned int value = array_uint16_le(data + offset);
dc_sample_value_t sample = {
.event.type = SAMPLE_EVENT_STRING,
.event.flags = SAMPLE_FLAGS_SEVERITY_INFO,
};

if (heading & 0x8000) {
sample.event.name = "Cleared compass heading";
unsigned int heading = value & 0x1FF;
if (value & OSTC4_COMPASS_HEADING_CLEARED_FLAG) {
snprintf(buf, BUFLEN, "Cleared compass heading");
} else {
if (heading & 0x4000) {
sample.event.value = heading;

if (value & OSTC4_COMPASS_HEADING_SET_FLAG) {
sample.event.type = SAMPLE_EVENT_HEADING;
sample.event.name = "Set compass heading";
snprintf(buf, BUFLEN, "Set compass heading [degrees]%s", sample.event.value ? "" : ": 0");
} else {
sample.event.name = "Logged compass heading";
snprintf(buf, BUFLEN, "Logged compass heading [degrees]%s", sample.event.value ? "" : ": 0");
}

sample.event.value = heading & 0x1FF;
}

sample.event.name = buf;

callback(DC_SAMPLE_EVENT, &sample, userdata);
}

offset += 2;
length -= 2;
}

// Scrubber state update
if (events & 0x0800) {
if (length < 2) {
ERROR (abstract->context, "Buffer underflow detected!");
return DC_STATUS_DATAFORMAT;
}

unsigned int scrubberState = array_uint16_le(data + offset);
int scrubberTimeMinutes = scrubberState & 0x0FFF; // Extract the 12-bit value
if (scrubberState & 0x0800) { // Check if the sign bit is set
scrubberTimeMinutes -= 0x1000; // Perform sign extension
}
if (parser->first_scrubber_time_minutes == INT_MAX) {
parser->first_scrubber_time_minutes = scrubberTimeMinutes;
}
parser->last_scrubber_time_minutes = scrubberTimeMinutes;

if (callback) {
dc_sample_value_t sample = {
.event.type = SAMPLE_EVENT_STRING,
.event.flags = SAMPLE_FLAGS_SEVERITY_STATE,
.event.value = scrubberTimeMinutes,
};

if (scrubberState & OSTC4_SCRUBBER_STATE_ERROR_FLAG) {
if (!parser->scrubber_error_reported) {
sample.event.flags = SAMPLE_FLAGS_SEVERITY_ALARM;
parser->scrubber_error_reported = true;
}
snprintf(buf, BUFLEN, "Scrubber exhausted, time remaining [minutes]%s", sample.event.value ? "" : ": 0");
} else if (scrubberState & OSTC4_SCRUBBER_STATE_WARNING_FLAG) {
if (!parser->scrubber_warning_reported) {
sample.event.flags = SAMPLE_FLAGS_SEVERITY_WARN;
parser->scrubber_warning_reported = true;
}
snprintf(buf, BUFLEN, "Scrubber warning, time remaining [minutes]%s", sample.event.value ? "" : ": 0");
} else {
snprintf(buf, BUFLEN, "Scrubber time remaining [minutes]%s", sample.event.value ? "" : ": 0");
}

sample.event.name = buf;

callback(DC_SAMPLE_EVENT, &sample, userdata);
}

Expand Down
Loading