signalk-server
Version:
An implementation of a [Signal K](http://signalk.org) server for boats.
207 lines • 6.93 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Alarm = void 0;
const server_api_1 = require("@signalk/server-api");
const notificationManager_1 = require("./notificationManager");
class Alarm {
external = false; // true when alarm was created from delta
status = {
silenced: false,
acknowledged: false,
canSilence: true,
canAcknowledge: true,
canClear: false
};
context = '';
update = {
values: [],
$source: 'notificationsApi',
timestamp: undefined,
notificationId: undefined
};
path = '';
value = {
state: server_api_1.ALARM_STATE.normal,
method: [server_api_1.ALARM_METHOD.visual, server_api_1.ALARM_METHOD.sound],
message: '',
status: this.status
};
constructor(notificationId) {
if (notificationId) {
this.timeStamp();
this.status.canClear = true;
this.update.notificationId = notificationId;
this.path = `notifications.${notificationId}`;
}
}
/**
* Extract and populate attributes from update and context
*/
parseDelta(update, context) {
this.context = context;
this.update = update;
if ((0, server_api_1.hasValues)(this.update)) {
this.path = this.update.values[0].path;
// ensure value is not empty
if (this.update.values[0].value) {
this.value = this.update.values[0].value;
}
else {
this.value.message = '';
this.value.method = [];
this.value.state = server_api_1.ALARM_STATE.normal;
}
}
}
/**
* Align notification alarm method with state and recorded user action
*/
alignAlarmMethod() {
if (this.status.acknowledged) {
if (this.value.state === 'emergency') {
this.value.method = [server_api_1.ALARM_METHOD.visual];
}
else {
this.value.method = [];
}
}
else if (this.status.silenced) {
if (this.value.state !== 'emergency') {
this.value.method = this.value.method?.filter((i) => i !== 'sound');
}
}
}
/** Update the timestamp to the current date / time */
timeStamp() {
this.update.timestamp = new Date().toISOString();
}
/**
* Create / update alarm from incoming update and context
*/
syncFromNotificationUpdate(update, context) {
this.external = true;
this.status.canClear = false;
const prevState = this.value?.state;
this.parseDelta(update, context);
if (prevState === server_api_1.ALARM_STATE.normal &&
this.value.state !== server_api_1.ALARM_STATE.normal) {
this.status.acknowledged = false;
this.status.silenced = false;
}
if (!this.status.acknowledged &&
this.value &&
'acknowledgeStatus' in this.value) {
this.status.acknowledged =
this.value.acknowledgeStatus === 'Yes' ? true : false;
}
if (!this.status.silenced &&
this.value &&
'temporarySilenceStatus' in this.value) {
this.status.silenced =
this.value.temporarySilenceStatus === 'Yes' ? true : false;
}
if (this.value && 'temporarySilenceSupport' in this.value) {
this.status.canSilence =
this.value.temporarySilenceSupport === 'Yes' ? true : false;
}
if (this.value && 'acknowledgeSupport' in this.value) {
this.status.canAcknowledge =
this.value.acknowledgeSupport === 'Yes' ? true : false;
}
this.alignAlarmMethod();
}
setContext(context) {
this.context = context;
}
/**
* Returns true if Alarm is external (generated from incoming Delta message)
*/
get isExternal() {
return this.external;
}
/**
* Generates and returns the delta payload for use with `handleMessage()`
*/
get delta() {
if ((0, server_api_1.hasValues)(this.update)) {
this.update.values = [
{
path: this.path,
value: this.value
? Object.assign(this.value, { id: this.update.notificationId }, { status: this.status })
: this.value
}
];
}
// Strip the original source metadata so handleMessage does not
// create a phantom N2K device entry under the notificationApi label.
// The $source field is sufficient for delta routing.
const { source: _source, ...updateWithoutSource } = this.update;
const d = { updates: [updateWithoutSource] };
if (this.external) {
d.context = this.context;
}
return d;
}
/** Return Alarm properties */
get properties() {
return {
context: this.context,
path: this.path,
value: this.value
};
}
/**
* Return the external key (context/path/$source) of an alarm generated from incoming Delta.
*/
get extKey() {
return (0, notificationManager_1.buildKey)(this.context, this.path, this.update.$source);
}
/**
* Sets the path associated with the alarm.
*/
setPath(path, id) {
if (path) {
path = path.startsWith('notifications.')
? path
: `notifications.${path}`;
this.path = id ? `${path}.${id}` : path;
}
}
silence() {
if (!this.status.canSilence) {
throw new Error('Alarm cannot be silenced!');
}
if (this.status.silenced || this.status.acknowledged) {
throw new Error('Alarm already silenced or acknowledged!');
}
if (this.value.state === 'emergency') {
throw new Error('Cannot silence Emergency Alarm!');
}
this.status.silenced = true;
this.alignAlarmMethod();
this.timeStamp();
}
acknowledge() {
if (!this.status.canAcknowledge) {
throw new Error('Alarm cannot be acknowledged!');
}
if (this.status.acknowledged) {
throw new Error('Alarm already acknowledged!');
}
this.status.acknowledged = true;
this.alignAlarmMethod();
this.timeStamp();
}
clear() {
if (!this.status.canClear) {
throw new Error('Alarm cannot be cleared!');
}
this.value.state = server_api_1.ALARM_STATE.normal;
this.status.silenced = false;
this.status.acknowledged = false;
this.timeStamp();
}
}
exports.Alarm = Alarm;
//# sourceMappingURL=alarm.js.map