diff --git a/index.js b/index.js index b93d67e..7c03dd6 100644 --- a/index.js +++ b/index.js @@ -16,6 +16,8 @@ * limitations under the License. */ +const pgns = require('./lib/pgns') + module.exports = { FromPgn: require('./lib/fromPgn').Parser, parseN2kString: require('./lib/stringMsg').parseN2kString, @@ -37,7 +39,9 @@ module.exports = { VenusMQTT: require('./lib/venus-mqtt'), discover: require('./lib/discovery'), SimpleCan: require('./lib/simpleCan'), - addCustomPgn: require('./lib/pgns').addCustomPgn + addCustomPgn: pgns.addCustomPgn, + lookupEnumerationValue: pgns.lookupEnumerationValue, + lookupEnumerationName: pgns.lookupEnumerationName } try { diff --git a/lib/fromPgn.js b/lib/fromPgn.js index 45d3ce9..6ccec47 100644 --- a/lib/fromPgn.js +++ b/lib/fromPgn.js @@ -19,7 +19,7 @@ const trace = require('debug')('canboatjs:fromPgn:trace') const EventEmitter = require('events') const pkg = require('../package.json') const _ = require('lodash') -const { pgns, getCustomPgn, addCustomPgn } = require('./pgns') +const { pgns, getCustomPgn, addCustomPgn, lookupEnumNameForField } = require('./pgns') const BitStream = require('bit-buffer').BitStream const BitView = require('bit-buffer').BitView const Int64LE = require('int64-buffer').Int64LE @@ -543,15 +543,8 @@ function pad(n, p, c) } function lookup(field, value) { - if (!field.value2name) { - field.value2name = {}; - field.EnumValues.forEach(function(enumPair) { - field.value2name[Number(enumPair.value)] = enumPair.name - }) - } - var name = field.value2name[value] + var name = lookupEnumNameForField(field, value) return name ? name : value - //return name } function lookupBitField(field, value) { diff --git a/lib/pgns.js b/lib/pgns.js index ecef540..d7f7e30 100644 --- a/lib/pgns.js +++ b/lib/pgns.js @@ -35,14 +35,83 @@ function organizePGNs() { return res } +/** doing this for now, when we move to the new canboat.json, we'll get from there*/ +const enumMappings = { + SHIP_TYPE: { + pgn: 129040, + field: 'Type of ship' + } +} + +function getField(pgn, name) { + return pgn.Fields.find(f => f.Name === name) +} + +function lookupEnumerationName(enumName, value) { + let mapping = enumMappings[enumName] + if ( mapping ) { + let pgn = getPgn0(mapping.pgn) + if ( pgn ) { + let field = getField(pgn, mapping.field) + return field && lookupEnumNameForField(field, value) + } + } +} + +function lookupEnumerationValue(enumName, name) { + let mapping = enumMappings[enumName] + if ( mapping ) { + let pgn = getPgn0(mapping.pgn) + if ( pgn ) { + let field = getField(pgn, mapping.field) + return field && lookupEnumValueForField(field, name) + } + } +} + +function getValue2Name(field) { + if (!field.value2name && field.EnumValues) { + field.value2name = {}; + field.EnumValues.forEach(function(enumPair) { + field.value2name[Number(enumPair.value)] = enumPair.name + }) + } + return field.value2name +} + +function getName2Value(field) { + if (!field.name2value && field.EnumValues) { + field.name2value = {}; + field.EnumValues.forEach(function(enumPair) { + field.name2value[enumPair.name] = Number(enumPair.value) + }) + } + return field.name2value +} + +function lookupEnumNameForField(field, value) { + let value2name = getValue2Name(field) + return value2name && value2name[value] +} + +function lookupEnumValueForField(field, stringValue) { + let name2value = getName2Value(field) + return name2value && name2value[stringValue] +} + const organizedPGNs = organizePGNs() const getPgn = pgn => organizedPGNs[pgn] +const getPgn0 = flow(getPgn, first) const customPgns = {} module.exports = { getPgn, - getPgn0: flow(getPgn, first), + getPgn0, pgns: organizedPGNs, + lookupEnumValueForField, + lookupEnumNameForField, + lookupEnumerationName, + lookupEnumerationValue, addCustomPgn: (pgn) => { if ( !customPgns[pgn.PGN] ) { customPgns[pgn.PGN] = { @@ -62,5 +131,7 @@ module.exports = { }, getCustomPgn: (pgnNum) => { return customPgns[pgnNum] + }, + getEnumForField: (pgnNumber, fieldName) => { } } diff --git a/lib/toPgn.js b/lib/toPgn.js index b34ddea..1aca6f1 100644 --- a/lib/toPgn.js +++ b/lib/toPgn.js @@ -15,7 +15,7 @@ */ const { getField } = require('./fromPgn') -const { pgns, getCustomPgn } = require('./pgns') +const { pgns, getCustomPgn, lookupEnumValueForField } = require('./pgns') const _ = require('lodash') const BitStream = require('bit-buffer').BitStream const Int64LE = require('int64-buffer').Int64LE @@ -270,13 +270,7 @@ function writeVariableLengthField(bs, pgn_number, pgn, field, value) { } function lookup(field, stringValue) { - if (!field.name2value) { - field.name2value = {}; - field.EnumValues.forEach(function(enumPair) { - field.name2value[enumPair.name] = Number(enumPair.value) - }) - } - var res = field.name2value[stringValue]; + var res = lookupEnumValueForField(field, stringValue) return _.isUndefined(res) ? stringValue : res } diff --git a/test/enum_lookups.js b/test/enum_lookups.js new file mode 100644 index 0000000..d86db7e --- /dev/null +++ b/test/enum_lookups.js @@ -0,0 +1,21 @@ +const chai = require('chai') +chai.Should() +chai.use(require('chai-things')) +chai.use(require('chai-json-equal')); + +const { lookupEnumerationValue, lookupEnumerationName} = require('../index') + +describe('enumeration lookups work', function () { + it(`name lookup works`, function (done) { + chai.expect(lookupEnumerationName('SHIP_TYPE', 21)) + .eq('Wing In Ground (hazard cat X)') + done() + }) + + it(`value lookup works`, function (done) { + chai.expect(lookupEnumerationValue('SHIP_TYPE', + 'Wing In Ground (hazard cat X)')) + .eq(21) + done() + }) +})