@yachteye/signalk-engineroom-plugin
Version:
Get EngineRoom data from the source (database or other) and add it to the SignalK graph.
150 lines (149 loc) • 6.88 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const _1 = require(".");
const node_net_1 = __importDefault(require("node:net"));
class TcpData {
constructor(app, settings, hostName, port, definitions) {
this.server = null;
/** The data we have received, keyed by the correct SignalK path. */
this.data = {};
app.debug(`[TcpData] starting for ${hostName}:${port}`);
this.app = app;
this.dataDefinitions = definitions;
this.server = node_net_1.default.createServer({ keepAlive: true }, (socket) => {
// this.data = {};
const socketAddress = JSON.stringify(socket.address());
app.debug('[TcpData] Client connected to socket: ' + socketAddress);
socket.on('data', (data) => {
if (data.length > 0) {
this.addData(data.toString());
}
});
socket.on('end', function () {
app.debug('[TcpData] Client disconnected: ' + socketAddress);
});
socket.on('error', function (err) {
app.error(`[TcpData] Socket error: ${err.message} (${socketAddress})`);
});
});
this.server.on('listening', () => {
app.debug(`[TcpData] tcp server listening on ${hostName}:${port} .`);
});
this.server.on('close', () => {
app.debug('[TcpData] tcp server closes');
});
this.server.on('drop', (data) => {
app.error(`[TcpData] tcp server drop event: ${JSON.stringify(data)}`);
});
this.server.on('error', (e) => {
app.error(`[TcpData] tcp server error: ${e.message}`);
});
this.server.listen(port, hostName);
}
stop() {
if (this.server) {
this.server.close((err) => {
this.server = null;
this.app.debug(`[TcpData] tcp server closed, error:${err === null || err === void 0 ? void 0 : err.message} `);
});
}
this.data = {};
}
/**
* Get the data that has been received over TCP, with fixed vales added.
* @returns Dictionary with data, keyed by the SignalK path.
*/
getData() {
this.app.debug(`[TcpData] getData()`);
// Add any fixed values we have defined.
for (const dataDef of this.dataDefinitions) {
if (dataDef.type === _1.IDataType.Fixed) {
this.data[dataDef.path] = dataDef.fixed === undefined ? 0 : dataDef.fixed;
}
}
return this.data;
}
/**
* Add the data to the internal collection.
* @param data Data to process, e.g. '{Type:2,Unix:1739802466,Key:Power Genset 3 (Genset CNT),Value:0.0,Unit:kW}'.
*/
addData(data) {
const nowSeconds = Date.now() / 1000;
const parts = data.split(',');
if (parts.length === 5) {
const timestampSeconds = parseInt(parts[1], 10);
const keyPart = parts[2];
const key = keyPart.split(':')[1];
const value = parts[3].split(':')[1];
const unitPart = parts[4];
if (nowSeconds - timestampSeconds > 5) {
this.app.debug(`[TcpData] addData(): data seems outdated (${nowSeconds - timestampSeconds}s), timestampSeconds=${timestampSeconds}, now=${nowSeconds} for ${keyPart}`);
}
switch (key.trim()) {
case 'Power POD (Total)':
this.data['yachteye.pod.wattage'] = Number.parseFloat(value) * 1000;
this.assertUnitString(unitPart, 'Unit:kW}', data);
break;
case 'Power PTI/O PS':
this.data['yachteye.pti_pto.ps.wattage'] = Number.parseFloat(value) * 1000;
break;
case 'Power PTI/O SB':
this.data['yachteye.pti_pto.sb.wattage'] = Number.parseFloat(value) * 1000;
break;
case 'Power Multidrive AFT POD':
this.data['yachteye.pod.aft.wattage'] = Number.parseFloat(value) * 1000;
break;
case 'Power Multidrive FWD POD':
this.data['yachteye.pod.fwd.wattage'] = Number.parseFloat(value) * 1000;
break;
case 'Power Input Multidrive AFT':
this.data['yachteye.multiDriveConverter.aft.wattage'] = Number.parseFloat(value) * 1000;
break;
case 'Power Input Multidrive FWD':
this.data['yachteye.multiDriveConverter.fwd.wattage'] = Number.parseFloat(value) * 1000;
break;
case 'Power Genset 1 (Genset SB OUT)':
this.data['yachteye.genset.1.wattage'] = Number.parseFloat(value) * 1000;
this.assertUnitString(unitPart, 'Unit:kW}', data);
break;
case 'Power Genset 2 (Genset SB IN)':
this.data['yachteye.genset.2.wattage'] = Number.parseFloat(value) * 1000;
break;
case 'Power Genset 3 (Genset CNT)':
this.data['yachteye.genset.3.wattage'] = Number.parseFloat(value) * 1000;
break;
case 'Power Genset 4 (Genset PS IN)':
this.data['yachteye.genset.4.wattage'] = Number.parseFloat(value) * 1000;
break;
case 'Power Genset 5 (Genset PS OUT)':
this.data['yachteye.genset.5.wattage'] = Number.parseFloat(value) * 1000;
break;
case 'Power Input MSB 400V AFT':
this.data['yachteye.msb400v.aft.wattage'] = Number.parseFloat(value) * 1000;
break;
case 'Power Input MSB 400V FWD':
this.data['yachteye.msb400v.fwd.wattage'] = Number.parseFloat(value) * 1000;
break;
case 'Total Remaining Fuel':
this.data['yachteye.fuel.remaining'] = Number.parseFloat(value);
this.assertUnitString(unitPart, 'Unit:m3}', data);
break;
default:
this.app.debug(`[TcpData] addData() unexpected key: ${data}`);
break;
}
}
else {
this.app.error(`[TcpData] addData() unexpected data format: ${data}`);
}
}
assertUnitString(input, check, data) {
if (input !== check) {
this.app.error(`[TcpData] assertUnitString() unexpected unit-string: ${input} in ${data}`);
}
}
}
exports.default = TcpData;