@yachteye/signalk-engineroom-plugin
Version:
Get EngineRoom data from the source (database or other) and add it to the SignalK graph.
579 lines (578 loc) • 84.6 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.IDataType = void 0;
const simulator_1 = __importDefault(require("./simulator"));
const sql_1 = __importDefault(require("./sql"));
const tcp_1 = __importDefault(require("./tcp"));
const utils = require('@signalk/nmea0183-utilities');
var IDataType;
(function (IDataType) {
/** Floating point number. */
IDataType["Number"] = "number";
/** Value between 0 (0%) and 1 (100%) unless specified otherwise. */
IDataType["Ratio"] = "ratio";
/** values 'Running' or 'Off'. */
IDataType["RunningOff"] = "running_off";
/** Fixed value. */
IDataType["Fixed"] = "fixed-value";
/** Integer number. */
IDataType["IntegerNumber"] = "integer-number";
/** Decreasing floating point number that gradually decreases. */
IDataType["NumberDecreasing"] = "number-decreasing";
/** Integer status value that should rotate through the values between min/max slowly. */
IDataType["IntegerStatus"] = "integer-status";
/** To be used for complex derived/calculated data. */
IDataType["Other"] = "other";
})(IDataType || (exports.IDataType = IDataType = {}));
/** The type of Engine Room to handle. */
var IEngineRoomType;
(function (IEngineRoomType) {
IEngineRoomType["Type13758"] = "13758";
IEngineRoomType["Type13774"] = "13774";
})(IEngineRoomType || (IEngineRoomType = {}));
/**
* YachtEye Engine Room Plugin.
* @param {*} app The SignalK app.
* @returns The plugin object.
*/
module.exports = (app) => {
const plugin = {
id: 'signalk-engineroom-plugin',
name: 'YachtEye EngineRoom plugin',
restartPlugin: null,
intervalTimer: null,
simulator: null,
unsubscribes: [],
valueHistory: {},
sqlDB: null,
amcs: null,
lastRawData: {
date: -1,
data: {},
},
dataDefinitions: [
// GENSET: port, starboard, midship
// yachteye.genset.[id].rpm → Hz
// Sean Feehan - Chief Engineer - M/Y KISMET: The Generator permanently runs at 1500RPM, so I think a Max of 2000RPM would display a bit better.
// @todo: decide what we want to show for RPM (e.g. average?).
{ path: 'yachteye.genset.port.rpm', type: 'number', unit: 'Hz', min: 0, max: 2000, fractionDigits: 0, displayNameDb: 'GENSET PS ENGINE SPEED' },
{ path: 'yachteye.genset.starboard.rpm', type: 'number', unit: 'Hz', min: 0, max: 2000, fractionDigits: 0, displayNameDb: 'GENSET SB ENGINE SPEED' },
{ path: 'yachteye.genset.midship.rpm', type: 'number', unit: 'Hz', min: 0, max: 2000, fractionDigits: 0, displayNameDb: 'GENSET CT ENGINE SPEED' },
{ path: 'yachteye.genset.rpm', type: 'number', unit: 'Hz', min: 0, max: 2000, fractionDigits: 0, displayNameDb: 'N.A. AVG' },
// yachteye.genset.[id].wattage
// Sean Feehan - Chief Engineer - M/Y KISMET: Maximum will be 724kw, so a Max of 775/800kW would be good for the display.
{ path: 'yachteye.genset.port.wattage', type: 'number', unit: 'W', min: 0, max: 800 * 1000, fractionDigits: 0, displayNameDb: 'PMS GENSET PS GENERATOR POWER' },
{ path: 'yachteye.genset.starboard.wattage', type: 'number', unit: 'W', min: 0, max: 800 * 1000, fractionDigits: 0, displayNameDb: 'PMS GENSET SB GENERATOR POWER' },
{ path: 'yachteye.genset.midship.wattage', type: 'number', unit: 'W', min: 0, max: 800 * 1000, fractionDigits: 0, displayNameDb: 'PMS GENSET CT GENERATOR POWER' },
{ path: 'yachteye.genset.wattage', type: 'number', unit: 'W', min: 0, max: 3 * 800 * 1000, fractionDigits: 0, displayNameDb: 'N.A. SUM' },
// yachteye.genset.[id].state → “running” or “off”
{ path: 'yachteye.genset.port.state', type: 'running_off', displayNameDb: 'GENSET PS ENGINE RUNNING' },
{ path: 'yachteye.genset.starboard.state', type: 'running_off', displayNameDb: 'GENSET SB ENGINE RUNNING' },
{ path: 'yachteye.genset.midship.state', type: 'running_off', displayNameDb: 'GENSET CT ENGINE RUNNING' },
// yachteye.genset.[id].voltage → V
{ path: 'yachteye.genset.port.voltage', type: 'number', unit: 'V', min: 0, max: 500, fractionDigits: 0, displayNameDb: 'PMS GENSET PS GENERATOR VOLTAGE' },
{ path: 'yachteye.genset.starboard.voltage', type: 'number', unit: 'V', min: 0, max: 500, fractionDigits: 0, displayNameDb: 'PMS GENSET SB GENERATOR VOLTAGE' },
{ path: 'yachteye.genset.midship.voltage', type: 'number', unit: 'V', min: 0, max: 500, fractionDigits: 0, displayNameDb: 'PMS GENSET CT GENERATOR VOLTAGE' },
{ path: 'yachteye.genset.voltage', type: 'number', unit: 'V', min: 0, max: 500, fractionDigits: 0, displayNameDb: 'N.A. AVG' },
// yachteye.genset.[id].current → A
// Note: we also have L2 and L3 values.
// Tim Schroeder (Luerssen): L1, L2 and L3 are pretty much the same. But not sure if this is on any interest as I think the total current might be the best?
// Sean Feehan - Chief Engineer - M/Y KISMET: 1000A would be a more sensible maximum here.
{ path: 'yachteye.genset.port.current', type: 'number', unit: 'A', min: 0, max: 1000, fractionDigits: 0, displayNameDb: 'PMS GENSET PS GENERATOR CURRENT L1' },
{ path: 'yachteye.genset.starboard.current', type: 'number', unit: 'A', min: 0, max: 1000, fractionDigits: 0, displayNameDb: 'PMS GENSET SB GENERATOR CURRENT L1' },
{ path: 'yachteye.genset.midship.current', type: 'number', unit: 'A', min: 0, max: 1000, fractionDigits: 0, displayNameDb: 'PMS GENSET CT GENERATOR CURRENT L1' },
{ path: 'yachteye.genset.current', type: 'number', unit: 'A', min: 0, max: 3 * 1000, fractionDigits: 0, displayNameDb: 'N.A. SUM' },
// yachteye.genset.[id].sineWaveFrequency → Hz
// Sean Feehan - Chief Engineer - M/Y KISMET: 50Hz is the permanent frequency here. A 55Hz maximum should display quite nicely.
{ path: 'yachteye.genset.port.sineWaveFrequency', type: 'number', unit: 'Hz', min: 0, max: 55, fractionDigits: 2, displayNameDb: 'PMS GENSET PS GENERATOR FREQUENCY' },
{ path: 'yachteye.genset.starboard.sineWaveFrequency', type: 'number', unit: 'Hz', min: 0, max: 55, fractionDigits: 2, displayNameDb: 'PMS GENSET SB GENERATOR FREQUENCY' },
{ path: 'yachteye.genset.midship.sineWaveFrequency', type: 'number', unit: 'Hz', min: 0, max: 55, fractionDigits: 2, displayNameDb: 'PMS GENSET CT GENERATOR FREQUENCY' },
{ path: 'yachteye.genset.sineWaveFrequency', type: 'number', unit: 'Hz', min: 0, max: 55, fractionDigits: 2, displayNameDb: 'N.A. AVG' },
// yachteye.genset.[id].wasteHeatRecoveryTemperature → K
// @todo: Not found in the database.
// { path: 'yachteye.genset.port.wasteHeatRecoveryTemperature', type: 'number', unit: 'K', min: utils.transform(40, 'C', 'K'), max: utils.transform(85, 'C', 'K'), fractionDigits: 1, displayNameDb: 'TODO' },
// { path: 'yachteye.genset.starboard.wasteHeatRecoveryTemperature', type: 'number', unit: 'K', min: utils.transform(40, 'C', 'K'), max: utils.transform(85, 'C', 'K'), fractionDigits: 1, displayNameDb: 'TODO' },
// { path: 'yachteye.genset.midship.wasteHeatRecoveryTemperature', type: 'number', unit: 'K', min: utils.transform(40, 'C', 'K'), max: utils.transform(85, 'C', 'K'), fractionDigits: 1, displayNameDb: 'TODO' },
// ENGINE: port, starboard
// yachteye.engine.[id].state → “running” or “off”
{ path: 'yachteye.engine.port.state', type: 'running_off', displayNameDb: 'M/E PS RUNNING' },
{ path: 'yachteye.engine.starboard.state', type: 'running_off', displayNameDb: 'M/E SB RUNNING' },
// yachteye.engine.[id].rpm → Hz
// Sean Feehan - Chief Engineer - M/Y KISMET: A Max of 2000RPM would display a bit better. Typical Main Engine RPM is 950-1500RPM.
{ path: 'yachteye.engine.port.rpm', type: 'number', unit: 'Hz', min: 0, max: 2000, fractionDigits: 0, displayNameDb: 'M/E PS ENGINE SPEED' },
{ path: 'yachteye.engine.starboard.rpm', type: 'number', unit: 'Hz', min: 0, max: 2000, fractionDigits: 0, displayNameDb: 'M/E SB ENGINE SPEED' },
// yachteye.engine.[id].load → ratio (%)
{ path: 'yachteye.engine.port.load', type: 'ratio', unit: '%', displayNameDb: 'M/E PS ENGINE LOAD' },
{ path: 'yachteye.engine.starboard.load', type: 'ratio', unit: '%', displayNameDb: 'M/E SB ENGINE LOAD' },
// yachteye.engine.[id].coolantTemperature → K
// Sean Feehan - Chief Engineer - M/Y KISMET: 105/110°C would be a more sensible maximum here.
{ path: 'yachteye.engine.port.coolantTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(105, 'C', 'K'), fractionDigits: 1, displayNameDb: 'M/E PS COOLANT TEMP' },
{ path: 'yachteye.engine.starboard.coolantTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(105, 'C', 'K'), fractionDigits: 1, displayNameDb: 'M/E SB COOLANT TEMP' },
// yachteye.engine.[id].exhaustTemperature → K
// Sean Feehan - Chief Engineer - M/Y KISMET: There is one Average Field for each main engine that gives an Average Exhaust Temperature Value. Please use that reading. The displayed maximum for this should be somewhere around 700°C.
{ path: 'yachteye.engine.port.exhaustTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(700, 'C', 'K'), fractionDigits: 1, displayNameDb: 'M/E PS EXHAUST AVERAGE TEMP' },
{ path: 'yachteye.engine.starboard.exhaustTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(700, 'C', 'K'), fractionDigits: 1, displayNameDb: 'M/E SB EXHAUST AVERAGE TEMP' },
// ESS (Energy Storage System).
// The 'yachteye.ess.wattage' will be calculated from Voltage and Current values.
{ path: 'yachteye.ess.wattage', type: IDataType.Number, unit: 'W', min: 600 * 6 * -80, max: 700 * 6 * 150, displayNameDb: 'N.A. PRODUCT' },
// Not found in the database, we will use a fixed value.
// Sean Feehan - Chief Engineer - M/Y KISMET: Total Capacity is ~500kWh.
{ path: 'yachteye.ess.capacity', type: IDataType.Fixed, unit: 'Wh', fixed: 500 * 1000, displayNameDb: 'N.A. FIXED' },
// @todo: there are 34 ESS voltage value, which one? (WHERE CONVERT(VARCHAR(MAX), [DisplayName]) LIKE '% ESS %' AND [Unit] = 'V').
// Sean Feehan - Chief Engineer - M/Y KISMET: You can put 600-700V as the range for this. It might also be worth noting that this is DC voltage as opposed to AC. So e.g. could read: 650V DC.
{ path: 'yachteye.ess.port.1.voltage', type: 'number', unit: 'V', min: 600, max: 700, fractionDigits: 0, displayNameDb: 'MD CONVERTER 2 PS ESS PACK 1 PACK VOLTAGE' },
{ path: 'yachteye.ess.port.2.voltage', type: 'number', unit: 'V', min: 600, max: 700, fractionDigits: 0, displayNameDb: 'MD CONVERTER 2 PS ESS PACK 2 PACK VOLTAGE' },
{ path: 'yachteye.ess.port.3.voltage', type: 'number', unit: 'V', min: 600, max: 700, fractionDigits: 0, displayNameDb: 'MD CONVERTER 2 PS ESS PACK 3 PACK VOLTAGE' },
{ path: 'yachteye.ess.starboard.1.voltage', type: 'number', unit: 'V', min: 600, max: 700, fractionDigits: 0, displayNameDb: 'MD CONVERTER 1 SB ESS PACK 1 PACK VOLTAGE' },
{ path: 'yachteye.ess.starboard.2.voltage', type: 'number', unit: 'V', min: 600, max: 700, fractionDigits: 0, displayNameDb: 'MD CONVERTER 1 SB ESS PACK 2 PACK VOLTAGE' },
{ path: 'yachteye.ess.starboard.3.voltage', type: 'number', unit: 'V', min: 600, max: 700, fractionDigits: 0, displayNameDb: 'MD CONVERTER 1 SB ESS PACK 3 PACK VOLTAGE' },
{ path: 'yachteye.ess.voltage', type: 'number', unit: 'V', min: 600, max: 700, fractionDigits: 0, displayNameDb: 'N.A. AVG' },
// @todo: we also have STATE OF CHARGE for each PACK (1-3), assume the SB and PS values are ok to use.
{ path: 'yachteye.ess.port.stateOfCharge', type: 'ratio', unit: '%', min: 0, max: 1.0, displayNameDb: 'MD CONVERTER 2 PS ESS STATE OF CHARGE' },
{ path: 'yachteye.ess.starboard.stateOfCharge', type: 'ratio', unit: '%', min: 0, max: 1.0, displayNameDb: 'MD CONVERTER 1 SB ESS STATE OF CHARGE' },
{ path: 'yachteye.ess.stateOfCharge', type: 'ratio', unit: '%', min: 0, max: 1.0, displayNameDb: 'N.A. AVG' },
// yachteye.ess.chargeDischargeRate → "C".
// E.g. C/2 = fully charged in two hours, can also be written as 0.5C. For now assume we use the 'C/x' format and store the value of x.
// Assume Lithium with value 2.
// Sean Feehan - Chief Engineer - M/Y KISMET:
// The C Rate runs between -2.20C to +2.20C.
// C is a symbol to measure how fast the batteries are charging/discharging relative to their official rate. A negative C reading means the batteries are being discharged. A positive means they are charging.
// If the min and max are set at -2.5C to 2.5C that would be ideal."
{ path: 'yachteye.ess.port.chargeDischargeRate', type: IDataType.Number, unit: 'C', min: -2.5, max: 2.5, displayNameDb: 'MD CONVERTER 2 PS ESS C-RATE' },
{ path: 'yachteye.ess.starboard.chargeDischargeRate', type: IDataType.Number, unit: 'C', min: -2.5, max: 2.5, displayNameDb: 'MD CONVERTER 1 SB ESS C-RATE' },
{ path: 'yachteye.ess.chargeDischargeRate', type: IDataType.Number, unit: 'C', min: -2.5, max: 2.5, displayNameDb: 'N.A. AVG' },
// yachteye.ess.current → A
// Sean Feehan - Chief Engineer - M/Y KISMET: For this data field the range should be -80A to +150A
// Database dump PS values: -106.4 to +204.2 Ampere. Database dump SB values: -174.6 to +165.7 Ampere.
{ path: 'yachteye.ess.port.1.current', type: 'number', unit: 'A', min: -80, max: 150, fractionDigits: 1, displayNameDb: 'MD CONVERTER 2 PS ESS PACK 1 CURRENT' },
{ path: 'yachteye.ess.port.2.current', type: 'number', unit: 'A', min: -80, max: 150, fractionDigits: 1, displayNameDb: 'MD CONVERTER 2 PS ESS PACK 2 CURRENT' },
{ path: 'yachteye.ess.port.3.current', type: 'number', unit: 'A', min: -80, max: 150, fractionDigits: 1, displayNameDb: 'MD CONVERTER 2 PS ESS PACK 3 CURRENT' },
{ path: 'yachteye.ess.starboard.1.current', type: 'number', unit: 'A', min: -80, max: 150, fractionDigits: 1, displayNameDb: 'MD CONVERTER 1 SB ESS PACK 1 CURRENT' },
{ path: 'yachteye.ess.starboard.2.current', type: 'number', unit: 'A', min: -80, max: 150, fractionDigits: 1, displayNameDb: 'MD CONVERTER 1 SB ESS PACK 2 CURRENT' },
{ path: 'yachteye.ess.starboard.3.current', type: 'number', unit: 'A', min: -80, max: 150, fractionDigits: 1, displayNameDb: 'MD CONVERTER 1 SB ESS PACK 3 CURRENT' },
{ path: 'yachteye.ess.current', type: 'number', unit: 'A', min: 6 * -80, max: 6 * 150, fractionDigits: 1, displayNameDb: 'N.A. SUM' },
// CHILLER:
// Sean Feehan - Chief Engineer - M/Y KISMET: The Range for this should be 0-100°C.
// @todo: remove these.
{ path: 'yachteye.chiller.1.returnTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'HRS HOT WATER HEATER 1 RETURN TEMP' },
{ path: 'yachteye.chiller.2.returnTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'HRS HOT WATER HEATER 2 RETURN TEMP' },
{ path: 'yachteye.chiller.3.returnTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'HRS HOT WATER HEATER 3 RETURN TEMP' },
{ path: 'yachteye.chiller.4.returnTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'HRS HOT WATER HEATER 4 RETURN TEMP' },
{ path: 'yachteye.chiller.5.returnTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'HRS HOT WATER HEATER 5 RETURN TEMP' },
{ path: 'yachteye.chiller.returnTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'N.A. AVG' },
// Sean Feehan - Chief Engineer - M/Y KISMET: The Range for this should be 0-100°C.
// { path: 'yachteye.chiller.1.supplyTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'HRS HOT WATER HEATER 1 FLOW TEMP' },
// { path: 'yachteye.chiller.2.supplyTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'HRS HOT WATER HEATER 2 FLOW TEMP' },
// { path: 'yachteye.chiller.3.supplyTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'HRS HOT WATER HEATER 3 FLOW TEMP' },
// { path: 'yachteye.chiller.4.supplyTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'HRS HOT WATER HEATER 4 FLOW TEMP' },
// { path: 'yachteye.chiller.5.supplyTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'HRS HOT WATER HEATER 5 FLOW TEMP' },
{ path: 'yachteye.chiller.1.supplyTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'SEAWATER TEMPERATURE COMPRESSOR 1' },
{ path: 'yachteye.chiller.2.supplyTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'SEAWATER TEMPERATURE COMPRESSOR 2' },
{ path: 'yachteye.chiller.3.supplyTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'SEAWATER TEMPERATURE COMPRESSOR 3' },
{ path: 'yachteye.chiller.4.supplyTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'SEAWATER TEMPERATURE COMPRESSOR 4' },
{ path: 'yachteye.chiller.5.supplyTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'SEAWATER TEMPERATURE COMPRESSOR 5' },
{ path: 'yachteye.chiller.supplyTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(100, 'C', 'K'), fractionDigits: 1, displayNameDb: 'N.A. AVG' },
// Chiller water unit (CWU) pressure (Bar).
// From this pressure value we will derive the running/off status.
{ path: 'yachteye.chiller.1.pressure', type: 'number', unit: 'Pa', min: 0, max: 4 * 100000, fractionDigits: 0, displayNameDb: 'SEA WATER PUMP 1 CWU PRESSURE' },
{ path: 'yachteye.chiller.2.pressure', type: 'number', unit: 'Pa', min: 0, max: 4 * 100000, fractionDigits: 0, displayNameDb: 'SEA WATER PUMP 2 CWU PRESSURE' },
{ path: 'yachteye.chiller.3.pressure', type: 'number', unit: 'Pa', min: 0, max: 4 * 100000, fractionDigits: 0, displayNameDb: 'SEA WATER PUMP 3 CWU PRESSURE' },
{ path: 'yachteye.chiller.4.pressure', type: 'number', unit: 'Pa', min: 0, max: 4 * 100000, fractionDigits: 0, displayNameDb: 'SEA WATER PUMP 4 CWU PRESSURE' },
{ path: 'yachteye.chiller.5.pressure', type: 'number', unit: 'Pa', min: 0, max: 4 * 100000, fractionDigits: 0, displayNameDb: 'SEA WATER PUMP 5 CWU PRESSURE' },
// yachteye.chiller.compressor.[id].state → “running” or “off”. [1,2,3,4,5]
{ path: 'yachteye.chiller.compressor.1.state', type: 'running_off', displayNameDb: 'N.A. DERIVED' },
{ path: 'yachteye.chiller.compressor.2.state', type: 'running_off', displayNameDb: 'N.A. DERIVED' },
{ path: 'yachteye.chiller.compressor.3.state', type: 'running_off', displayNameDb: 'N.A. DERIVED' },
{ path: 'yachteye.chiller.compressor.4.state', type: 'running_off', displayNameDb: 'N.A. DERIVED' },
{ path: 'yachteye.chiller.compressor.5.state', type: 'running_off', displayNameDb: 'N.A. DERIVED' },
// THRUSTER: stern, bow0, bow1
// yachteye.thruster.[id].thrust → ratio (%)
// @todo: Not found in the database.
// { path: 'yachteye.thruster.stern.thrust', type: 'ratio', unit: '%', displayNameDb: 'TODO' },
// { path: 'yachteye.thruster.bow0.thrust', type: 'ratio', unit: '%', displayNameDb: 'TODO' },
// { path: 'yachteye.thruster.bow1.thrust', type: 'ratio', unit: '%', displayNameDb: 'TODO' },
// yachteye.thruster.[id].load → ratio (%)
// check if max of 120% is correct, for now assume it should be 100%, as suggested by Tim Schroeder (Luerssen).
// Sean Feehan - Chief Engineer - M/Y KISMET: Stern load: This should just be 0 - 100%.
// Sean Feehan - Chief Engineer - M/Y KISMET: Bow load: Yes the max should be 100%. During heavy maoneuvring it could touch 105%, but this is rare so we shouldn't skew the graphic to account for it.
{ path: 'yachteye.thruster.stern.load', type: 'ratio', unit: '%', min: 0, max: 1.0, fractionDigits: 3, displayNameDb: 'STERN THRUSTER LOAD IN %' },
{ path: 'yachteye.thruster.bow0.load', type: 'ratio', unit: '%', min: 0, max: 1.0, fractionDigits: 3, displayNameDb: 'BOW THRUSTER FWD DRIVE MOTOR LOAD' },
{ path: 'yachteye.thruster.bow1.load', type: 'ratio', unit: '%', min: 0, max: 1.0, fractionDigits: 3, displayNameDb: 'BOW THRUSTER AFT DRIVE MOTOR LOAD' },
{ path: 'yachteye.thruster.bow.load', type: 'ratio', unit: '%', min: 0, max: 1.0, fractionDigits: 3, displayNameDb: 'N.A. AVG' },
// yachteye.thruster.[id].current → A
// Tim Schroeder (Luerssen): There are 2 bow thrusters each are set to 432A. The stern thruster has max 470A.
{ path: 'yachteye.thruster.stern.current', type: 'number', unit: 'A', min: 0, max: 470, fractionDigits: 1, displayNameDb: 'STERN THRUSTER MOTOR CURRENT' },
{ path: 'yachteye.thruster.bow0.current', type: 'number', unit: 'A', min: 0, max: 432, fractionDigits: 0, displayNameDb: 'BOW THRUSTER FWD CURRENT' },
{ path: 'yachteye.thruster.bow1.current', type: 'number', unit: 'A', min: 0, max: 432, fractionDigits: 0, displayNameDb: 'BOW THRUSTER AFT CURRENT' },
{ path: 'yachteye.thruster.bow.current', type: 'number', unit: 'A', min: 0, max: 432, fractionDigits: 0, displayNameDb: 'N.A. AVG' },
// GEARBOX
// Sean Feehan - Chief Engineer - M/Y KISMET: If this is the Gearbox Oil Pressure then 0-4 Bar is a good Range. If it is the gearbox clutch pressure then 0-35Bar is good.
// DB values are from 0 to 4.6, so use a range [0, 5].
{ path: 'yachteye.gearbox.port.oilPressure', type: 'number', unit: 'Pa', min: 0, max: 5 * 100000, fractionDigits: 0, displayNameDb: 'M/E PS GEAR BOX OIL PRESS' },
{ path: 'yachteye.gearbox.starboard.oilPressure', type: 'number', unit: 'Pa', min: 0, max: 5 * 100000, fractionDigits: 0, displayNameDb: 'M/E SB GEAR BOX OIL PRESS' },
{ path: 'yachteye.gearbox.oilPressure', type: 'number', unit: 'Pa', min: 0, max: 5 * 100000, fractionDigits: 0, displayNameDb: 'N.A. AVG' },
// Sean Feehan - Chief Engineer - M/Y KISMET: You can put 0-65°C for this one.
{ path: 'yachteye.gearbox.port.oilTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(65, 'C', 'K'), fractionDigits: 1, displayNameDb: 'M/E PS GEAR BOX OIL TEMP' },
{ path: 'yachteye.gearbox.starboard.oilTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(65, 'C', 'K'), fractionDigits: 1, displayNameDb: 'M/E SB GEAR BOX OIL TEMP' },
{ path: 'yachteye.gearbox.oilTemperature', type: 'number', unit: 'K', min: utils.transform(0, 'C', 'K'), max: utils.transform(65, 'C', 'K'), fractionDigits: 1, displayNameDb: 'N.A. AVG' },
// MultiDrive Converter:
// max is defined as 10000 (to be divided by scale 10). For now assume it should be 100%, as suggested by Tim Schroeder (Luerssen).
// Sean Feehan - Chief Engineer - M/Y KISMET: Yes. 0-100%.
{ path: 'yachteye.multiDriveConverter.port.load', type: 'ratio', unit: '%', fractionDigits: 3, displayNameDb: 'PMS MULTI DRIVE 2 PS LOAD' },
{ path: 'yachteye.multiDriveConverter.starboard.load', type: 'ratio', unit: '%', fractionDigits: 3, displayNameDb: 'PMS MULTI DRIVE 1 SB LOAD' },
{ path: 'yachteye.multiDriveConverter.load', type: 'ratio', unit: '%', fractionDigits: 3, displayNameDb: 'N.A. AVG' },
// Sean Feehan - Chief Engineer - M/Y KISMET: 0-450V would be a more sensible range.
{ path: 'yachteye.multiDriveConverter.port.voltage', type: 'number', unit: 'V', min: 0, max: 450, fractionDigits: 0, displayNameDb: 'PMS MULTI DRIVE 2 PS VOLTAGE' },
{ path: 'yachteye.multiDriveConverter.starboard.voltage', type: 'number', unit: 'V', min: 0, max: 450, fractionDigits: 0, displayNameDb: 'PMS MULTI DRIVE 1 SB VOLTAGE' },
{ path: 'yachteye.multiDriveConverter.voltage', type: 'number', unit: 'V', min: 0, max: 450, fractionDigits: 0, displayNameDb: 'N.A. AVG' },
// Sean Feehan - Chief Engineer - M/Y KISMET: 0-450kW is the correct range.
{ path: 'yachteye.multiDriveConverter.port.wattage', type: 'number', unit: 'W', min: 0, max: 450 * 1000, fractionDigits: 0, displayNameDb: 'PMS MULTI DRIVE 2 PS POWER' },
{ path: 'yachteye.multiDriveConverter.starboard.wattage', type: 'number', unit: 'W', min: 0, max: 450 * 1000, fractionDigits: 0, displayNameDb: 'PMS MULTI DRIVE 1 SB POWER' },
{ path: 'yachteye.multiDriveConverter.wattage', type: 'number', unit: 'W', min: 0, max: 2 * 450 * 1000, fractionDigits: 0, displayNameDb: 'N.A. SUM' },
// yachteye.multiDriveConverter.powerFactor → number?
// database range says [-1, 1] but data from the database dump values are always positive.
// Sean Feehan - Chief Engineer - M/Y KISMET: A good range for this would be from 0.5-1.2 Cos Phi.
// Actual data is between 0-1 at the moment.
{ path: 'yachteye.multiDriveConverter.port.powerFactor', type: 'number', unit: '', min: 0.5, max: 1.2, fractionDigits: 2, displayNameDb: 'PMS MULTI DRIVE 2 PS POWER FACTOR' },
{ path: 'yachteye.multiDriveConverter.starboard.powerFactor', type: 'number', unit: '', min: 0.5, max: 1.2, fractionDigits: 2, displayNameDb: 'PMS MULTI DRIVE 1 SB POWER FACTOR' },
{ path: 'yachteye.multiDriveConverter.powerFactor', type: 'number', unit: '', min: 0.5, max: 1.2, fractionDigits: 2, displayNameDb: 'N.A. AVG' },
// PTO (Power Take-Off): [port, starboard]
// yachteye.pto.[id].wattage → W
// @todo: Not found in the database.
// Sean Feehan - Chief Engineer - M/Y KISMET: PTO is another name for the shaft generator motor. A good range is 0-700kW. I am not sure where this data feed would be taken from however.
// { path: 'yachteye.pto.port.wattage', type: 'number', unit: 'W', min: 0, max: 100, fractionDigits: 0, displayNameDb: 'TODO' },
// { path: 'yachteye.pto.starboard.wattage', type: 'number', unit: 'W', min: 0, max: 100, fractionDigits: 0, displayNameDb: 'TODO' },
// yachteye.pto.[id].current → A
// @todo: Not found in the database.
// { path: 'yachteye.pto.port.current', type: 'number', unit: 'A', min: 2, max: 4, fractionDigits: 1, displayNameDb: 'TODO' },
// { path: 'yachteye.pto.starboard.current', type: 'number', unit: 'A', min: 2, max: 4, fractionDigits: 1, displayNameDb: 'TODO' },
// STABILISER: forwardPort, forwardStarboard, aftPort, aftStarboard
{ path: 'yachteye.stabiliser.forwardPort.angle', type: IDataType.Number, unit: 'degrees', min: utils.transform(-45, 'deg', 'rad'), max: utils.transform(45, 'deg', 'rad'), displayNameDb: 'STABILIZER FWD PS FIN ANGLE SENSOR' },
{ path: 'yachteye.stabiliser.forwardStarboard.angle', type: IDataType.Number, unit: 'degrees', min: utils.transform(-45, 'deg', 'rad'), max: utils.transform(45, 'deg', 'rad'), displayNameDb: 'STABILIZER FWD SB FIN ANGLE SENSOR' },
{ path: 'yachteye.stabiliser.aftPort.angle', type: IDataType.Number, unit: 'degrees', min: utils.transform(-45, 'deg', 'rad'), max: utils.transform(45, 'deg', 'rad'), displayNameDb: 'STABILIZER AFT PS FIN ANGLE SENSOR' },
{ path: 'yachteye.stabiliser.aftStarboard.angle', type: IDataType.Number, unit: 'degrees', min: utils.transform(-45, 'deg', 'rad'), max: utils.transform(45, 'deg', 'rad'), displayNameDb: 'STABILIZER AFT SB FIN ANGLE SENSOR' },
// PROPELLER: [port, starboard]
// Sean Feehan - Chief Engineer - M/Y KISMET: A Max of 330RPM would display a bit better. Typical Shaft RPM is 150-250RPM.
{ path: 'yachteye.propellor.port.rpm', type: 'number', unit: 'Hz', min: 0, max: 330, fractionDigits: 0, displayNameDb: 'M/E PS SHAFT SPEED' },
{ path: 'yachteye.propellor.starboard.rpm', type: 'number', unit: 'Hz', min: 0, max: 330, fractionDigits: 0, displayNameDb: 'M/E SB SHAFT SPEED' },
// yachteye.propellor.[id].corePitch → ratio (%)
{ path: 'yachteye.propellor.port.corePitch', type: 'ratio', unit: '%', min: -1, displayNameDb: 'CPP SYSTEM PS PITCH ORDER' },
{ path: 'yachteye.propellor.starboard.corePitch', type: 'ratio', unit: '%', min: -1, displayNameDb: 'CPP SYSTEM SB PITCH ORDER' },
// To be determined with @Fabio Pizzella
// yachteye.path.[id].direction → Special path used to render the dataflow. See below.
],
dataDefinitions_13774: [
// Speed - From the regular NMEA (navigation.speedOverGround).
// fuel remaining %.
{ path: 'yachteye.fuel.currentLevel', type: IDataType.Ratio, unit: '%', fractionDigits: 2, displayNameDb: 'N.A. Calculated' }, // @todo: assume this is calculated.
// Total Remaining Fuel (m3).
// {Type:2,Unix:1738867084,Key:Total Remaining Fuel,Value:0.0,Unit:m3}
{ path: 'yachteye.fuel.remaining', type: IDataType.NumberDecreasing, unit: 'm3', min: 0, max: 16000 / 1000, displayNameDb: '', startVal: 14 },
// The capacity is derived from the design, where 13500L is shown as 84%. Therefore the capacity is 13500 * 100 / 84, which is about 16000L.
// @todo: set the capacity to 900, so at least we get decent values. The correct value is to be confirmed.
{ path: 'yachteye.fuel.capacity', type: IDataType.Fixed, unit: 'm3', fixed: 900, fractionDigits: 3, displayNameDb: '' }, // @todo: assume this is a fixed value for now.
// fuel used in last 24 hrs. @todo: not clear where this data is supposed to come from.
{ path: 'yachteye.fuel.usage.24h', type: IDataType.Other, unit: 'm3', displayNameDb: 'N.A. Calculated' },
// Mode: Inactive (0), top-speed (1), full-diesel-electric-cruise (2), crew-sea-transit (3), pod-slow-speed-cruise (4), sea-mode (5).
// Propulsion Mode (Drive Mode) - Kongsberg.
{ path: 'yachteye.engineroom.mode', type: IDataType.IntegerStatus, unit: '', min: 0, max: 5, displayNameDb: '', startVal: 0 },
// Top speed.
// max speed 24 kn
{ path: 'yachteye.engineroom.mode.1.max-speed', type: IDataType.Fixed, unit: 'm/s', fixed: (24 * 1852) / 3600, displayNameDb: '' },
// Full diesel electric cruise.
// max speed 18 kn
{ path: 'yachteye.engineroom.mode.2.max-speed', type: IDataType.Fixed, unit: 'm/s', fixed: (18 * 1852) / 3600, displayNameDb: '' },
// Crew sea transit.
// max speed 18 kn
{ path: 'yachteye.engineroom.mode.3.max-speed', type: IDataType.Fixed, unit: 'm/s', fixed: (18 * 1852) / 3600, displayNameDb: '' },
// POD slow speed cruise.
// max speed 12 kn
{ path: 'yachteye.engineroom.mode.4.max-speed', type: IDataType.Fixed, unit: 'm/s', fixed: (12 * 1852) / 3600, displayNameDb: '' },
// Sea mode.
// max speed 16 kn
{ path: 'yachteye.engineroom.mode.5.max-speed', type: IDataType.Fixed, unit: 'm/s', fixed: (16 * 1852) / 3600, displayNameDb: '' },
// Generator 1,2,3,4,5:
// load %
// Max. output power is 1,850kWe
{ path: 'yachteye.genset.1.load', type: IDataType.Ratio, unit: '%', fractionDigits: 3, displayNameDb: 'N.A. Calculated' },
{ path: 'yachteye.genset.2.load', type: IDataType.Ratio, unit: '%', fractionDigits: 3, displayNameDb: 'N.A. Calculated' },
{ path: 'yachteye.genset.3.load', type: IDataType.Ratio, unit: '%', fractionDigits: 3, displayNameDb: 'N.A. Calculated' },
{ path: 'yachteye.genset.4.load', type: IDataType.Ratio, unit: '%', fractionDigits: 3, displayNameDb: 'N.A. Calculated' },
{ path: 'yachteye.genset.5.load', type: IDataType.Ratio, unit: '%', fractionDigits: 3, displayNameDb: 'N.A. Calculated' },
// fuel consumption 0 -300 litre/hour.
{ path: 'yachteye.genset.1.fuelRate', type: IDataType.Number, unit: 'm3/s', min: 0, max: 300 / 1000 / 3600, fractionDigits: 8, displayNameDb: '' },
{ path: 'yachteye.genset.2.fuelRate', type: IDataType.Number, unit: 'm3/s', min: 0, max: 300 / 1000 / 3600, fractionDigits: 8, displayNameDb: '' },
{ path: 'yachteye.genset.3.fuelRate', type: IDataType.Number, unit: 'm3/s', min: 0, max: 300 / 1000 / 3600, fractionDigits: 8, displayNameDb: '' },
{ path: 'yachteye.genset.4.fuelRate', type: IDataType.Number, unit: 'm3/s', min: 0, max: 300 / 1000 / 3600, fractionDigits: 8, displayNameDb: '' },
{ path: 'yachteye.genset.5.fuelRate', type: IDataType.Number, unit: 'm3/s', min: 0, max: 300 / 1000 / 3600, fractionDigits: 8, displayNameDb: '' },
// kW output (to MSB) 0 - 2 kW.
// Power Genset 1 (Genset SB OUT)
// {Type:2,Unix:1738866968,Key:Power Genset 1 (Genset SB OUT),Value:0.0,Unit:kW}
{ path: 'yachteye.genset.1.wattage', type: IDataType.Number, unit: 'W', min: 0, max: 1850 * 1000, fractionDigits: 0, displayNameDb: '' },
// Power Genset 2 (Genset SB IN)
// {Type:2,Unix:1738866974,Key:Power Genset 2 (Genset SB IN),Value:0.0,Unit:kW}
{ path: 'yachteye.genset.2.wattage', type: IDataType.Number, unit: 'W', min: 0, max: 1850 * 1000, fractionDigits: 0, displayNameDb: '' },
// Power Genset 3 (Genset CNT)
// {Type:2,Unix:1738866982,Key:Power Genset 3 (Genset CNT),Value:0.0,Unit:kW}
{ path: 'yachteye.genset.3.wattage', type: IDataType.Number, unit: 'W', min: 0, max: 1850 * 1000, fractionDigits: 0, displayNameDb: '' },
// Power Genset 4 (Genset PS IN)
// {Type:2,Unix:1738866989,Key:Power Genset 4 (Genset PS IN),Value:0.0,Unit:kW}
{ path: 'yachteye.genset.4.wattage', type: IDataType.Number, unit: 'W', min: 0, max: 1850 * 1000, fractionDigits: 0, displayNameDb: '' },
// Power Genset 5 (Genset PS OUT)
// {Type:2,Unix:1738866996,Key:Power Genset 5 (Genset PS OUT),Value:0.0,Unit:kW}
{ path: 'yachteye.genset.5.wattage', type: IDataType.Number, unit: 'W', min: 0, max: 1850 * 1000, fractionDigits: 0, displayNameDb: '' },
// MSB (Main Storage Bank) 690V AFT.
// MSB 690V AFT to MSB 400V AFT
// Power Input MSB 400V AFT
// {Type:2,Unix:1738867007,Key:Power Input MSB 400V AFT,Value:0.0,Unit:kW}
{ path: 'yachteye.msb400v.aft.wattage', type: IDataType.Number, unit: 'W', min: 0, max: 823 * 1000, fractionDigits: 0, displayNameDb: '' },
// MSB (Main Storage Bank) 690V FWD
// MSB 690V FWD to MSB 400V FWD
// Power Input MSB 400V FWD
// {Type:2,Unix:1738867015,Key:Power Input MSB 400V FWD,Value:0.0,Unit:kW}
{ path: 'yachteye.msb400v.fwd.wattage', type: IDataType.Number, unit: 'W', min: 0, max: 823 * 1000, fractionDigits: 0, displayNameDb: '' },
// MSB (Main Storage Bank) 400V AFT
// MSB (Main Storage Bank) 400V FWD
// MultiDrive AFT
// From MSB (Main Storage Bank) 690V AFT to Multidrive AFT.
// Power Input Multidrive AFT
// {Type:2,Unix:1738866940,Key:Power Input Multidrive AFT,Value:0.0,Unit:kW}
{ path: 'yachteye.multiDriveConverter.aft.wattage', type: IDataType.Number, unit: 'W', min: 0, max: 3915 * 1000, fractionDigits: 0, displayNameDb: '' },
// MultiDrive FWD
// From MSB (Main Storage Bank) 690V FWD to Multidrive FWD.
// Power Input Multidrive FWD
// {Type:2,Unix:1738866951,Key:Power Input Multidrive FWD,Value:0.0,Unit:kW}
{ path: 'yachteye.multiDriveConverter.fwd.wattage', type: IDataType.Number, unit: 'W', min: 0, max: 3915 * 1000, fractionDigits: 0, displayNameDb: '' },
// PTI/PTO PS (PTO is another name for the shaft generator motor)
// kW input (from MultiDrive AFT)
// Power PTI/O PS
// {Type:2,Unix:1738866893,Key:Power PTI/O PS,Value:0.0,Unit:kW}
{ path: 'yachteye.pti_pto.ps.wattage', type: IDataType.Number, unit: 'W', min: 0, max: 2.6 * 1000, fractionDigits: 0, displayNameDb: '' },
// PTI/PTO SB (PTO is another name for the shaft generator motor)
// kW input (from MultiDrive FWD)
// Power PTI/O SB
// {Type:2,Unix:1738866908,Key:Power PTI/O SB,Value:0.0,Unit:kW}
{ path: 'yachteye.pti_pto.sb.wattage', type: IDataType.Number, unit: 'W', min: 0, max: 2.6 * 1000, fractionDigits: 0, displayNameDb: '' },
// POD - pod drive propulsion in the centre.
// kW value of the POD - total.
// {Type:2,Unix:1738866874,Key:Power POD (Total),Value:0.0,Unit:kW}
{ path: 'yachteye.pod.wattage', type: IDataType.Number, unit: 'W', min: 0, max: 17429 * 1000, fractionDigits: 0, displayNameDb: '' },
// kW input (from MultiDrive AFT)
// Power Multidrive AFT POD
// {Type:2,Unix:1738866914,Key:Power Multidrive AFT POD,Value:0.0,Unit:kW}
{ path: 'yachteye.pod.aft.wattage', type: IDataType.Number, unit: 'W', min: 0, max: 1637 * 1000, fractionDigits: 0, displayNameDb: '' },
// kW input (from MultiDrive FWD)
// Power Multidrive FWD POD
// {Type:2,Unix:1738866931,Key:Power Multidrive FWD POD,Value:0.0,Unit:kW}
{ path: 'yachteye.pod.fwd.wattage', type: IDataType.Number, unit: 'W', min: 0, max: 1637 * 1000, fractionDigits: 0, displayNameDb: '' },
],
averageFuelRate: { N: 0, average: 0, hour: new Date().getUTCHours() },
fuelUsedIn24Hours: [],
/**
* Register with the router.
* @param router the router to register with.
*/
registerWithRouter(router) {
router.get('/report', (req, res) => {
res.set('Content-Type', 'text/html').send(`
<html>
<head>
<title>Engine Room Data</title>
</head>
<body>
<table style="width: 100%;">
<thead>
<tr>
<th>ID</th>
<th>YachtEye Path</th>
<th>Database Metric</th>
<th>Raw Value</th>
<th>Parsed Value</th>
<th>Last Update</th>
</tr>
</thead>
<tbody>
${Object.keys(plugin.lastRawData.data)
.map((key) => {
const data = plugin.lastRawData.data[key];
return `
<tr>
<td>${data.id}</td>
<td>${data.path}</td>
<td>${data.displayNameDb}</td>
<td>${data.value}</td>
<td>${data.parsed}</td>
<td>${data.lastUpdate}</td>
</tr>
`;
})
.join('')}
</tbody>
</table>
</body>
</html>`);
});
},
/**
* Start the plugin.
* @param settings the configuration data entered via the Plugin Config screen.
* @param restartPlugin a function that can be called by the plugin to restart itself.
*/
start: (settings, restartPlugin) => {
app.debug(`starting...`);
plugin.restartPlugin = restartPlugin;
const pluginSettings = settings;
const dataDefs = pluginSettings.erType === IEngineRoomType.Type13774 ? plugin.dataDefinitions_13774 : plugin.dataDefinitions;
try {
dataDefs.forEach((v, i) => {
plugin.valueHistory[v.path] = [];
if (v.type === 'fixed-value' && v.fixed === undefined) {
app.error(`Incorrect data definition: ${JSON.stringify(v)}`);
}
if (v.type === IDataType.NumberDecreasing && v.startVal === undefined) {
app.error(`Incorrect data definition: ${JSON.stringify(v)}`);
}
if (v.type === IDataType.IntegerStatus && v.startVal === undefined) {
app.error(`Incorrect data definition: ${JSON.stringify(v)}`);
}
});
plugin.averageFuelRate = { N: 0, average: 0, hour: new Date().getUTCHours() };
plugin.fuelUsedIn24Hours = [{ hour: 99, fuelUsed: null, remainingValueAtStart: null, remainingValueLast: null }];
if (pluginSettings.simulator === true) {
plugin.simulator = new simulator_1.default(dataDefs);
}
else if (pluginSettings.erType === IEngineRoomType.Type13758) {
plugin.sqlDB = new sql_1.default(settings, plugin.dataDefinitions);
}
else if (pluginSettings.erType === IEngineRoomType.Type13774) {
plugin.amcs = new tcp_1.default(app, pluginSettings, '0.0.0.0', pluginSettings.amcsPort, plugin.dataDefinitions_13774);
}
else {
throw new Error(`Invalid Engine Room type: ${pluginSettings.erType}`);
}
app.handleMessage(plugin.id, plugin.meta());
plugin.intervalTimer = setInterval(plugin.pollData, settings.interval * 1000, settings);
// @todo: improve connected to info.
const connectedTo = pluginSettings.simulator ? 'simulator' : pluginSettings.erType === IEngineRoomType.Type13758 ? pluginSettings.sqlServer : 'AMCS';
app.setPluginStatus(`Started, mode=${pluginSettings.erType}, interval=${settings.interval} (s), connected to ${connectedTo}.`);
}
catch (err) {
app.setPluginError(`Error in start(): ${err === null || err === void 0 ? void 0 : err.message}`);
}
},
/**
* Stop the plugin.
*/
stop: () => {
if (plugin.intervalTimer !== null) {
clearInterval(plugin.intervalTimer);
plugin.intervalTimer = null;
}
if (plugin.sqlDB !== null) {
plugin.sqlDB.disconnect();
plugin.sqlDB = null;
}
if (plugin.amcs !== null) {
plugin.amcs.stop();
plugin.amcs = null;
}
plugin.simulator = null;
plugin.fuelUsedIn24Hours = [];
plugin.unsubscribes.forEach((f) => f());
plugin.unsubscribes = [];
app.debug(`Stopped.`);
app.setPluginStatus(`Stopped.`);
},
pollData: (settings) => {
const timeStamp = new Date().toISOString();
const SkValues = [];
if (plugin.simulator !== null) {
const simulatedData = plugin.simulator.getData();
if (settings.erType === IEngineRoomType.Type13758) {
plugin.postProcess(simulatedData);
}
else if (settings.erType === IEngineRoomType.Type13774) {
plugin.postProcess_13774(simulatedData);
}
for (let key in simulatedData) {
const dataValue = simulatedData[key];
plugin.valueHistory[key].push(dataValue);
const surplus = plugin.valueHistory[key].length - settings.historyLength;
if (surplus > 0) {
plugin.valueHistory[key] = plugin.valueHistory[key].slice(surplus);
}
SkValues.push({ path: key, value: { latest: dataValue, history: plugin.valueHistory[key] } });
}
const delta = {
context: 'vessels.self',
updates: [],
};
const skUpdate = {
source: { label: plugin.id },
timestamp: timeStamp,
values: SkValues,
};
delta.updates.push(skUpdate);
app.handleMessage(plugin.id, delta);
}
else if (plugin.sqlDB && settings.erType === IEngineRoomType.Type13758) {
const dataPromise = plugin.sqlDB.getData();
dataPromise
.then((result) => {
const databaseData = result.data;
plugin.lastRawData.date = Date.now();
plugin.lastRawData.data = result.raw;
plugin.postProcess(databaseData);
for (let key in databaseData) {
const dataValue = databaseData[key];
plugin.valueHistory[key].push(dataValue);
const surplus = plugin.valueHistory[key].length - settings.historyLength;
if (surplus > 0) {
plugin.valueHistory[key] = plugin.valueHistory[key].slice(surplus);
}
SkValues.push({ path: key, value: { latest: dataValue, history: plugin.valueHistory[key] } });
}
const delta = {
context: 'vessels.self',
updates: [],
};
const skUpdate = {
source: { label: plugin.id },
timestamp: timeStamp,
values: SkValues,
};
delta.updates.push(skUpdate);
app.handleMessage(plugin.id, delta);
})
.catch((reason) => {
app.error(`pollData() error: ${reason}`);
app.setPluginError(`pollData() error: ${reason === null || reason === void 0 ? void 0 : reason.message}`);
});
}
else if (plugin.amcs !== null && settings.erType === IEngineRoomType.Type13774) {
const amcsData = plugin.amcs.getData();
// @todo get the Kongsberg data.
plugin.postProcess_13774(amcsData);
for (let key in amcsData) {
const dataValue = amcsData[key];
// Type13774 does not need history.
// plugin.valueHistory[key].push(dataValue);
// const surplus = plugin.valueHistory[key].length - settings.historyLength;
// if (surplus > 0) {
// plugin.valueHistory[key] = plugin.valueHistory[key].slice(surplus);
// }
SkValues.push({ path: key, value: { latest: dataValue, history: plugin.valueHistory[key] } });
}
const delta = {
context: 'vessels.self',
updates: [],
};
const skUpdate = {
source: { label: plugin.id },
timestamp: timeStamp,
values: SkValues,
};
delta.updates.push(skUpdate);