Skip to content

Commit

Permalink
feature: use canboat v4 or canboatjs v2 (#263)
Browse files Browse the repository at this point in the history
Use canboatjs v2 so that we can use the latest PGN definitions from upstream https://github.com/canboat/canboat
  • Loading branch information
sbender9 authored Oct 1, 2023
1 parent c6ffb1a commit 20d0544
Show file tree
Hide file tree
Showing 43 changed files with 619 additions and 652 deletions.
53 changes: 2 additions & 51 deletions aisShipTypeMapping.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const schema = require('@signalk/signalk-schema')
const { lookupEnumerationValue } = require('@canboat/canboatjs')

module.exports = function (type) {
const num = mapping[type]
const num = lookupEnumerationValue('SHIP_TYPE', type)
var name
if (typeof num !== 'undefined' && (name = schema.getAISShipTypeName(num))) {
return {
Expand All @@ -12,53 +13,3 @@ module.exports = function (type) {
return null
}
}

const mapping = {
unavailable: 0,
'Wing In Ground': 20,
'Wing In Ground (no other information)': 29,
Fishing: 30,
Towing: 31,
'Towing exceeds 200m or wider than 25m': 32,
'Engaged in dredging or underwater operations': 33,
'Engaged in diving operations': 34,
'Engaged in military operations': 35,
Sailing: 36,
Pleasure: 37,
'High speed craft': 40,
'High speed craft carrying dangerous goods': 41,
'High speed craft hazard cat B': 42,
'High speed craft hazard cat C': 43,
'High speed craft hazard cat D': 44,
'High speed craft (no additional information)': 49,
'Pilot vessel': 50,
SAR: 51,
Tug: 52,
'Port tender': 53,
'Anti-pollution': 54,
'Law enforcement': 55,
Spare: 56,
'Spare #2': 57,
Medical: 58,
'RR Resolution No.1': 59,
'Passenger ship': 60,
'Passenger ship (no additional information)': 69,
'Cargo ship': 70,
'Cargo ship carrying dangerous goods': 71,
'Cargo ship hazard cat B': 72,
'Cargo ship hazard cat C': 73,
'Cargo ship hazard cat D': 74,
'Cargo ship (no additional information)': 79,
Tanker: 80,
'Tanker carrying dangerous goods': 81,
'Tanker hazard cat B': 82,
'Tanker hazard cat C': 83,
'Tanker hazard cat D': 84,
'Tanker (no additional information)': 89,
Other: 90,
'Other carrying dangerous goods': 91,
'Other hazard cat B': 92,
'Other hazard cat C': 93,
'Other hazard cat D': 94,
'Other (no additional information)': 99
}
26 changes: 16 additions & 10 deletions fusion/130820.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

const { timeToSeconds } = require('../utils.js')
var currentFusionSource = null
var fusionSources = {}

Expand Down Expand Up @@ -26,13 +26,19 @@ module.exports = [
node: function(n2k) { return 'entertainment.device.fusion1.avsource.source' + currentFusionSource + '.track.name'} ,
filter: function(n2k) { return n2k.fields['Message ID'] == 'Track Title' && n2k.fields.Track != 0 && currentFusionSource != null }
}, {
source: 'Progress',
//source: 'Progress',
node: function(n2k) { return 'entertainment.device.fusion1.avsource.source' + currentFusionSource + '.track.elapsedTime'} ,
filter: function(n2k) { return n2k.fields['Message ID'] == 'Track Progress' && currentFusionSource != null }
filter: function(n2k) { return n2k.fields['Message ID'] == 'Track Progress' && currentFusionSource != null },
value: function(n2k) {
return timeToSeconds(n2k.fields['Progress'])
}
}, {
source: 'Track Length',
//source: 'Length',
node: function(n2k) { return 'entertainment.device.fusion1.avsource.source' + currentFusionSource + '.track.length'} ,
filter: function(n2k) { return n2k.fields['Message ID'] == 'Track Info' && currentFusionSource != null }
filter: function(n2k) { return n2k.fields['Message ID'] == 'Track Info' && currentFusionSource != null },
value: function(n2k) {
return timeToSeconds(n2k.fields['Length'])
}
}, {
source: 'Artist',
node: function(n2k) { return 'entertainment.device.fusion1.avsource.source' + currentFusionSource + '.track.artistName'} ,
Expand Down Expand Up @@ -125,35 +131,35 @@ module.exports = [
node: function(n2k) { return 'entertainment.device.fusion1.avsource.source' + currentFusionSource + '.playbackState'} ,
value: function(n2k) {
var val = n2k.fields['Transport']
return val == 'Paused' ? 'Paused' : 'Playing'
return val == 'Paused' || val == 'Stop' ? 'Paused' : 'Playing'
},
filter: function(n2k) { return n2k.fields['Message ID'] == 'Track Info' }
}, {
node: 'entertainment.device.fusion1.output.zone1.isMuted',
value: function(n2k) {
var val = n2k.fields['Mute']
return val == 'Muted' ? true : false
return val == 'Mute On' ? true : false
},
filter: function(n2k) { return n2k.fields['Message ID'] == 'Mute' }
}, {
node: 'entertainment.device.fusion1.output.zone2.isMuted',
value: function(n2k) {
var val = n2k.fields['Mute']
return val == 'Muted' ? true : false
return val == 'Mute On' ? true : false
},
filter: function(n2k) { return n2k.fields['Message ID'] == 'Mute' }
}, {
node: 'entertainment.device.fusion1.output.zone3.isMuted',
value: function(n2k) {
var val = n2k.fields['Mute']
return val == 'Muted' ? true : false
return val == 'Mute On' ? true : false
},
filter: function(n2k) { return n2k.fields['Message ID'] == 'Mute' }
}, {
node: 'entertainment.device.fusion1.output.zone4.isMuted',
value: function(n2k) {
var val = n2k.fields['Mute']
return val == 'Muted' ? true : false
return val == 'Mute On' ? true : false
},
filter: function(n2k) { return n2k.fields['Message ID'] == 'Mute' }

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@signalk/n2k-signalk",
"version": "2.7.0",
"version": "3.0.0-beta.1",
"description": "NMEA 2000 to SignalK conversion library",
"main": "n2kMapper.js",
"scripts": {
Expand All @@ -21,10 +21,10 @@
"license": "Apache-2.0",
"repository": "https://github.com/SignalK/n2k-signalk",
"dependencies": {
"@canboat/canboatjs": "^1.13.1",
"JSONStream": "~1.3.0",
"@canboat/canboatjs": "^2.1.0",
"debug": "^4.0.0",
"int64-buffer": "^0.99.1007",
"JSONStream": "~1.3.0",
"lodash": "^4.17.11",
"through": ">=2.2.7 <3"
},
Expand Down
4 changes: 2 additions & 2 deletions pgns/126983.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ module.exports = [

//if the alert is silenced or acknowledged then dont alert in SK
if (
n2k.fields['Temporary Silence Status'] == 'Temporary Silence' ||
n2k.fields['Acknowledge Status'] == 'Acknowledged'
n2k.fields['Temporary Silence Status'] == 'Yes' ||
n2k.fields['Acknowledge Status'] == 'Yes'
) {
value.method = []
}
Expand Down
15 changes: 11 additions & 4 deletions pgns/127489.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
const util = require('util')
const { chooseField, skEngineId, skEngineTitle } = require('../utils.js')
const {
chooseField,
skEngineId,
skEngineTitle,
timeToSeconds
} = require('../utils.js')

module.exports = [
{
Expand Down Expand Up @@ -33,9 +38,11 @@ module.exports = [
}
},
{
source: 'Total Engine hours',
node: function (n2k) {
return 'propulsion.' + skEngineId(n2k) + '.runTime'
},
value: function (n2k) {
return timeToSeconds(n2k.fields['Total Engine hours'])
}
},
{
Expand All @@ -58,7 +65,7 @@ module.exports = [
return 'propulsion.' + skEngineId(n2k) + '.engineLoad'
},
value: function (n2k) {
var percent = Number(n2k.fields['Percent Engine Load'])
var percent = Number(n2k.fields['Engine Load'])
return isNaN(percent) ? null : percent / 100.0
}
},
Expand All @@ -67,7 +74,7 @@ module.exports = [
return 'propulsion.' + skEngineId(n2k) + '.engineTorque'
},
value: function (n2k) {
var percent = Number(n2k.fields['Percent Engine Torque'])
var percent = Number(n2k.fields['Engine Torque'])
return isNaN(percent) ? null : percent / 100.0
}
},
Expand Down
11 changes: 2 additions & 9 deletions pgns/127506.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { chooseField } = require('../utils.js')
const { chooseField, timeToSeconds } = require('../utils.js')

function instance (n2k) {
return chooseField(n2k, 'DC Instance', 'Instance')
Expand All @@ -25,14 +25,7 @@ module.exports = [
{
allowNull: true,
value: function (n2k) {
var val = n2k.fields['Time Remaining']
var res
if (typeof val !== 'undefined') {
res = val * 60 // convert to seconds
} else {
res = null
}
return res
return timeToSeconds(n2k.fields['Time Remaining'])
},
node: function (n2k) {
return 'electrical.batteries.' + instance(n2k) + '.capacity.timeRemaining'
Expand Down
6 changes: 4 additions & 2 deletions pgns/130306.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ module.exports = [
filter: function (n2k) {
return (
n2k.fields['Reference'] === 'Apparent' ||
n2k.fields['Reference'] === undefined
n2k.fields['Reference'] === undefined ||
n2k.fields['Reference'] === null
)
}
},
Expand All @@ -28,7 +29,8 @@ module.exports = [
filter: function (n2k) {
return (
n2k.fields['Reference'] === 'Apparent' ||
n2k.fields['Reference'] === undefined
n2k.fields['Reference'] === undefined ||
n2k.fields['Reference'] === null
)
},
value: function (n2k) {
Expand Down
10 changes: 5 additions & 5 deletions raymarine/126720.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ module.exports = [
},
node: 'steering.autopilot.state',
value: function (n2k) {
var mode = Number(n2k.fields['Pilot Mode'])
var mode = n2k.fields['Pilot Mode']
var subMode = Number(n2k.fields['Sub Mode'])
if (
(mode == 0 || mode == 64 || mode == 68 || mode == 72) &&
(mode == 0 || mode == 'Standby' || mode == 68 || mode == 72) &&
subMode == 0
) {
return 'standby'
} else if (
mode == 70 &&
mode == 'Wind' &&
(subMode == 0 || subMode == 4 || subMode == 8 || subMode == 12)
) {
// submodes: 0=on course, 4=off course pt/stb, 8=wind shift, submode 12 tbd
return 'wind'
} else if (mode == 74 && subMode == 0) {
} else if (mode == 'Track' && subMode == 0) {
return 'route'
} else if (mode == 66 && (subMode == 0 || subMode == 4)) {
} else if (mode == 'Auto' && (subMode == 0 || subMode == 4)) {
//subMode 4 means offcourse
return 'auto'
} else {
Expand Down
8 changes: 4 additions & 4 deletions test/126720_seatalk_STNG_pilot_mode.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe('126720 Seatalk-STNG-Converter Pilot Mode', function () {
it('complet pilot mode sentence converts track', function () {
var tree = require('./testMapper').toNested(
JSON.parse(
'{"timestamp":"2016-10-18T15:52:49.048Z","prio":7,"src":115,"dst":255,"pgn":126720,"description":"Seatalk1: Pilot Mode","fields":{"Manufacturer Code":"Raymarine","Industry Code":"Marine Industry","Pilot Mode":"74","Sub Mode":"0","Pilot Mode Data":"0"}}'
'{"timestamp":"2016-10-18T15:52:49.048Z","prio":7,"src":115,"dst":255,"pgn":126720,"description":"Seatalk1: Pilot Mode","fields":{"Manufacturer Code":"Raymarine","Industry Code":"Marine Industry","Pilot Mode":74,"Sub Mode":0,"Pilot Mode Data":"0","Proprietary ID":33264,"command":132}}'
)
)
tree.should.have.nested.property('steering.autopilot.state.value', 'route')
Expand All @@ -17,7 +17,7 @@ describe('126720 Seatalk-STNG-Converter Pilot Mode', function () {
it('complet pilot mode sentence converts auto', function () {
var tree = require('./testMapper').toNested(
JSON.parse(
'{"timestamp":"2016-09-06T22:56:27.719Z","prio":7,"src":115,"dst":255,"pgn":126720,"description":"Seatalk1: Pilot Mode","fields":{"Manufacturer Code":"Raymarine","Industry Code":"Marine Industry","Pilot Mode":"66","Sub Mode":"0","Pilot Mode Data":"0"}}'
'{"timestamp":"2016-09-06T22:56:27.719Z","prio":7,"src":115,"dst":255,"pgn":126720,"description":"Seatalk1: Pilot Mode","fields":{"Manufacturer Code":"Raymarine","Industry Code":"Marine Industry","Pilot Mode":"66","Sub Mode":"0","Pilot Mode Data":"0","Proprietary ID":33264,"command":132}}'
)
)
tree.should.have.nested.property('steering.autopilot.state.value', 'auto')
Expand All @@ -27,7 +27,7 @@ describe('126720 Seatalk-STNG-Converter Pilot Mode', function () {
it('complet pilot mode sentence converts wind', function () {
var tree = require('./testMapper').toNested(
JSON.parse(
'{"timestamp":"2016-09-06T23:01:38.822Z","prio":7,"src":115,"dst":255,"pgn":126720,"description":"Seatalk1: Pilot Mode","fields":{"Manufacturer Code":"Raymarine","Industry Code":"Marine Industry","Pilot Mode":"70","Sub Mode":"0","Pilot Mode Data":"0"}}'
'{"timestamp":"2016-09-06T23:01:38.822Z","prio":7,"src":115,"dst":255,"pgn":126720,"description":"Seatalk1: Pilot Mode","fields":{"Manufacturer Code":"Raymarine","Industry Code":"Marine Industry","Pilot Mode":"70","Sub Mode":"0","Pilot Mode Data":"0", "Proprietary ID":33264,"command":132}}'
)
)
tree.should.have.nested.property('steering.autopilot.state.value', 'wind')
Expand All @@ -37,7 +37,7 @@ describe('126720 Seatalk-STNG-Converter Pilot Mode', function () {
it('complet pilot mode sentence converts standby', function () {
var tree = require('./testMapper').toNested(
JSON.parse(
'{"timestamp":"2016-10-18T15:52:00.751Z","prio":7,"src":115,"dst":255,"pgn":126720,"description":"Seatalk1: Pilot Mode","fields":{"Manufacturer Code":"Raymarine","Industry Code":"Marine Industry","Pilot Mode":"0","Sub Mode":"0","Pilot Mode Data":"0"}}'
'{"timestamp":"2016-10-18T15:52:00.751Z","prio":7,"src":115,"dst":255,"pgn":126720,"description":"Seatalk1: Pilot Mode","fields":{"Manufacturer Code":"Raymarine","Industry Code":"Marine Industry","Pilot Mode":"0","Sub Mode":"0","Pilot Mode Data":"0","Proprietary ID":33264,"command":132}}'
)
)
tree.should.have.nested.property(
Expand Down
24 changes: 12 additions & 12 deletions test/126983_alert.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ var value = {
dataSourceInstance: 0,
'dataSourceIndex-Source': 0,
occurrence: 1,
temporarySilenceStatus: 'Not Temporary Silence',
acknowledgeStatus: 'Not Acknowledged',
escalationStatus: 'Not Escalated',
temporarySilenceSupport: 'Supported',
acknowledgeSupport: 'Supported',
escalationSupport: 'Not Supported',
temporarySilenceStatus: 'No',
acknowledgeStatus: 'No',
escalationStatus: 'No',
temporarySilenceSupport: 'Yes',
acknowledgeSupport: 'Yes',
escalationSupport: 'No',
acknowledgeSourceNetworkIDNAME: 1233993542451364400,
triggerCondition: 'Auto',
thresholdStatus: 'Threshold Exceeded',
Expand All @@ -47,7 +47,7 @@ var value = {
describe('126983 Alert', function () {
it('alert without silence or ackknowledgement', function () {
var msg = JSON.parse(
'{"canId":166725416,"prio":2,"src":40,"dst":255,"pgn":126983,"direction":"R","time":"15:48:36.090","fields":{"Alert Type":"Warning","Alert Category":"Navigational","Alert System":20,"Alert ID":23480,"Data Source Network ID NAME":6458553273545042000,"Data Source Instance":0,"Data Source Index-Source":0,"Alert Occurrence Number":1,"Temporary Silence Status":"Not Temporary Silence","Acknowledge Status":"Not Acknowledged","Escalation Status":"Not Escalated","Temporary Silence Support":"Supported","Acknowledge Support":"Supported","Escalation Support":"Not Supported","Acknowledge Source Network ID NAME":1233993542451364400,"Trigger Condition":"Auto","Threshold Status":"Threshold Exceeded","Alert Priority":187,"Alert State":"Active"},"description":"Alert","timestamp":"2020-03-03T15:48:36.494Z"}'
'{"canId":166725416,"prio":2,"src":40,"dst":255,"pgn":126983,"direction":"R","time":"15:48:36.090","fields":{"Alert Type":"Warning","Alert Category":"Navigational","Alert System":20,"Alert ID":23480,"Data Source Network ID NAME":6458553273545042000,"Data Source Instance":0,"Data Source Index-Source":0,"Alert Occurrence Number":1,"Temporary Silence Status":"Not Temporary Silence","Acknowledge Status":"Not Acknowledged","Escalation Status":"Not Escalated","Temporary Silence Support":"Yes","Acknowledge Support":"Yes","Escalation Support":"Not Supported","Acknowledge Source Network ID NAME":1233993542451364400,"Trigger Condition":"Auto","Threshold Status":"Threshold Exceeded","Alert Priority":187,"Alert State":"Active"},"description":"Alert","timestamp":"2020-03-03T15:48:36.494Z"}'
)
var tree = mapper.toNested(msg, state)
tree.should.have.nested.property(
Expand All @@ -65,10 +65,10 @@ describe('126983 Alert', function () {
it('alert with temporary silence', function () {
//method should be empty for this test
value.method = []
value.temporarySilenceStatus = 'Temporary Silence'
value.temporarySilenceStatus = 'Yes'

var msg = JSON.parse(
'{"canId":166725416,"prio":2,"src":40,"dst":255,"pgn":126983,"direction":"R","time":"15:48:36.090","fields":{"Alert Type":"Warning","Alert Category":"Navigational","Alert System":20,"Alert ID":23480,"Data Source Network ID NAME":6458553273545042000,"Data Source Instance":0,"Data Source Index-Source":0,"Alert Occurrence Number":1,"Temporary Silence Status":"Temporary Silence","Acknowledge Status":"Not Acknowledged","Escalation Status":"Not Escalated","Temporary Silence Support":"Supported","Acknowledge Support":"Supported","Escalation Support":"Not Supported","Acknowledge Source Network ID NAME":1233993542451364400,"Trigger Condition":"Auto","Threshold Status":"Threshold Exceeded","Alert Priority":187,"Alert State":"Active"},"description":"Alert","timestamp":"2020-03-03T15:48:36.494Z"}'
'{"canId":166725416,"prio":2,"src":40,"dst":255,"pgn":126983,"direction":"R","time":"15:48:36.090","fields":{"Alert Type":"Warning","Alert Category":"Navigational","Alert System":20,"Alert ID":23480,"Data Source Network ID NAME":6458553273545042000,"Data Source Instance":0,"Data Source Index-Source":0,"Alert Occurrence Number":1,"Temporary Silence Status":"Yes","Acknowledge Status":"Not Acknowledged","Escalation Status":"Not Escalated","Temporary Silence Support":"Yes","Acknowledge Support":"Yes","Escalation Support":"Not Supported","Acknowledge Source Network ID NAME":1233993542451364400,"Trigger Condition":"Auto","Threshold Status":"Threshold Exceeded","Alert Priority":187,"Alert State":"Active"},"description":"Alert","timestamp":"2020-03-03T15:48:36.494Z"}'
)
var tree = mapper.toNested(msg, state)
tree.should.have.nested.property(
Expand All @@ -84,11 +84,11 @@ describe('126983 Alert', function () {
})

it('alert with acknowledgement', function () {
value.temporarySilenceStatus = 'Not Temporary Silence'
value.acknowledgeStatus = 'Acknowledged'
value.temporarySilenceStatus = 'No'
value.acknowledgeStatus = 'Yes'

var msg = JSON.parse(
'{"canId":166725416,"prio":2,"src":40,"dst":255,"pgn":126983,"direction":"R","time":"15:48:36.090","fields":{"Alert Type":"Warning","Alert Category":"Navigational","Alert System":20,"Alert ID":23480,"Data Source Network ID NAME":6458553273545042000,"Data Source Instance":0,"Data Source Index-Source":0,"Alert Occurrence Number":1,"Temporary Silence Status":"Not Temporary Silence","Acknowledge Status":"Acknowledged","Escalation Status":"Not Escalated","Temporary Silence Support":"Supported","Acknowledge Support":"Supported","Escalation Support":"Not Supported","Acknowledge Source Network ID NAME":1233993542451364400,"Trigger Condition":"Auto","Threshold Status":"Threshold Exceeded","Alert Priority":187,"Alert State":"Active"},"description":"Alert","timestamp":"2020-03-03T15:48:36.494Z"}'
'{"canId":166725416,"prio":2,"src":40,"dst":255,"pgn":126983,"direction":"R","time":"15:48:36.090","fields":{"Alert Type":"Warning","Alert Category":"Navigational","Alert System":20,"Alert ID":23480,"Data Source Network ID NAME":6458553273545042000,"Data Source Instance":0,"Data Source Index-Source":0,"Alert Occurrence Number":1,"Temporary Silence Status":"No","Acknowledge Status":"Yes","Escalation Status":"Not Escalated","Temporary Silence Support":"Yes","Acknowledge Support":"Yes","Escalation Support":"Not Supported","Acknowledge Source Network ID NAME":1233993542451364400,"Trigger Condition":"Auto","Threshold Status":"Threshold Exceeded","Alert Priority":187,"Alert State":"Active"},"description":"Alert","timestamp":"2020-03-03T15:48:36.494Z"}'
)
var tree = mapper.toNested(msg, state)
tree.should.have.nested.property(
Expand Down
Loading

0 comments on commit 20d0544

Please sign in to comment.