Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: set the transmit pgn list on the Actisens NGT-1 #124

Merged
merged 3 commits into from
Aug 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/candevice.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const addressClaim = {
"Reserved2": 2
}

const deviceTransmitPGNs = [ 60928, 59904, 126996, 126464 ]

class CanDevice extends EventEmitter {
constructor (canbus, options) {
super()
Expand All @@ -50,7 +52,7 @@ class CanDevice extends EventEmitter {
this.foundConflict = false
this.devices = {}

this.transmitPGNs = defaultTransmitPGNs
this.transmitPGNs = _.union(deviceTransmitPGNs, defaultTransmitPGNs)
if ( this.options.transmitPGNs ) {
this.transmitPGNs = _.union(this.transmitPGNs,
this.options.transmitPGNs)
Expand Down
11 changes: 6 additions & 5 deletions lib/codes.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ const industryNames = invert(industryCodes)
industryNames['Marine'] = 4

const defaultTransmitPGNs = [
60928,
59904,
126996,
126464,
126992,
128267,
129794,
129038,
Expand All @@ -54,7 +51,11 @@ const defaultTransmitPGNs = [
126720,
127489,
127488,
130312
130311,
130312,
127257,
128259,
127502
]

const manufacturerCodes = invert(manufacturerNames)
Expand Down
208 changes: 181 additions & 27 deletions lib/serial.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

const debug = require('debug')('signalk:canbusjs')
const debug = require('debug')('signalk:actisense-serial')
const debugOut = require('debug')('signalk:actisense-out')
const Transform = require('stream').Transform
const SerialPort = require('serialport')
Expand All @@ -23,6 +23,7 @@ const BitStream = require('bit-buffer').BitStream
const BitView = require('bit-buffer').BitView
const { toPgn } = require('./toPgn')
const { encodeActisense } = require('./stringMsg')
const { defaultTransmitPGNs } = require('./codes')
const _ = require('lodash')

/* ASCII characters used to mark packet start/stop */
Expand Down Expand Up @@ -66,6 +67,13 @@ function SerialStream (options) {
this.reconnect = options.reconnect || true
this.serial = null
this.options = options

this.transmitPGNs = defaultTransmitPGNs
if ( this.options.transmitPGNs ) {
this.transmitPGNs = _.union(this.transmitPGNs,
this.options.transmitPGNs)
}

this.start()
}

Expand Down Expand Up @@ -103,22 +111,7 @@ SerialStream.prototype.start = function () {
}
: () => {}
var that = this
this.serial.on(
'open',
function () {
try {
setProviderStatus(`Connected to ${that.options.device}`)
var buf = composeMessage(NGT_MSG_SEND, Buffer.from(NGT_STARTUP_MSG), NGT_STARTUP_MSG.length)
that.serial.write(buf)
debug('sent startup message')
} catch ( err ) {
setProviderError(err.message)
console.error(err)
console.error(err.stack)
}
}
)


this.serial.on('data', (data) => {
try {
readData(this, data)
Expand Down Expand Up @@ -146,20 +139,24 @@ SerialStream.prototype.start = function () {
}

this.options.app.on(this.options.outEevent || 'nmea2000out', msg => {
if ( typeof msg === 'string' ) {
writeString(msg)
} else {
writeObject(msg)
if ( this.outAvailable ) {
if ( typeof msg === 'string' ) {
writeString(msg)
} else {
writeObject(msg)
}
}
})

this.options.app.on('nmea2000JsonOut', msg => {
writeObject(msg)
if ( this.outAvailable ) {
writeObject(msg)
}
})

this.options.app.emit('nmea2000OutAvailable')
}

this.outAvailable = false

this.serial.on('error', function (x) {
setProviderError(x.message)
console.log(x)
Expand All @@ -168,6 +165,27 @@ SerialStream.prototype.start = function () {
setProviderError('Closed, reconnecting...')
this.start.bind(this)
})
this.serial.on(
'open',
function () {
try {
setProviderStatus(`Connected to ${that.options.device}`)
var buf = composeMessage(NGT_MSG_SEND, Buffer.from(NGT_STARTUP_MSG), NGT_STARTUP_MSG.length)
that.serial.write(buf)
debug('sent startup message')
setTimeout(() => {
if ( that.outAvailable === false ) {
debug('retry startup message...')
that.serial.write(buf)
}
}, 5000)
} catch ( err ) {
setProviderError(err.message)
console.error(err)
console.error(err.stack)
}
}
)
}
}

Expand Down Expand Up @@ -206,8 +224,8 @@ function read1Byte(that, c)
processN2KMessage(that, that.buffer, that.bufferOffset)
//that.push(that.buffer.slice(2, that.bufferOffset))
} else if ( that.buffer[0] == NGT_MSG_RECEIVED) {
processNTGMessage(that.buffer.slice(2, that.bufferOffset))
}
processNTGMessage(that, that.buffer, that.bufferOffset)
}
that.bufferOffset = 0
that.stat = MSG_START;
}
Expand Down Expand Up @@ -253,8 +271,92 @@ function read1Byte(that, c)
}
}

function processNTGMessage(buffer)
function enableTXPGN(serial, pgn) {
debug('enabling pgn %d', pgn)
serial.write(composeEnablePGN(pgn))
}

function enableOutput(that) {
debug('outputEnabled')
that.outAvailable = true
if ( that.options.app ) {
that.options.app.emit('nmea2000OutAvailable')
}
}

function processNTGMessage(that, buffer, len)
{
var checksum = 0

for ( var i = 0; i < len; i++ ) {
checksum = addUInt8(checksum, buffer[i])
}

if ( checksum != 0 ) {
debug('received message with invalid checksum')
return
}

const command = buffer[2]

/*
console.log('got msg ' + command.toString(16))

if ( command != 0xf2 ) {
let data = new Uint32Array(buffer.slice(0, len))
.reduce(function(acc, i) {
acc.push(i.toString(16));
return acc;
}, [])
.map(x => (x.length === 1 ? "0" + x : x))
.join(" ")
console.log(data)
}*/

if ( command === 0x11 ) {
//confirm startup
debug('request tx pgns...')
that.serial.write(composeRequestTXPGNList())
} else if ( command === 0x49 && buffer[3] === 1 ) {
const pgnCount = buffer[14];
let bv = new BitView(buffer.slice(15, that.bufferOffset));
let bs = new BitStream(bv)
let pgns = []
for ( let i = 0; i < pgnCount; i++ ) {
pgns.push(bs.readUint32())
}
debug('tx pgns: %j', pgns)

that.neededTransmitPGNs = that.transmitPGNs.filter(pgn => {
return pgns.indexOf(pgn) == -1
})
debug('needed pgns: %j', that.neededTransmitPGNs)
} else if ( command === 0x49 && buffer[3] === 4 ) {
if ( that.neededTransmitPGNs.length ) {
enableTXPGN(that.serial, that.neededTransmitPGNs[0])
} else {
enableOutput(that)
}
} else if ( command === 0x47 ) {
if ( buffer[3] === 1 ) {
debug('enabled %d', that.neededTransmitPGNs[0])
that.neededTransmitPGNs = that.neededTransmitPGNs.slice(1)
if ( that.neededTransmitPGNs.length === 0 ) {
that.serial.write(composeCommitTXPGN())
} else {
enableTXPGN(that.serial, that.neededTransmitPGNs[0])
}
} else {
debug('bad response from Enable TX: %d', buffer[3])
}
} else if ( command === 0x01 ) {
debug('commited tx list')
that.serial.write(composeActivateTXPGN())
} else if ( command === 0x4b ) {
debug('activated tx list')
enableOutput(that)
}

/*
if (buffer.length < 12)
{
Expand Down Expand Up @@ -401,6 +503,58 @@ function parseInput(msg)
return bs.view.buffer.slice(0, bs.byteIndex)
}

function composeCommitTXPGN() {
let msg = new Uint32Array([0x01])
return composeMessage(NGT_MSG_SEND, Buffer.from(msg), msg.length)
}

function composeActivateTXPGN() {
let msg = new Uint32Array([0x4b])
return composeMessage(NGT_MSG_SEND, Buffer.from(msg), msg.length)
}

function composeRequestTXPGNList() {
let msg = new Uint32Array([0x49])
return composeMessage(NGT_MSG_SEND, Buffer.from(msg), msg.length)
}

function composeEnablePGN(pgn) {
var outBuf = Buffer.alloc(14);
let out = new BitStream(outBuf)
out.writeUint8(0x47)
out.writeUint32(pgn)
out.writeUint8(1) //enabled

out.writeUint32(0xfffffffe)
out.writeUint32(0xfffffffe)

let res = composeMessage(NGT_MSG_SEND, out.view.buffer.slice(0, out.byteIndex), out.byteIndex)

//debug('composeEnablePGN: %o', res)

return res;
}

function composeDisablePGN(pgn) {
var outBuf = Buffer.alloc(14);
let out = new BitStream(outBuf)
out.writeUint8(0x47)
out.writeUint32(pgn)
out.writeUint8(0) //disabled

//disbale system time
//10 02 a1 0e 47 10 10 f0 01 00 00 e8 03 00 00 00 00 00 00 1e 10 03

out.writeUint32(0x000003e8) //???
out.writeUint32(0x00)

let res = composeMessage(NGT_MSG_SEND, out.view.buffer.slice(0, out.byteIndex), out.byteIndex)

debug('composeDisablePGN: %o', res)

return res;
}

SerialStream.prototype.end = function () {
this.serial.close()
}
Expand Down