@canboat/canboatjs 2.1.1 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/analyzerjs +18 -2
- package/index.js +1 -1
- package/lib/fromPgn.js +51 -46
- package/lib/pgns.js +61 -53
- package/lib/toPgn.js +25 -31
- package/package.json +2 -2
package/bin/analyzerjs
CHANGED
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const argv = require('minimist')(process.argv.slice(2)
|
|
3
|
+
const argv = require('minimist')(process.argv.slice(2), {
|
|
4
|
+
alias: { h: 'help' },
|
|
5
|
+
boolean: ['n']
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
if ( argv['help'] ) {
|
|
9
|
+
console.error(`Usage: ${process.argv[1]} [options]
|
|
10
|
+
|
|
11
|
+
Options:
|
|
12
|
+
-c don't check for invalid values
|
|
13
|
+
-n output null values
|
|
14
|
+
-h, --help output usage information`)
|
|
15
|
+
process.exit(1)
|
|
16
|
+
}
|
|
4
17
|
|
|
5
18
|
const Parser = require('../index').FromPgn
|
|
6
|
-
var parser = new Parser(
|
|
19
|
+
var parser = new Parser( {
|
|
20
|
+
returnNulls: argv['n'] === true,
|
|
21
|
+
checkForInvalidFields: argv['n']
|
|
22
|
+
})
|
|
7
23
|
|
|
8
24
|
parser.on('error', (pgn, error) => {
|
|
9
25
|
console.error(`Error parsing ${pgn.pgn} ${error}`)
|
package/index.js
CHANGED
|
@@ -39,7 +39,7 @@ module.exports = {
|
|
|
39
39
|
VenusMQTT: require('./lib/venus-mqtt'),
|
|
40
40
|
discover: require('./lib/discovery'),
|
|
41
41
|
SimpleCan: require('./lib/simpleCan'),
|
|
42
|
-
|
|
42
|
+
addCustomPgns: pgns.addCustomPgns,
|
|
43
43
|
lookupEnumerationValue: pgns.lookupEnumerationValue,
|
|
44
44
|
lookupEnumerationName: pgns.lookupEnumerationName
|
|
45
45
|
}
|
package/lib/fromPgn.js
CHANGED
|
@@ -19,7 +19,7 @@ const trace = require('debug')('canboatjs:fromPgn:trace')
|
|
|
19
19
|
const EventEmitter = require('events')
|
|
20
20
|
const pkg = require('../package.json')
|
|
21
21
|
const _ = require('lodash')
|
|
22
|
-
const { pgns, getCustomPgn,
|
|
22
|
+
const { pgns, getCustomPgn, addCustomPgns, lookupEnumerationName, lookupBitEnumerationName } = require('./pgns')
|
|
23
23
|
const BitStream = require('bit-buffer').BitStream
|
|
24
24
|
const BitView = require('bit-buffer').BitView
|
|
25
25
|
const Int64LE = require('int64-buffer').Int64LE
|
|
@@ -60,6 +60,10 @@ class Parser extends EventEmitter {
|
|
|
60
60
|
super()
|
|
61
61
|
this.options = _.isUndefined(opts) ? {} : opts
|
|
62
62
|
|
|
63
|
+
if ( this.options.returnNulls === undefined ) {
|
|
64
|
+
this.options.returnNulls = false
|
|
65
|
+
}
|
|
66
|
+
|
|
63
67
|
this.name = pkg.name
|
|
64
68
|
this.version = pkg.version
|
|
65
69
|
this.author = pkg.author
|
|
@@ -71,12 +75,7 @@ class Parser extends EventEmitter {
|
|
|
71
75
|
if ( this.options.onPropertyValues ) {
|
|
72
76
|
this.options.onPropertyValues('canboat-custom-pgns', values => {
|
|
73
77
|
values.filter(v => v != null).forEach(pv => {
|
|
74
|
-
pv.value.
|
|
75
|
-
if ( !addCustomPgn(pgn, pv.value.callback) ) {
|
|
76
|
-
this.emit('warning', pgn, `pgn ${pgn.PGN} can't be overwritten`)
|
|
77
|
-
}
|
|
78
|
-
debug('registered custom pgn %d by %s', pgn.PGN, pv.setter)
|
|
79
|
-
})
|
|
78
|
+
addCustomPgns(pv.value, pv.setter)
|
|
80
79
|
})
|
|
81
80
|
})
|
|
82
81
|
}
|
|
@@ -221,7 +220,7 @@ class Parser extends EventEmitter {
|
|
|
221
220
|
pgnList = [ nonMatch ]
|
|
222
221
|
pgnData = pgnList[0]
|
|
223
222
|
fields = pgnData.Fields
|
|
224
|
-
var postProcessor = fieldTypePostProcessors[field.
|
|
223
|
+
var postProcessor = fieldTypePostProcessors[field.FieldType]
|
|
225
224
|
if ( postProcessor ) {
|
|
226
225
|
value = postProcessor(pgnData.Fields[i], value)
|
|
227
226
|
}
|
|
@@ -240,7 +239,8 @@ class Parser extends EventEmitter {
|
|
|
240
239
|
}
|
|
241
240
|
}
|
|
242
241
|
|
|
243
|
-
if ( !_.isUndefined(value) && value != null
|
|
242
|
+
if ( !_.isUndefined(value) && (value != null ||
|
|
243
|
+
this.options.returnNulls) ) {
|
|
244
244
|
pgn.fields[field.Name] = value
|
|
245
245
|
}
|
|
246
246
|
}
|
|
@@ -543,29 +543,18 @@ function pad(n, p, c)
|
|
|
543
543
|
}
|
|
544
544
|
|
|
545
545
|
function lookup(field, value) {
|
|
546
|
-
var name =
|
|
546
|
+
var name = lookupEnumerationName(field.LookupEnumeration, value)
|
|
547
547
|
return name ? name : value
|
|
548
548
|
}
|
|
549
549
|
|
|
550
|
-
function lookupBitField(field, value) {
|
|
551
|
-
if (!field.value2name) {
|
|
552
|
-
field.value2name = {};
|
|
553
|
-
field.EnumBitValues.forEach(function(enumPair) {
|
|
554
|
-
var key = _.keys(enumPair)[0]
|
|
555
|
-
field.value2name[Number(key)] = enumPair[key]
|
|
556
|
-
})
|
|
557
|
-
}
|
|
558
|
-
return (field.value2name[value]);
|
|
559
|
-
}
|
|
560
|
-
|
|
561
550
|
function readField(options, runPostProcessor, pgn, field, bs) {
|
|
562
551
|
var value
|
|
563
552
|
|
|
564
|
-
var reader = fieldTypeReaders[field.
|
|
553
|
+
var reader = fieldTypeReaders[field.FieldType]
|
|
565
554
|
if ( reader ) {
|
|
566
555
|
value = reader(pgn, field, bs)
|
|
567
556
|
} else {
|
|
568
|
-
if ( field.
|
|
557
|
+
if ( field.FieldType !== RES_BINARY && bs.bitsLeft < field.BitLength ) {
|
|
569
558
|
//no more data
|
|
570
559
|
bs.readBits(bs.bitsLeft, false)
|
|
571
560
|
return
|
|
@@ -576,7 +565,7 @@ function readField(options, runPostProcessor, pgn, field, bs) {
|
|
|
576
565
|
//console.log(`${field.Name} ${value} ${field.Resolution}`)
|
|
577
566
|
|
|
578
567
|
if ( value != null && !_.isUndefined(value) ) {
|
|
579
|
-
let type = field.
|
|
568
|
+
let type = field.FieldType //hack, missing type
|
|
580
569
|
var postProcessor = fieldTypePostProcessors[type]
|
|
581
570
|
if ( postProcessor ) {
|
|
582
571
|
if ( runPostProcessor ) {
|
|
@@ -586,7 +575,18 @@ function readField(options, runPostProcessor, pgn, field, bs) {
|
|
|
586
575
|
if ( field.Offset ) {
|
|
587
576
|
value += field.Offset
|
|
588
577
|
}
|
|
589
|
-
|
|
578
|
+
let max
|
|
579
|
+
if ( typeof field.RangeMax !== 'undefined'
|
|
580
|
+
&& field.Resolution ) {
|
|
581
|
+
max = field.RangeMax / field.Resolution
|
|
582
|
+
}
|
|
583
|
+
if ( options.checkForInvalidFields !== false && max !== 'undefined' &&
|
|
584
|
+
field.FieldType !== 'LOOKUP' &&
|
|
585
|
+
field.BitLength > 1 &&
|
|
586
|
+
max - value <= 0 ) {
|
|
587
|
+
//console.log(`Bad field ${field.Name} ${max - value}`)
|
|
588
|
+
value = null
|
|
589
|
+
} if ( field.Resolution && typeof value === 'number' ) {
|
|
590
590
|
var resolution = field.Resolution
|
|
591
591
|
|
|
592
592
|
if ( _.isString(resolution) ) {
|
|
@@ -602,16 +602,10 @@ function readField(options, runPostProcessor, pgn, field, bs) {
|
|
|
602
602
|
}
|
|
603
603
|
|
|
604
604
|
value = Number.parseFloat(value.toFixed(precision))
|
|
605
|
-
|
|
606
|
-
/*
|
|
607
|
-
if ( resolution === 3.125e-8 ) {
|
|
608
|
-
//yes. hack.
|
|
609
|
-
resolution = "0.0000000001"
|
|
610
|
-
}
|
|
611
|
-
*/
|
|
612
605
|
}
|
|
613
606
|
|
|
614
|
-
if (field.
|
|
607
|
+
if (field.FieldType === 'LOOKUP' &&
|
|
608
|
+
runPostProcessor &&
|
|
615
609
|
(_.isUndefined(options.resolveEnums) ||
|
|
616
610
|
options.resolveEnums)) {
|
|
617
611
|
if (field.Id === "timeStamp" && value < 60) {
|
|
@@ -628,9 +622,9 @@ function readField(options, runPostProcessor, pgn, field, bs) {
|
|
|
628
622
|
}
|
|
629
623
|
}
|
|
630
624
|
|
|
631
|
-
if ( field.
|
|
625
|
+
if ( field.Unit === "kWh" ) {
|
|
632
626
|
value *= 3.6e6; // 1 kWh = 3.6 MJ.
|
|
633
|
-
} else if (field.
|
|
627
|
+
} else if (field.Unit === "Ah") {
|
|
634
628
|
value *= 3600.0; // 1 Ah = 3600 C.
|
|
635
629
|
}
|
|
636
630
|
}
|
|
@@ -643,7 +637,7 @@ function readValue(options, pgn, field, bs, bitLength) {
|
|
|
643
637
|
if ( _.isUndefined(bitLength) ) {
|
|
644
638
|
bitLength = field.BitLength
|
|
645
639
|
}
|
|
646
|
-
if (
|
|
640
|
+
if ( field.FieldType == 'VARIABLE' ) {
|
|
647
641
|
return readVariableLengthField(options, pgn, field, bs)
|
|
648
642
|
} else if (bitLength === 8) {
|
|
649
643
|
if ( field.Signed ) {
|
|
@@ -713,6 +707,7 @@ function readValue(options, pgn, field, bs, bitLength) {
|
|
|
713
707
|
}, [])
|
|
714
708
|
.map(x => (x.length === 1 ? "0" + x : x))
|
|
715
709
|
.join(" ")
|
|
710
|
+
|
|
716
711
|
return value
|
|
717
712
|
}
|
|
718
713
|
|
|
@@ -767,7 +762,10 @@ function readVariableLengthField(options, pgn, field, bs) {
|
|
|
767
762
|
}
|
|
768
763
|
}
|
|
769
764
|
|
|
770
|
-
fieldTypeReaders[
|
|
765
|
+
fieldTypeReaders[
|
|
766
|
+
'STRING_LAU'
|
|
767
|
+
//'ASCII or UNICODE string starting with length and control byte'
|
|
768
|
+
] = (pgn, field, bs) => {
|
|
771
769
|
|
|
772
770
|
if ( bs.bitsLeft >= 16 ) {
|
|
773
771
|
const len = bs.readUint8()-2
|
|
@@ -797,7 +795,10 @@ fieldTypeReaders['ASCII or UNICODE string starting with length and control byte'
|
|
|
797
795
|
}
|
|
798
796
|
}
|
|
799
797
|
|
|
800
|
-
fieldTypeReaders[
|
|
798
|
+
fieldTypeReaders[
|
|
799
|
+
'STRING_LZ'
|
|
800
|
+
//'ASCII string starting with length byte'
|
|
801
|
+
] = (pgn, field, bs) => {
|
|
801
802
|
var len = bs.readUint8()
|
|
802
803
|
|
|
803
804
|
var buf = Buffer.alloc(len)
|
|
@@ -842,7 +843,7 @@ fieldTypeReaders["String with start/stop byte"] = (pgn, field, bs) => {
|
|
|
842
843
|
}
|
|
843
844
|
}
|
|
844
845
|
|
|
845
|
-
fieldTypeReaders['
|
|
846
|
+
fieldTypeReaders['STRING_FIX'] = (pgn, field, bs) => {
|
|
846
847
|
var len = field.BitLength / 8
|
|
847
848
|
var buf = Buffer.alloc(len)
|
|
848
849
|
|
|
@@ -865,17 +866,19 @@ fieldTypeReaders['ASCII text'] = (pgn, field, bs) => {
|
|
|
865
866
|
return buf.toString('ascii', 0, len)
|
|
866
867
|
}
|
|
867
868
|
|
|
868
|
-
fieldTypeReaders['
|
|
869
|
+
fieldTypeReaders['BITLOOKUP'] = (pgn, field, bs) => {
|
|
869
870
|
var value = []
|
|
870
871
|
for ( var i = 0; i < field.BitLength; i++ ) {
|
|
871
872
|
if ( bs.readBits(1, 0) ) {
|
|
872
|
-
value.push(
|
|
873
|
+
value.push(
|
|
874
|
+
lookupBitEnumerationName(field.LookupBitEnumeration, i)
|
|
875
|
+
)
|
|
873
876
|
}
|
|
874
877
|
}
|
|
875
878
|
return value
|
|
876
879
|
}
|
|
877
880
|
|
|
878
|
-
fieldTypePostProcessors['
|
|
881
|
+
fieldTypePostProcessors['DATE'] = (field, value) => {
|
|
879
882
|
if ( value >= 0xfffd ) {
|
|
880
883
|
value = undefined
|
|
881
884
|
} else {
|
|
@@ -886,7 +889,7 @@ fieldTypePostProcessors['Date'] = (field, value) => {
|
|
|
886
889
|
return value
|
|
887
890
|
}
|
|
888
891
|
|
|
889
|
-
fieldTypePostProcessors['
|
|
892
|
+
fieldTypePostProcessors['TIME'] = (field, value) => {
|
|
890
893
|
if (value >= 0xfffffffd) {
|
|
891
894
|
value = undefined
|
|
892
895
|
} else {
|
|
@@ -906,9 +909,9 @@ fieldTypePostProcessors['Time'] = (field, value) => {
|
|
|
906
909
|
}
|
|
907
910
|
|
|
908
911
|
fieldTypePostProcessors['Pressure'] = (field, value) => {
|
|
909
|
-
if (field.
|
|
912
|
+
if (field.Unit)
|
|
910
913
|
{
|
|
911
|
-
switch (field.
|
|
914
|
+
switch (field.Unit[0]) {
|
|
912
915
|
case 'h':
|
|
913
916
|
case 'H':
|
|
914
917
|
value *= 100;
|
|
@@ -929,10 +932,12 @@ fieldTypePostProcessors[RES_BINARY] = (field, value) => {
|
|
|
929
932
|
return value.toString()
|
|
930
933
|
}
|
|
931
934
|
|
|
935
|
+
/*
|
|
932
936
|
fieldTypePostProcessors['Manufacturer code'] = (field, value) => {
|
|
933
937
|
var manufacturer = getManufacturerName(value)
|
|
934
938
|
return manufacturer ? manufacturer : value
|
|
935
|
-
}
|
|
939
|
+
}
|
|
940
|
+
*/
|
|
936
941
|
|
|
937
942
|
module.exports = {
|
|
938
943
|
Parser: Parser,
|
package/lib/pgns.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
const { flow, first, isArray, isEmpty, propertyOf } = require('lodash/fp')
|
|
2
2
|
const pgns = require('@canboat/pgns')
|
|
3
|
-
const pgnsIK = require('@canboat/pgns/pgns-ik')
|
|
4
|
-
const pgnsNGT = require('@canboat/pgns/pgns-ngt')
|
|
3
|
+
const pgnsIK = { PGNs: [] } //require('@canboat/pgns/pgns-ik')
|
|
4
|
+
const pgnsNGT = { PGNs: [] } //require('@canboat/pgns/pgns-ngt')
|
|
5
5
|
const _ = require('lodash')
|
|
6
|
+
const debug = require('debug')('canboatjs:pgns')
|
|
6
7
|
|
|
7
8
|
function organizePGNs() {
|
|
8
9
|
const res = {}
|
|
@@ -35,10 +36,6 @@ function organizePGNs() {
|
|
|
35
36
|
return res
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
function getField(pgn, name) {
|
|
39
|
-
return pgn.Fields.find(f => f.Name === name)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
39
|
function getEnumeration(name) {
|
|
43
40
|
const enumeration = lookupEnumerations[name]
|
|
44
41
|
if ( enumeration ) {
|
|
@@ -57,48 +54,45 @@ function getEnumeration(name) {
|
|
|
57
54
|
return enumeration
|
|
58
55
|
}
|
|
59
56
|
|
|
57
|
+
function getBitEnumeration(name) {
|
|
58
|
+
const enumeration = lookupBitEnumerations[name]
|
|
59
|
+
if ( enumeration ) {
|
|
60
|
+
if ( !enumeration.value2name ) {
|
|
61
|
+
enumeration.value2name = {}
|
|
62
|
+
enumeration.EnumBitValues.forEach((enumPair) => {
|
|
63
|
+
enumeration.value2name[Number(enumPair.Bit)] = enumPair.Name
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
enumeration.name2value = {}
|
|
67
|
+
enumeration.EnumBitValues.forEach((enumPair) => {
|
|
68
|
+
enumeration.name2value[enumPair.Name] = Number(enumPair.Bit)
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return enumeration
|
|
73
|
+
}
|
|
74
|
+
|
|
60
75
|
function lookupEnumerationName(enumName, value) {
|
|
61
76
|
const enumeration = getEnumeration(enumName)
|
|
62
|
-
return enumeration.value2name[value]
|
|
77
|
+
return enumeration && enumeration.value2name[value]
|
|
63
78
|
}
|
|
64
79
|
|
|
65
80
|
function lookupEnumerationValue(enumName, name) {
|
|
66
81
|
const enumeration = getEnumeration(enumName)
|
|
67
|
-
return enumeration.name2value[name]
|
|
82
|
+
return enumeration && enumeration.name2value[name]
|
|
68
83
|
}
|
|
69
84
|
|
|
70
|
-
function
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
field.EnumValues.forEach(function(enumPair) {
|
|
74
|
-
field.value2name[Number(enumPair.value)] = enumPair.name
|
|
75
|
-
})
|
|
76
|
-
}
|
|
77
|
-
return field.value2name
|
|
85
|
+
function lookupBitEnumerationName(enumName, value) {
|
|
86
|
+
const enumeration = getBitEnumeration(enumName)
|
|
87
|
+
return enumeration && enumeration.value2name[value]
|
|
78
88
|
}
|
|
79
89
|
|
|
80
|
-
function
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
field.EnumValues.forEach(function(enumPair) {
|
|
84
|
-
field.name2value[enumPair.name] = Number(enumPair.value)
|
|
85
|
-
})
|
|
86
|
-
}
|
|
87
|
-
return field.name2value
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function lookupEnumNameForField(field, value) {
|
|
91
|
-
let value2name = getValue2Name(field)
|
|
92
|
-
return value2name && value2name[value]
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function lookupEnumValueForField(field, stringValue) {
|
|
96
|
-
let name2value = getName2Value(field)
|
|
97
|
-
return name2value && name2value[stringValue]
|
|
90
|
+
function lookupBitEnumerationValue(enumName, name) {
|
|
91
|
+
const enumeration = getBitEnumeration(enumName)
|
|
92
|
+
return enumeration.name2value[name]
|
|
98
93
|
}
|
|
99
94
|
|
|
100
|
-
function organizeEnumerations() {
|
|
101
|
-
let enums = require('@canboat/pgns/canboat').LookupEnumerations
|
|
95
|
+
function organizeEnumerations(enums) {
|
|
102
96
|
let map = {}
|
|
103
97
|
enums.forEach(e => {
|
|
104
98
|
map[e.Name] = e
|
|
@@ -106,7 +100,8 @@ function organizeEnumerations() {
|
|
|
106
100
|
return map
|
|
107
101
|
}
|
|
108
102
|
|
|
109
|
-
const lookupEnumerations = organizeEnumerations()
|
|
103
|
+
const lookupEnumerations = organizeEnumerations(pgns.LookupEnumerations)
|
|
104
|
+
const lookupBitEnumerations = organizeEnumerations(pgns.LookupBitEnumerations)
|
|
110
105
|
const organizedPGNs = organizePGNs()
|
|
111
106
|
const getPgn = pgn => organizedPGNs[pgn]
|
|
112
107
|
const getPgn0 = flow(getPgn, first)
|
|
@@ -116,26 +111,39 @@ module.exports = {
|
|
|
116
111
|
getPgn,
|
|
117
112
|
getPgn0,
|
|
118
113
|
pgns: organizedPGNs,
|
|
119
|
-
lookupEnumValueForField,
|
|
120
|
-
lookupEnumNameForField,
|
|
121
114
|
lookupEnumerationName,
|
|
122
115
|
lookupEnumerationValue,
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
116
|
+
lookupBitEnumerationName,
|
|
117
|
+
lookupBitEnumerationValue,
|
|
118
|
+
addCustomPgns: (pgns, setter) => {
|
|
119
|
+
pgns.PGNs.forEach(pgn => {
|
|
120
|
+
if ( !customPgns[pgn.PGN] ) {
|
|
121
|
+
customPgns[pgn.PGN] = {
|
|
122
|
+
definitions: [],
|
|
123
|
+
callbacks: []
|
|
124
|
+
}
|
|
128
125
|
}
|
|
126
|
+
|
|
127
|
+
customPgns[pgn.PGN].definitions.push(pgn)
|
|
128
|
+
|
|
129
|
+
/*
|
|
130
|
+
if ( pgn.calllback ) {
|
|
131
|
+
customPgns[pgn.PGN].callbacks.push()
|
|
132
|
+
}
|
|
133
|
+
*/
|
|
134
|
+
|
|
135
|
+
debug('registered custom pgn %d by %s', pgn.PGN, setter)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
if ( pgns.LookupEnumerations ) {
|
|
139
|
+
pgns.LookupEnumerations.forEach(e => {
|
|
140
|
+
if ( !lookupEnumerations[e.Name] ) {
|
|
141
|
+
lookupEnumerations[e.Name] = e
|
|
142
|
+
} else {
|
|
143
|
+
debug(`enumeration ${e.Name} already exists`)
|
|
144
|
+
}
|
|
145
|
+
})
|
|
129
146
|
}
|
|
130
|
-
|
|
131
|
-
customPgns[pgn.PGN].definitions.push(pgn)
|
|
132
|
-
/*
|
|
133
|
-
if ( pgn.calllback ) {
|
|
134
|
-
customPgns[pgn.PGN].callbacks.push()
|
|
135
|
-
}
|
|
136
|
-
*/
|
|
137
|
-
|
|
138
|
-
return customPgns[pgn.PGN]
|
|
139
147
|
},
|
|
140
148
|
getCustomPgn: (pgnNum) => {
|
|
141
149
|
return customPgns[pgnNum]
|
package/lib/toPgn.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
const { getField } = require('./fromPgn')
|
|
18
|
-
const { pgns, getCustomPgn,
|
|
18
|
+
const { pgns, getCustomPgn, lookupEnumerationValue, lookupBitEnumerationName } = require('./pgns')
|
|
19
19
|
const _ = require('lodash')
|
|
20
20
|
const BitStream = require('bit-buffer').BitStream
|
|
21
21
|
const Int64LE = require('int64-buffer').Int64LE
|
|
@@ -27,8 +27,8 @@ const { encodeCanId } = require('./canId')
|
|
|
27
27
|
const { getIndustryCode, getManufacturerCode } = require('./codes')
|
|
28
28
|
const debug = require('debug')('canboatjs:toPgn')
|
|
29
29
|
|
|
30
|
-
const RES_STRINGLAU = 'ASCII or UNICODE string starting with length and control byte'
|
|
31
|
-
const RES_STRINGLZ = 'ASCII string starting with length byte'
|
|
30
|
+
const RES_STRINGLAU = 'STRING_LAU' //'ASCII or UNICODE string starting with length and control byte'
|
|
31
|
+
const RES_STRINGLZ = 'STRING_LZ' //'ASCII string starting with length byte'
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
var fieldTypeWriters = {}
|
|
@@ -117,8 +117,8 @@ function toPgn(data) {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
if ( pgnData.Length != 0xff
|
|
120
|
-
&& fields[fields.length-1].
|
|
121
|
-
&& fields[fields.length-1].
|
|
120
|
+
&& fields[fields.length-1].FieldType != RES_STRINGLAU
|
|
121
|
+
&& fields[fields.length-1].FieldType != RES_STRINGLZ
|
|
122
122
|
&& !RepeatingFields ) {
|
|
123
123
|
|
|
124
124
|
var len = lengthsOff[pgnData.PGN] || pgnData.Length
|
|
@@ -156,8 +156,8 @@ function writeField(bs, pgn_number, field, data, value, bitLength) {
|
|
|
156
156
|
|
|
157
157
|
// console.log(`${field.Name}:${value}(${bitLength}-${field.Resolution})`)
|
|
158
158
|
if ( _.isUndefined(value) || value === null) {
|
|
159
|
-
if ( field.
|
|
160
|
-
fieldTypeWriters[field.
|
|
159
|
+
if ( field.FieldType && fieldTypeWriters[field.FieldType] ) {
|
|
160
|
+
fieldTypeWriters[field.FieldType](pgn_number, field, value, bs)
|
|
161
161
|
} else if ( bitLength % 8 == 0 ) {
|
|
162
162
|
var bytes = bitLength/8
|
|
163
163
|
var lastByte = field.Signed ? 0x7f : 0xff
|
|
@@ -170,14 +170,14 @@ function writeField(bs, pgn_number, field, data, value, bitLength) {
|
|
|
170
170
|
bs.writeBits(0xffffffff, bitLength)
|
|
171
171
|
}
|
|
172
172
|
} else {
|
|
173
|
-
let type = field.
|
|
173
|
+
let type = field.FieldType
|
|
174
174
|
if ( field.Name === 'Industry Code' ) {
|
|
175
175
|
if ( _.isString(value) ) {
|
|
176
176
|
value = Number(getIndustryCode(value))
|
|
177
177
|
}
|
|
178
178
|
} else if ( type && fieldTypeMappers[type] ) {
|
|
179
179
|
value = fieldTypeMappers[type](field, value)
|
|
180
|
-
} else if (field.
|
|
180
|
+
} else if (field.FieldType === 'LOOKUP' && _.isString(value)) {
|
|
181
181
|
if (!(field.Id === "timeStamp" && value < 60)) {
|
|
182
182
|
value = lookup(field, value)
|
|
183
183
|
}
|
|
@@ -187,23 +187,23 @@ function writeField(bs, pgn_number, field, data, value, bitLength) {
|
|
|
187
187
|
value = Number((value / field.Resolution).toFixed(0))
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
if ( field.
|
|
191
|
-
fieldTypeWriters[field.
|
|
190
|
+
if ( field.FieldType && fieldTypeWriters[field.FieldType] ) {
|
|
191
|
+
fieldTypeWriters[field.FieldType](pgn_number, field, value, bs)
|
|
192
192
|
} else {
|
|
193
193
|
if ( _.isString(value) && typeof bitLength !== 'undefined' && bitLength !== 0 ) {
|
|
194
194
|
value = Number(value)
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
if ( field.
|
|
197
|
+
if ( field.Unit === "kWh" ) {
|
|
198
198
|
value /= 3.6e6; // 1 kWh = 3.6 MJ.
|
|
199
|
-
} else if (field.
|
|
199
|
+
} else if (field.Unit === "Ah") {
|
|
200
200
|
value /= 3600.0; // 1 Ah = 3600 C.
|
|
201
201
|
}
|
|
202
202
|
if ( field.Offset ) {
|
|
203
203
|
value -= field.Offset
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
if (
|
|
206
|
+
if ( field.FieldType === 'VARIABLE' ) {
|
|
207
207
|
writeVariableLengthField(bs, pgn_number, data, field, value)
|
|
208
208
|
} else if ( _.isBuffer(value) ) {
|
|
209
209
|
value.copy(bs.view.buffer, bs.byteIndex)
|
|
@@ -270,7 +270,7 @@ function writeVariableLengthField(bs, pgn_number, pgn, field, value) {
|
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
function lookup(field, stringValue) {
|
|
273
|
-
var res =
|
|
273
|
+
var res = lookupEnumerationValue(field.LookupEnumeration, stringValue)
|
|
274
274
|
return _.isUndefined(res) ? stringValue : res
|
|
275
275
|
}
|
|
276
276
|
|
|
@@ -326,17 +326,10 @@ const actisenseToN2KAsciiFormat = _.flow(parseActisense, encodeActisenseN2KACSII
|
|
|
326
326
|
const actisenseToN2KActisenseFormat = _.flow(parseActisense, encodeN2KActisense)
|
|
327
327
|
|
|
328
328
|
function bitIsSet(field, index, value) {
|
|
329
|
-
|
|
330
|
-
field.value2name = {};
|
|
331
|
-
field.EnumBitValues.forEach(function(enumPair) {
|
|
332
|
-
var key = _.keys(enumPair)[0]
|
|
333
|
-
field.value2name[Number(key)] = enumPair[key]
|
|
334
|
-
})
|
|
335
|
-
}
|
|
336
|
-
return value.indexOf(field.value2name[index]) != -1
|
|
329
|
+
return value.indexOf(lookupBitEnumerationName(field.LookupBitEnumeration, index)) != -1
|
|
337
330
|
}
|
|
338
331
|
|
|
339
|
-
fieldTypeWriters['
|
|
332
|
+
fieldTypeWriters['BITLOOKUP'] = (pgn, field, value, bs) => {
|
|
340
333
|
if ( _.isUndefined(value) || value.length === 0 ) {
|
|
341
334
|
if ( field.BitLength % 8 == 0 ) {
|
|
342
335
|
var bytes = field.BitLength/8
|
|
@@ -355,7 +348,7 @@ fieldTypeWriters['Bitfield'] = (pgn, field, value, bs) => {
|
|
|
355
348
|
}
|
|
356
349
|
}
|
|
357
350
|
|
|
358
|
-
fieldTypeWriters['
|
|
351
|
+
fieldTypeWriters['STRING_FIX'] = (pgn, field, value, bs) => {
|
|
359
352
|
|
|
360
353
|
let fill = 0xff
|
|
361
354
|
if ( (pgn === 129810 && (field.Name === "Vendor ID" || field.Name === "Callsign")) || (pgn === 129809 && field.Name === 'Name') ) {
|
|
@@ -422,7 +415,7 @@ fieldTypeWriters[RES_STRINGLAU] = (pgn, field, value, bs) => {
|
|
|
422
415
|
}
|
|
423
416
|
}
|
|
424
417
|
|
|
425
|
-
fieldTypeMappers['
|
|
418
|
+
fieldTypeMappers['DATE'] = (field, value) => {
|
|
426
419
|
//console.log(`Date: ${value}`)
|
|
427
420
|
if ( _.isString(value) ) {
|
|
428
421
|
var date = new Date(value)
|
|
@@ -432,7 +425,7 @@ fieldTypeMappers['Date'] = (field, value) => {
|
|
|
432
425
|
return value
|
|
433
426
|
}
|
|
434
427
|
|
|
435
|
-
fieldTypeMappers['
|
|
428
|
+
fieldTypeMappers['TIME'] = (field, value) => {
|
|
436
429
|
if ( _.isString(value) ) {
|
|
437
430
|
var split = value.split(':')
|
|
438
431
|
|
|
@@ -445,18 +438,19 @@ fieldTypeMappers['Time'] = (field, value) => {
|
|
|
445
438
|
return value
|
|
446
439
|
}
|
|
447
440
|
|
|
448
|
-
|
|
441
|
+
/*
|
|
449
442
|
fieldTypeMappers['Manufacturer code'] = (field, value) => {
|
|
450
443
|
if ( _.isString(value) ) {
|
|
451
444
|
value = getManufacturerCode(value)
|
|
452
445
|
}
|
|
453
446
|
return Number(value)
|
|
454
|
-
}
|
|
447
|
+
}
|
|
448
|
+
*/
|
|
455
449
|
|
|
456
450
|
fieldTypeMappers['Pressure'] = (field, value) => {
|
|
457
|
-
if (field.
|
|
451
|
+
if (field.Unit)
|
|
458
452
|
{
|
|
459
|
-
switch (field.
|
|
453
|
+
switch (field.Unit[0]) {
|
|
460
454
|
case 'h':
|
|
461
455
|
case 'H':
|
|
462
456
|
value /= 100;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canboat/canboatjs",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Native javascript version of canboat",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
],
|
|
54
54
|
"license": "Apache-2.0",
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@canboat/pgns": "
|
|
56
|
+
"@canboat/pgns": "3.x.x",
|
|
57
57
|
"bit-buffer": "0.2.3",
|
|
58
58
|
"date-fns": "2.0.0-alpha.27",
|
|
59
59
|
"debug": "^4.3.4",
|