Skip to content

Commit 2829431

Browse files
committed
Heinrichs Weikamp: Log the Remaining Scrubber Time on OSTC 4/5.
Log the remaining scrubber run time, and warnings and errors when reaching the limits. Also add the compass heading value to compass heading messages. Requires mikeller/ostc4#32 to work. Signed-off-by: Michael Keller <[email protected]>
1 parent f65ef04 commit 2829431

File tree

1 file changed

+90
-8
lines changed

1 file changed

+90
-8
lines changed

src/hw_ostc_parser.c

Lines changed: 90 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include <stdlib.h>
2323
#include <stdio.h>
2424
#include <string.h>
25+
#include <stdbool.h>
26+
#include <limits.h>
2527

2628
#ifdef _MSC_VER
2729
#define snprintf _snprintf
@@ -88,6 +90,12 @@
8890
(((micro) & 0x1F) << 1) | \
8991
((beta) & 0x01))
9092

93+
#define OSTC4_COMPASS_HEADING_CLEARED_FLAG 0x8000
94+
#define OSTC4_COMPASS_HEADING_SET_FLAG 0x4000
95+
96+
#define OSTC4_SCRUBBER_STATE_ERROR_FLAG 0x4000
97+
#define OSTC4_SCRUBBER_STATE_WARNING_FLAG 0x2000
98+
9199
typedef struct hw_ostc_sample_info_t {
92100
unsigned int type;
93101
unsigned int divisor;
@@ -139,6 +147,10 @@ typedef struct hw_ostc_parser_t {
139147
unsigned int initial_setpoint;
140148
unsigned int initial_cns;
141149
hw_ostc_gasmix_t gasmix[NGASMIXES];
150+
int first_scrubber_time_minutes;
151+
int last_scrubber_time_minutes;
152+
bool scrubber_error_reported;
153+
bool scrubber_warning_reported;
142154
} hw_ostc_parser_t;
143155

144156
static dc_status_t hw_ostc_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
@@ -438,6 +450,10 @@ hw_ostc_parser_create_internal (dc_parser_t **out, dc_context_t *context, const
438450
parser->gasmix[i].active = 0;
439451
parser->gasmix[i].diluent = 0;
440452
}
453+
parser->first_scrubber_time_minutes = INT_MAX;
454+
parser->last_scrubber_time_minutes = INT_MAX;
455+
parser->scrubber_error_reported = false;
456+
parser->scrubber_warning_reported = false;
441457
parser->serial = serial;
442458

443459
*out = (dc_parser_t *) parser;
@@ -800,6 +816,22 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
800816
else
801817
return DC_STATUS_DATAFORMAT;
802818
break;
819+
case 6:
820+
if (parser->first_scrubber_time_minutes == INT_MAX) {
821+
return DC_STATUS_DATAFORMAT;
822+
}
823+
824+
string->desc = "Remaining scrubber time at start [minutes]";
825+
snprintf(buf, BUFLEN, "%d", parser->first_scrubber_time_minutes);
826+
break;
827+
case 7:
828+
if (parser->last_scrubber_time_minutes == INT_MAX) {
829+
return DC_STATUS_DATAFORMAT;
830+
}
831+
832+
string->desc = "Remaining scrubber time at end [minutes]";
833+
snprintf(buf, BUFLEN, "%d", parser->last_scrubber_time_minutes);
834+
break;
803835
default:
804836
return DC_STATUS_UNSUPPORTED;
805837
}
@@ -928,6 +960,7 @@ hw_ostc_parser_internal_foreach (hw_ostc_parser_t *parser, dc_sample_callback_t
928960
unsigned int tank = parser->initial != UNDEFINED ? parser->initial - 1 : 0;
929961

930962
unsigned int offset = header;
963+
char buf[BUFLEN];
931964
if (version == 0x23 || version == 0x24)
932965
offset += 5 + 3 * nconfig;
933966
while (offset + 3 <= size) {
@@ -1135,30 +1168,79 @@ hw_ostc_parser_internal_foreach (hw_ostc_parser_t *parser, dc_sample_callback_t
11351168
// Compass heading update
11361169
if (events & 0x0200) {
11371170
if (length < 2) {
1138-
ERROR (abstract->context, "Buffer overflow detected!");
1171+
ERROR (abstract->context, "Buffer underflow detected!");
11391172
return DC_STATUS_DATAFORMAT;
11401173
}
11411174

11421175
if (callback) {
1143-
unsigned int heading = array_uint16_le(data + offset);
1176+
unsigned int value = array_uint16_le(data + offset);
11441177
dc_sample_value_t sample = {
11451178
.event.type = SAMPLE_EVENT_STRING,
11461179
.event.flags = SAMPLE_FLAGS_SEVERITY_INFO,
11471180
};
11481181

1149-
if (heading & 0x8000) {
1150-
sample.event.name = "Cleared compass heading";
1182+
unsigned int heading = value & 0x1FF;
1183+
if (value & OSTC4_COMPASS_HEADING_CLEARED_FLAG) {
1184+
snprintf(buf, BUFLEN, "Cleared compass heading");
11511185
} else {
1152-
if (heading & 0x4000) {
1186+
if (value & OSTC4_COMPASS_HEADING_SET_FLAG) {
11531187
sample.event.type = SAMPLE_EVENT_HEADING;
1154-
sample.event.name = "Set compass heading";
1188+
snprintf(buf, BUFLEN, "Set compass heading %d degrees", heading);
11551189
} else {
1156-
sample.event.name = "Logged compass heading";
1190+
snprintf(buf, BUFLEN, "Logged compass heading %d degrees", heading);
11571191
}
11581192

1159-
sample.event.value = heading & 0x1FF;
1193+
sample.event.value = heading;
1194+
}
1195+
1196+
sample.event.name = buf;
1197+
1198+
callback(DC_SAMPLE_EVENT, &sample, userdata);
1199+
}
1200+
1201+
offset += 2;
1202+
length -= 2;
1203+
}
1204+
1205+
// Scrubber state update
1206+
if (events & 0x0800) {
1207+
if (length < 2) {
1208+
ERROR (abstract->context, "Buffer underflow detected!");
1209+
return DC_STATUS_DATAFORMAT;
1210+
}
1211+
1212+
unsigned int scrubberState = array_uint16_le(data + offset);
1213+
int scrubberTimeMinutes = (scrubberState & 0x0800) ? (-1 ^ 0x0FFF) | (scrubberState & 0x0FFF) : scrubberState & 0x0FFF; // extract 12 bit signed int
1214+
if (parser->first_scrubber_time_minutes == INT_MAX) {
1215+
parser->first_scrubber_time_minutes = scrubberTimeMinutes;
1216+
}
1217+
parser->last_scrubber_time_minutes = scrubberTimeMinutes;
1218+
1219+
if (callback) {
1220+
dc_sample_value_t sample = {
1221+
.event.type = SAMPLE_EVENT_STRING,
1222+
.event.flags = SAMPLE_FLAGS_SEVERITY_STATE,
1223+
};
1224+
1225+
1226+
if (scrubberState & OSTC4_SCRUBBER_STATE_ERROR_FLAG) {
1227+
if (!parser->scrubber_error_reported) {
1228+
sample.event.flags = SAMPLE_FLAGS_SEVERITY_ALARM;
1229+
parser->scrubber_error_reported = true;
1230+
}
1231+
snprintf(buf, BUFLEN, "Scrubber exhausted: %d minutes remaining", scrubberTimeMinutes);
1232+
} else if (scrubberState & OSTC4_SCRUBBER_STATE_WARNING_FLAG) {
1233+
if (!parser->scrubber_warning_reported) {
1234+
sample.event.flags = SAMPLE_FLAGS_SEVERITY_WARN;
1235+
parser->scrubber_warning_reported = true;
1236+
}
1237+
snprintf(buf, BUFLEN, "Scrubber warning: %d minutes remaining", scrubberTimeMinutes);
1238+
} else {
1239+
snprintf(buf, BUFLEN, "Scrubber: %d minutes remaining", scrubberTimeMinutes);
11601240
}
11611241

1242+
sample.event.name = buf;
1243+
11621244
callback(DC_SAMPLE_EVENT, &sample, userdata);
11631245
}
11641246

0 commit comments

Comments
 (0)