signalk-server
Version:
An implementation of a [Signal K](http://signalk.org) server for boats.
102 lines (101 loc) • 3.17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Zones = void 0;
const debug_1 = require("./debug");
const debug = (0, debug_1.createDebug)('signalk-server:zones');
class Zones {
streambundle;
sendDelta;
unsubscribesForPaths = {};
constructor(streambundle, sendDelta) {
this.streambundle = streambundle;
this.sendDelta = sendDelta;
streambundle.getSelfMetaBus().onValue((metaMessage) => {
debug(`${JSON.stringify(metaMessage)}`);
const { path, value } = metaMessage;
//send normal notification to clear out any previous notification
//when zones field is reset
if (value.zones === null) {
this.sendNormalDelta(path);
return;
}
if (value.zones) {
this.watchForZones(path, value.zones, value);
}
});
}
sendNormalDelta(path) {
this.sendDelta({
updates: [
{
values: [
{
path: `notifications.${path}`,
value: { state: 'normal', method: [] }
}
]
}
]
});
}
watchForZones(path, zones, methods) {
if (this.unsubscribesForPaths[path]) {
this.unsubscribesForPaths[path]();
}
const tests = zones.map((zone) => {
const { upper = Infinity, lower = -Infinity } = zone;
return (value) => {
return typeof value === 'number' && value < upper && value >= lower;
};
});
this.unsubscribesForPaths[path] = this.streambundle
.getSelfStream(path)
.map((value) => {
if (value === null) {
return -1;
}
const zoneIndex = tests.findIndex((test) => test(value));
return zoneIndex;
})
.skipDuplicates()
.onValue((zoneIndex) => {
if (debug.enabled) {
debug(`Notify: ${path}, zone ${zoneIndex}`);
}
this.sendDelta(getNotificationDelta(path, zoneIndex, zones, methods));
});
}
}
exports.Zones = Zones;
function getNotificationDelta(path, zoneIndex, zones, methods) {
let value = null;
if (zoneIndex >= 0) {
const { lower, upper, state, message } = zones[zoneIndex];
const methodName = `${state}Method`;
value = {
state: state,
message: message || `${lower} < value < ${upper}`,
method: methods[methodName] || ['visual']
};
}
else {
// Default to "normal" zone
value = {
state: 'normal',
message: 'Value is within normal range',
method: []
};
}
return {
updates: [
{
values: [
{
path: `notifications.${path}`,
value: value
}
]
}
]
};
}