signalk-n2k-switching-emulator
Version:
Signal K Plugin which makes existing switches in sk available as n2k switches
179 lines (178 loc) • 8.05 kB
JavaScript
;
/*
* Copyright 2021 Scott Bender <scott@scottbender.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
var ts_pgns_1 = require("@canboat/ts-pgns");
var semver_1 = require("semver");
function default_1(app) {
var error = app.error;
var debug = app.debug;
var props;
var onStop = [];
var switchBanks = {};
var needsCamelMapping = !(0, semver_1.satisfies)(app.config.version, '>=2.15.0');
var plugin = {
start: function (properties) {
props = properties;
if (!(props === null || props === void 0 ? void 0 : props.banks) || !props.banks.length) {
return;
}
props.banks.forEach(function (bank) {
if (!bank.switches || !bank.switches.length) {
return;
}
switchBanks[bank.instance] = bank.switches;
app.subscriptionmanager.subscribe({
context: 'vessels.self',
subscribe: bank.switches.map(function (path) {
return { path: path };
})
}, onStop, function (err) {
error(err);
app.setProviderError(err);
}, function (delta) {
var _a;
var pgn = makeBinaryStatusReport(bank);
(_a = delta.updates) === null || _a === void 0 ? void 0 : _a.forEach(function (update) {
var _a;
(_a = update.values) === null || _a === void 0 ? void 0 : _a.forEach(function (vp) {
;
pgn.fields["indicator".concat(bank.switches.indexOf(vp.path) + 1)] =
vp.value === 1 || vp.value === true ? 'On' : 'Off';
});
});
pgn = needsCamelMapping ? (0, ts_pgns_1.mapCamelCaseKeys)(pgn) : pgn;
debug('sending %j', pgn);
app.emit('nmea2000JsonOut', pgn);
});
if (bank.sendRate) {
var interval_1 = setInterval(function () {
var pgn = makeBinaryStatusReport(bank);
pgn = needsCamelMapping ? (0, ts_pgns_1.mapCamelCaseKeys)(pgn) : pgn;
debug('sending update %j', pgn);
app.emit('nmea2000JsonOut', pgn);
}, bank.sendRate * 1000);
onStop.push(function () { return clearInterval(interval_1); });
}
});
var n2kCallback = function (msg) {
try {
if (msg.pgn == 127502) {
var camel = msg.fields['instance'];
var instance = camel !== undefined ? camel : msg.fields['Instance'];
var paths = switchBanks[instance];
if (paths) {
debug('msg: ' + JSON.stringify(msg));
for (var i = 1; i < 29; i++) {
var lowerVal = msg.fields["switch".concat(i)];
var val = lowerVal !== undefined ? lowerVal : msg.fields["Switch".concat(i)];
if (typeof val !== 'undefined') {
if (paths.length < i - 1) {
error("no path for switch ".concat(i, " bank ").concat(instance));
}
else {
debug("Switch ".concat(i, " ").concat(val));
app.putSelfPath(paths[i - 1], val === 'On' ? 1 : 0);
}
}
}
}
}
}
catch (e) {
error(e);
}
};
app.on('N2KAnalyzerOut', n2kCallback);
onStop.push(function () { return app.removeListener('N2KAnalyzerOut', n2kCallback); });
},
stop: function () {
onStop.forEach(function (f) { return f(); });
onStop = [];
},
id: 'signalk-n2k-switching-emulator',
name: 'NMEA 2000 Siwtching Emulator',
description: 'Signal K Plugin which makes existing switches in sk available as n2k switches',
schema: function () {
var _a;
var paths = app.streambundle.getAvailablePaths()
.filter(function (path) { return path && path.startsWith('electrical.switches.') && path.endsWith('.state'); });
if (props) {
(_a = props.banks) === null || _a === void 0 ? void 0 : _a.forEach(function (bank) {
var _a;
(_a = bank.switches) === null || _a === void 0 ? void 0 : _a.forEach(function (sw) {
if (paths.indexOf(sw) === -1) {
paths.push(sw);
}
});
});
}
paths = paths.sort();
return {
//title: plugin.name,
type: 'object',
properties: {
banks: {
title: 'Banks',
type: 'array',
description: 'N2K bank instances to emulate',
items: {
type: 'object',
properties: {
instance: {
title: 'N2K Bank Instance',
type: 'number',
default: 0
},
sendRate: {
title: 'Send Rate',
type: 'number',
description: 'Rate (in seconds) to send to N2K (set to 0 to not send updates)',
default: 15
},
switches: {
type: 'array',
title: 'Switches',
items: {
title: 'Switch Path',
type: 'string',
enum: paths.length > 0 ? paths : undefined
}
}
}
}
}
}
};
}
};
function makeBinaryStatusReport(bank) {
var _a;
var pgn = new ts_pgns_1.PGN_127501({
instance: bank.instance
});
(_a = bank.switches) === null || _a === void 0 ? void 0 : _a.forEach(function (sw, index) {
var value = app.getSelfPath(sw);
if (value && typeof value.value !== 'undefined') {
;
pgn.fields["indicator".concat(index + 1)] =
value.value === 1 || value.value === true ? 'On' : 'Off';
}
});
return pgn;
}
return plugin;
}
exports.default = default_1;