From 2e995b0db5843b30edca712cf556041067b0cad2 Mon Sep 17 00:00:00 2001 From: panaaj <38519157+panaaj@users.noreply.github.com> Date: Fri, 1 Dec 2023 16:15:17 +1030 Subject: [PATCH 1/7] Added initial support for Autopilot API --- index.js | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/index.js b/index.js index 45b2187..5ae5329 100644 --- a/index.js +++ b/index.js @@ -74,6 +74,8 @@ module.exports = function(app) { app.registerPutHandler('vessels.self', advance, autopilot.putAdvanceWaypoint) + + registerProvider(props.type) } plugin.stop = function() { @@ -119,5 +121,115 @@ module.exports = function(app) { return config } + // register with Autopilot API + const registerProvider = (apType)=> { + app.debug('**** registerProvider *****') + try { + app.registerAutopilotProvider( + { + getData: async (deviceId) => { + const apState = app.getSelfPath(state_path) + return { + options: { + states: [ + {name: 'auto', engaged: true}, + {name: 'wind', engaged: true}, + {name: 'route', engaged: true}, + {name: 'standby', engaged: false} + ], + modes: [] + }, + mode: null, + state: apState ?? null, + engaged: ['auto','wind','route'].includes(apState) ? true : false + } + }, + getState: async (deviceId) => { + return app.getSelfPath(state_path) ?? null + }, + setState: async ( + state, + deviceId + ) => { + const r = autopilot.putState(undefined, undefined, state, undefined) + if (r.state === 'FAILURE') { + throw new Error(r.message) + } + else { + return state === 'standby' ? false : true + } + }, + getMode: async (deviceId) => { + throw new Error('Not implemented!') + }, + setMode: async (mode, deviceId) => { + throw new Error('Not implemented!') + }, + getTarget: async (deviceId) => { + throw new Error('Not implemented!') + }, + setTarget: async (value, deviceId) => { + const apState = app.getSelfPath(state_path) + const deg = value * (180 / Math.PI) + if ( apState === 'auto' ) { + const r = autopilot.putTargetHeading(undefined, undefined, deg, undefined) + if (r.state === 'FAILURE') { + throw new Error(r.message) + } + } else if ( apState === 'wind' ) { + const r = autopilot.putTargetWind(undefined, undefined, deg, undefined) + if (r.state === 'FAILURE') { + throw new Error(r.message) + } + } + return + }, + adjustTarget: async ( + value, + deviceId + ) => { + const deg = value * (180 / Math.PI) + const r = autopilot.putAdjustHeading(undefined, undefined, deg, undefined) + if (r.state === 'FAILURE') { + throw new Error(r.message) + } + return + }, + engage: async (deviceId) => { + const r = autopilot.putState(undefined, undefined, 'auto', undefined) + if (r.state === 'FAILURE') { + throw new Error(r.message) + } + return + }, + disengage: async (deviceId) => { + const r = autopilot.putState(undefined, undefined, 'standby', undefined) + if (r.state === 'FAILURE') { + throw new Error(r.message) + } + return + }, + tack: async ( + direction, + deviceId + ) => { + const r = autopilot.putTack(undefined, undefined, 'direction', undefined) + if (r.state === 'FAILURE') { throw new Error(r.message) } + return + }, + gybe: async ( + direction, + deviceId + ) => { + throw new Error('Not implemented!') + } + }, + [apType] + ) + } catch (error) { + app.debug(error) + } + } + return plugin; } From 3284817bc7842cdd8af2c1afd451d54c3c3bac39 Mon Sep 17 00:00:00 2001 From: panaaj <38519157+panaaj@users.noreply.github.com> Date: Mon, 11 Dec 2023 14:33:18 +1030 Subject: [PATCH 2/7] Inital support for sending updates to API (N2KAnalyzerOut) --- index.js | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 116 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 5ae5329..fb0b9e1 100644 --- a/index.js +++ b/index.js @@ -34,6 +34,8 @@ module.exports = function(app) { var autopilot var pilots = {} + let apType = '' // autopilot type + _.keys(types).forEach( type => { const module = types[type] //console.log(`${type}: ${module}`) @@ -47,7 +49,7 @@ module.exports = function(app) { }) plugin.start = function(props) { - + apType= props.type autopilot = pilots[props.type] autopilot.start(props) @@ -75,7 +77,7 @@ module.exports = function(app) { advance, autopilot.putAdvanceWaypoint) - registerProvider(props.type) + registerProvider() } plugin.stop = function() { @@ -122,7 +124,10 @@ module.exports = function(app) { } // register with Autopilot API - const registerProvider = (apType)=> { + const registerProvider = ()=> { + app.debug('**** intialise n2k listener *****') + app.on('N2KAnalyzerOut', onStreamEvent) + app.debug('**** registerProvider *****') try { app.registerAutopilotProvider( @@ -231,5 +236,113 @@ module.exports = function(app) { } } + // parse NMEA2000 stream input + const onStreamEvent = (evt) => { + // in-scope PGNs + const pgns = [ + 65345, 65360, 65379, + 65288, + 127237 + ] + + // out-of-scope PGNs + if (!pgns.includes(evt.pgn)) { + return + } + + // 127237 `Heading / Track control (Rudder, etc.)` + if (evt.pgn === 127237) { + //app.debug('n2k pgn=', evt.pgn, evt.fields, evt.description) + } + + // 65288 = notifications.autopilot. + if (evt.pgn === 65288) { + //app.debug('n2k pgn=', evt.pgn, evt.fields, evt.description) + if (evt.fields['Manufacturer Code'] !== 'Raymarine' + || typeof evt.fields['Alarm Group'] === 'Autopilot' + || typeof evt.fields['Alarm Status'] === 'undefined') { + return + } + + const method = [ 'visual' ] + let state = evt.fields['Alarm Status'] + if ( state === 'Alarm condition met and not silenced' ) { + method.push('sound') + } + if ( state === 'Alarm condition not met' ) { + state = 'normal' + } else { + state = 'alarm' + } + + let alarmName = evt.fields['Alarm ID'] + if ( typeof alarmName !== 'string' ) { + alarmName = `Unknown Seatalk Alarm ${alarmName}` + } else if ( state === 'alarm' && ( + alarmName === 'WP Arrival' + || alarmName === 'Pilot Way Point Advance' + || alarmName === 'Pilot Route Complete' + ) + ) { + state = 'alert' + } + + const path = evt.fields['Alarm Group'].toLowerCase().replace(/ /g, '') + '.' + alarmName.replace(/ /g, '') + + app.debug('notifications.' + path) + app.debug({ + message: alarmName, + method: method, + state: state + }) + } + + // 65345 = 'steering.autopilot.target.windAngleApparent' + if (evt.pgn === 65345) { + app.debug('n2k pgn=', evt.pgn, evt.description) + let angle = evt.fields['Wind Datum'] ? Number(evt.fields['Wind Datum']) : null + angle = ( typeof angle === 'number' && angle > Math.PI ) ? angle-(Math.PI*2) : angle + app.autopilotUpdate(apType, 'target', angle) + } + + // 65360 = 'steering.autopilot.target.headingTrue' + if (evt.pgn === 65360) { + //app.debug('n2k pgn=', evt.pgn, evt.fields, evt.description) + const targetTrue = evt.fields['Target Heading True'] ? Number(evt.fields['Target Heading True']) : null + const targetMagnetic = evt.fields['Target Heading Magnetic'] ? Number(evt.fields['Target Heading Magnetic']) : null + const target = typeof targetTrue === 'number' ? targetTrue : + typeof targetMagnetic === 'number' ? targetMagnetic: null + app.autopilotUpdate(apType, 'target', target) + } + + // 65379 = 'steering.autopilot.state' + if (evt.pgn === 65379) { + //app.debug('n2k pgn=', evt.pgn, evt.fields, evt.description) + const mode = evt.fields['Pilot Mode'] ? Number(evt.fields['Pilot Mode']) : null + const subMode = evt.fields['Sub Mode'] ? Number(evt.fields['Sub Mode']) : null + if ( mode === 0 && subMode === 0 ) { + app.autopilotUpdate(apType, 'state', 'standby') + app.autopilotUpdate(apType, 'engaged', false) + } + else if ( mode == 0 && subMode == 1 ) { + app.autopilotUpdate(apType, 'state', 'wind') + app.autopilotUpdate(apType, 'engaged', true) + } + else if ( (mode == 128 || mode == 129) && subMode == 1 ) { + app.autopilotUpdate(apType, 'state', 'route') + app.autopilotUpdate(apType, 'engaged', true) + } + else if ( mode == 64 && subMode == 0 ) { + app.autopilotUpdate(apType, 'state', 'auto') + app.autopilotUpdate(apType, 'engaged', true) + } + else { + app.autopilotUpdate(apType, 'state', 'standby') + app.autopilotUpdate(apType, 'engaged', false) + } + } + + } + return plugin; } From 06a66413d71d93437a9235cc2b025e03f842ac52 Mon Sep 17 00:00:00 2001 From: panaaj <38519157+panaaj@users.noreply.github.com> Date: Tue, 12 Dec 2023 17:02:02 +1030 Subject: [PATCH 3/7] Only process N2K messages from the target device Id. --- index.js | 28 ++++++++++++---------------- raymarinen2k.js | 6 +++++- raystngconv.js | 6 +++++- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/index.js b/index.js index fb0b9e1..1206f81 100644 --- a/index.js +++ b/index.js @@ -52,6 +52,7 @@ module.exports = function(app) { apType= props.type autopilot = pilots[props.type] autopilot.start(props) + app.debug('autopilot.id:', autopilot.id, apType) app.registerPutHandler('vessels.self', state_path, @@ -123,7 +124,7 @@ module.exports = function(app) { return config } - // register with Autopilot API + // Autopilot API - register with Autopilot API const registerProvider = ()=> { app.debug('**** intialise n2k listener *****') app.on('N2KAnalyzerOut', onStreamEvent) @@ -236,7 +237,7 @@ module.exports = function(app) { } } - // parse NMEA2000 stream input + // Autopilot API - parse NMEA2000 stream input const onStreamEvent = (evt) => { // in-scope PGNs const pgns = [ @@ -244,9 +245,8 @@ module.exports = function(app) { 65288, 127237 ] - - // out-of-scope PGNs - if (!pgns.includes(evt.pgn)) { + + if (!pgns.includes(evt.pgn) || evt.src !== autopilot.id) { return } @@ -256,8 +256,7 @@ module.exports = function(app) { } // 65288 = notifications.autopilot. - if (evt.pgn === 65288) { - //app.debug('n2k pgn=', evt.pgn, evt.fields, evt.description) + if (evt.pgn === 65288) { if (evt.fields['Manufacturer Code'] !== 'Raymarine' || typeof evt.fields['Alarm Group'] === 'Autopilot' || typeof evt.fields['Alarm Status'] === 'undefined') { @@ -297,17 +296,15 @@ module.exports = function(app) { }) } - // 65345 = 'steering.autopilot.target.windAngleApparent' - if (evt.pgn === 65345) { - app.debug('n2k pgn=', evt.pgn, evt.description) + // 65345 = 'steering.autopilot.target (windAngleApparent)' + if (evt.pgn === 65345) { let angle = evt.fields['Wind Datum'] ? Number(evt.fields['Wind Datum']) : null angle = ( typeof angle === 'number' && angle > Math.PI ) ? angle-(Math.PI*2) : angle app.autopilotUpdate(apType, 'target', angle) } - // 65360 = 'steering.autopilot.target.headingTrue' - if (evt.pgn === 65360) { - //app.debug('n2k pgn=', evt.pgn, evt.fields, evt.description) + // 65360 = 'steering.autopilot.target (true/magnetic)' + if (evt.pgn === 65360) { const targetTrue = evt.fields['Target Heading True'] ? Number(evt.fields['Target Heading True']) : null const targetMagnetic = evt.fields['Target Heading Magnetic'] ? Number(evt.fields['Target Heading Magnetic']) : null const target = typeof targetTrue === 'number' ? targetTrue : @@ -315,9 +312,8 @@ module.exports = function(app) { app.autopilotUpdate(apType, 'target', target) } - // 65379 = 'steering.autopilot.state' - if (evt.pgn === 65379) { - //app.debug('n2k pgn=', evt.pgn, evt.fields, evt.description) + // 65379 = 'steering.autopilot.state', 'steering.autopilot.engaged' + if (evt.pgn === 65379) { const mode = evt.fields['Pilot Mode'] ? Number(evt.fields['Pilot Mode']) : null const subMode = evt.fields['Sub Mode'] ? Number(evt.fields['Sub Mode']) : null if ( mode === 0 && subMode === 0 ) { diff --git a/raymarinen2k.js b/raymarinen2k.js index 1944e9e..99822c5 100644 --- a/raymarinen2k.js +++ b/raymarinen2k.js @@ -53,12 +53,14 @@ const everyone_dst = '255' module.exports = function(app) { var deviceid - var pilot = {} + var pilot = {id: null} var timers = [] var discovered pilot.start = (props) => { deviceid = props.deviceid + pilot.id = Number(deviceid) + app.debug('props.deviceid:', deviceid) if ( props.controlHead ) { timers.push(setInterval(() => { @@ -212,6 +214,8 @@ module.exports = function(app) { description = `Discovered an EV-1 with id ${discovered}` app.debug(description) } + + defaultId = pilot.id ?? defaultId return { deviceid: { diff --git a/raystngconv.js b/raystngconv.js index ef1a1bb..f4aca73 100644 --- a/raystngconv.js +++ b/raystngconv.js @@ -56,11 +56,13 @@ const everyone_dst = '255' module.exports = function(app) { var deviceid - var pilot = {} + var pilot = {id: null} var discovered pilot.start = (props) => { deviceid = props.converterDeviceId + pilot.id = Number(deviceid) + app.debug('props.converterDeviceId:', deviceid) } pilot.stop = () => { @@ -195,6 +197,8 @@ module.exports = function(app) { app.debug(description) } + defaultConverterId = pilot.id ?? defaultConverterId + return { converterDeviceId: { type: "string", From 5aa2c734d29d438ef3eacb34c0195e5576372d3c Mon Sep 17 00:00:00 2001 From: panaaj <38519157+panaaj@users.noreply.github.com> Date: Wed, 20 Dec 2023 16:27:19 +1030 Subject: [PATCH 4/7] Use stored deviceid as default if device not discovered. --- index.js | 4 ++-- raymarinen2k.js | 9 ++++++--- raystngconv.js | 11 +++++++---- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index 1206f81..fa423f6 100644 --- a/index.js +++ b/index.js @@ -52,7 +52,7 @@ module.exports = function(app) { apType= props.type autopilot = pilots[props.type] autopilot.start(props) - app.debug('autopilot.id:', autopilot.id, apType) + app.debug('autopilot.id:', autopilot.id, 'autopilot.type:', apType) app.registerPutHandler('vessels.self', state_path, @@ -246,7 +246,7 @@ module.exports = function(app) { 127237 ] - if (!pgns.includes(evt.pgn) || evt.src !== autopilot.id) { + if (!pgns.includes(evt.pgn) || String(evt.src) !== autopilot.id) { return } diff --git a/raymarinen2k.js b/raymarinen2k.js index 99822c5..8a24a53 100644 --- a/raymarinen2k.js +++ b/raymarinen2k.js @@ -59,7 +59,7 @@ module.exports = function(app) { pilot.start = (props) => { deviceid = props.deviceid - pilot.id = Number(deviceid) + pilot.id = deviceid app.debug('props.deviceid:', deviceid) if ( props.controlHead ) { @@ -189,9 +189,11 @@ module.exports = function(app) { } pilot.properties = () => { - let defaultId = '205' + let defaultId = deviceid ?? '205' let description = 'No EV-1 Found' + app.debug('***pre-discovery -> defaultId', defaultId) + if ( !discovered ) { //let full = app.deltaCache.buildFull(undefined, [ 'sources' ]) //if ( full && full.sources ) { @@ -215,7 +217,8 @@ module.exports = function(app) { app.debug(description) } - defaultId = pilot.id ?? defaultId + pilot.id = defaultId + app.debug('*** post-discovery -> defaultId', defaultId) return { deviceid: { diff --git a/raystngconv.js b/raystngconv.js index f4aca73..99619c3 100644 --- a/raystngconv.js +++ b/raystngconv.js @@ -61,7 +61,7 @@ module.exports = function(app) { pilot.start = (props) => { deviceid = props.converterDeviceId - pilot.id = Number(deviceid) + pilot.id = deviceid app.debug('props.converterDeviceId:', deviceid) } @@ -173,8 +173,10 @@ module.exports = function(app) { } pilot.properties = () => { - let defaultConverterId = '115' + let defaultConverterId = deviceid ?? '115' let description = 'No SeaTalk-STNG-Converter device found' + + app.debug('***pre-discovery -> defaultConverterId', defaultConverterId) if ( !discovered ) { const sources = app.getPath('/sources') @@ -192,12 +194,13 @@ module.exports = function(app) { } if ( discovered ) { - converterDeviceId = discovered + defaultConverterId = discovered description = `SeaTalk-STNG-Converter with id ${discovered} discovered` app.debug(description) } - defaultConverterId = pilot.id ?? defaultConverterId + pilot.id = defaultConverterId + app.debug('*** post-discovery -> defaultConverterId', defaultConverterId) return { converterDeviceId: { From 28cda932a60dbe027c23e9590ee2f392803ec40b Mon Sep 17 00:00:00 2001 From: panaaj <38519157+panaaj@users.noreply.github.com> Date: Thu, 21 Dec 2023 17:11:09 +1030 Subject: [PATCH 5/7] Add support for autopilotAlarm interface method. --- index.js | 51 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/index.js b/index.js index fa423f6..ce9fca2 100644 --- a/index.js +++ b/index.js @@ -264,36 +264,43 @@ module.exports = function(app) { } const method = [ 'visual' ] + let state = evt.fields['Alarm Status'] if ( state === 'Alarm condition met and not silenced' ) { method.push('sound') } + if ( state === 'Alarm condition not met' ) { state = 'normal' } else { state = 'alarm' } - let alarmName = evt.fields['Alarm ID'] - if ( typeof alarmName !== 'string' ) { - alarmName = `Unknown Seatalk Alarm ${alarmName}` - } else if ( state === 'alarm' && ( - alarmName === 'WP Arrival' - || alarmName === 'Pilot Way Point Advance' - || alarmName === 'Pilot Route Complete' - ) - ) { + let alarmId = evt.fields['Alarm ID'] + + if ( typeof alarmId !== 'string' ) { + alarmId = `Unknown Seatalk Alarm ${alarmId}` + } else if ( + state === 'alarm' && + ['WP Arrival','Pilot Way Point Advance','Pilot Route Complete'].includes(alarmId) + ) { state = 'alert' } - - const path = evt.fields['Alarm Group'].toLowerCase().replace(/ /g, '') + '.' + alarmName.replace(/ /g, '') - - app.debug('notifications.' + path) - app.debug({ + + // normalise alarm name + let alarmName = normaliseAlarmId(alarmId) + if (!alarmName) { + app.debug(`*** Normalise Alarm Failed: ${alarmId}`) + return + } + + const msg = { message: alarmName, method: method, state: state - }) + } + + app.autopilotAlarm(apType, alarmName, msg) } // 65345 = 'steering.autopilot.target (windAngleApparent)' @@ -340,5 +347,19 @@ module.exports = function(app) { } + // normalise SK alarm path + const normaliseAlarmId = (id) => { + switch (id) { + case 'WP Arrival': + return 'waypointArrival' + case 'Pilot Way Point Advance': + return 'waypointAdvance' + case 'Pilot Route Complete': + return 'routeComplete' + default: + return '' + } + } + return plugin; } From a7e376c27e4c754827106108ebc0be77a14a308a Mon Sep 17 00:00:00 2001 From: panaaj <38519157+panaaj@users.noreply.github.com> Date: Mon, 25 Nov 2024 15:36:02 +1030 Subject: [PATCH 6/7] Return data to REST API calls --- index.js | 138 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 95 insertions(+), 43 deletions(-) diff --git a/index.js b/index.js index ce9fca2..a83d6c6 100644 --- a/index.js +++ b/index.js @@ -28,12 +28,29 @@ const types = { raymarineN2K: require('./raymarinen2k') } +const apData = { + options: { + states: [ + {name: 'auto', engaged: true}, + {name: 'wind', engaged: true}, + {name: 'route', engaged: true}, + {name: 'standby', engaged: false} + ], + modes: [] + }, + mode: null, + state: null, + engaged: false, + target: null +} + module.exports = function(app) { var plugin = {} var onStop = [] var autopilot var pilots = {} + let apType = '' // autopilot type _.keys(types).forEach( type => { @@ -134,24 +151,10 @@ module.exports = function(app) { app.registerAutopilotProvider( { getData: async (deviceId) => { - const apState = app.getSelfPath(state_path) - return { - options: { - states: [ - {name: 'auto', engaged: true}, - {name: 'wind', engaged: true}, - {name: 'route', engaged: true}, - {name: 'standby', engaged: false} - ], - modes: [] - }, - mode: null, - state: apState ?? null, - engaged: ['auto','wind','route'].includes(apState) ? true : false - } + return apData }, getState: async (deviceId) => { - return app.getSelfPath(state_path) ?? null + return apData.state }, setState: async ( state, @@ -161,9 +164,6 @@ module.exports = function(app) { if (r.state === 'FAILURE') { throw new Error(r.message) } - else { - return state === 'standby' ? false : true - } }, getMode: async (deviceId) => { throw new Error('Not implemented!') @@ -172,18 +172,17 @@ module.exports = function(app) { throw new Error('Not implemented!') }, getTarget: async (deviceId) => { - throw new Error('Not implemented!') + return apData.target }, setTarget: async (value, deviceId) => { - const apState = app.getSelfPath(state_path) - const deg = value * (180 / Math.PI) + const apState = apData.state if ( apState === 'auto' ) { - const r = autopilot.putTargetHeading(undefined, undefined, deg, undefined) + const r = autopilot.putTargetHeading(undefined, undefined, value, undefined) if (r.state === 'FAILURE') { throw new Error(r.message) } } else if ( apState === 'wind' ) { - const r = autopilot.putTargetWind(undefined, undefined, deg, undefined) + const r = autopilot.putTargetWind(undefined, undefined, value, undefined) if (r.state === 'FAILURE') { throw new Error(r.message) } @@ -194,8 +193,7 @@ module.exports = function(app) { value, deviceId ) => { - const deg = value * (180 / Math.PI) - const r = autopilot.putAdjustHeading(undefined, undefined, deg, undefined) + const r = autopilot.putAdjustHeading(undefined, undefined, value, undefined) if (r.state === 'FAILURE') { throw new Error(r.message) } @@ -228,6 +226,12 @@ module.exports = function(app) { deviceId ) => { throw new Error('Not implemented!') + }, + dodge: async ( + direction, + deviceId + ) => { + throw new Error('Not implemented!') } }, [apType] @@ -243,7 +247,8 @@ module.exports = function(app) { const pgns = [ 65345, 65360, 65379, 65288, - 127237 + 127237, + 126720 ] if (!pgns.includes(evt.pgn) || String(evt.src) !== autopilot.id) { @@ -300,14 +305,20 @@ module.exports = function(app) { state: state } - app.autopilotAlarm(apType, alarmName, msg) + app.autopilotUpdate(apType, { + alarm: { + path: alarmName, + value: msg + } + }) } // 65345 = 'steering.autopilot.target (windAngleApparent)' if (evt.pgn === 65345) { let angle = evt.fields['Wind Datum'] ? Number(evt.fields['Wind Datum']) : null angle = ( typeof angle === 'number' && angle > Math.PI ) ? angle-(Math.PI*2) : angle - app.autopilotUpdate(apType, 'target', angle) + apData.target = radiansToDegrees(angle) + app.autopilotUpdate(apType, {target: angle}) } // 65360 = 'steering.autopilot.target (true/magnetic)' @@ -316,32 +327,68 @@ module.exports = function(app) { const targetMagnetic = evt.fields['Target Heading Magnetic'] ? Number(evt.fields['Target Heading Magnetic']) : null const target = typeof targetTrue === 'number' ? targetTrue : typeof targetMagnetic === 'number' ? targetMagnetic: null - app.autopilotUpdate(apType, 'target', target) + apData.target = radiansToDegrees(target) + app.autopilotUpdate(apType, {target: target}) + } + + // 126720 `` + if (evt.pgn === 126720) { + //app.debug('n2k pgn=', evt.pgn, evt.fields, evt.description) } // 65379 = 'steering.autopilot.state', 'steering.autopilot.engaged' if (evt.pgn === 65379) { - const mode = evt.fields['Pilot Mode'] ? Number(evt.fields['Pilot Mode']) : null - const subMode = evt.fields['Sub Mode'] ? Number(evt.fields['Sub Mode']) : null + //app.debug('n2k pgn=', evt.pgn, evt.fields, evt.description) + const mode = typeof evt.fields['Pilot Mode Data'] === 'number' ? evt.fields['Pilot Mode Data'] : null + const subMode = typeof evt.fields['Sub Mode'] === 'number' ? evt.fields['Sub Mode'] : null + //app.debug(`mode: ${mode}, subMode: ${subMode}`) if ( mode === 0 && subMode === 0 ) { - app.autopilotUpdate(apType, 'state', 'standby') - app.autopilotUpdate(apType, 'engaged', false) + apData.state = 'standby' + apData.engaged = false + app.autopilotUpdate(apType, { + state: apData.state, + engaged: false + }) } else if ( mode == 0 && subMode == 1 ) { - app.autopilotUpdate(apType, 'state', 'wind') - app.autopilotUpdate(apType, 'engaged', true) + apData.state = 'wind' + apData.engaged = true + app.autopilotUpdate(apType, { + state: apData.state, + engaged: true + }) } else if ( (mode == 128 || mode == 129) && subMode == 1 ) { - app.autopilotUpdate(apType, 'state', 'route') - app.autopilotUpdate(apType, 'engaged', true) + apData.state = 'route' + apData.engaged = true + app.autopilotUpdate(apType, { + state: apData.state, + engaged: true + }) + } + else if ( mode == 2 && subMode == 0 ) { + apData.state = 'route' + apData.engaged = true + app.autopilotUpdate(apType, { + state: apData.state, + engaged: true + }) } else if ( mode == 64 && subMode == 0 ) { - app.autopilotUpdate(apType, 'state', 'auto') - app.autopilotUpdate(apType, 'engaged', true) + apData.state = 'auto' + apData.engaged = true + app.autopilotUpdate(apType, { + state: apData.state, + engaged: true + }) } else { - app.autopilotUpdate(apType, 'state', 'standby') - app.autopilotUpdate(apType, 'engaged', false) + apData.state = 'standby' + apData.engaged = false + app.autopilotUpdate(apType, { + state: apData.state, + engaged: false + }) } } @@ -357,9 +404,14 @@ module.exports = function(app) { case 'Pilot Route Complete': return 'routeComplete' default: - return '' + return 'unknown' } } + const radiansToDegrees = (value) => value * 180 / Math.PI + + const degreesToRadians = (value) => value * (Math.PI/180.0) + + return plugin; } From 98bf110214bcc5940e4c79c2abed12c69b8b213b Mon Sep 17 00:00:00 2001 From: panaaj <38519157+panaaj@users.noreply.github.com> Date: Sat, 30 Nov 2024 16:09:35 +1030 Subject: [PATCH 7/7] chore: format --- index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 78f7034..622155c 100644 --- a/index.js +++ b/index.js @@ -95,9 +95,6 @@ module.exports = function(app) { advance, autopilot.putAdvanceWaypoint) - registerProvider() - - app.handleMessage(plugin.id, { updates: [ { @@ -131,6 +128,8 @@ module.exports = function(app) { } ] }) + + registerProvider() } plugin.stop = function() {