@canboat/canboatjs 3.0.2 → 3.1.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.
Files changed (222) hide show
  1. package/.github/workflows/test.yml +2 -2
  2. package/.github/workflows/test_canboat_changes.yml +91 -0
  3. package/.husky/pre-commit +4 -0
  4. package/.mocharc.js +7 -0
  5. package/.prettierrc.json +5 -0
  6. package/README.md +2 -7
  7. package/dist/actisense-serial.d.ts +17 -0
  8. package/dist/actisense-serial.d.ts.map +1 -0
  9. package/dist/actisense-serial.js +569 -0
  10. package/dist/actisense-serial.js.map +1 -0
  11. package/dist/bin/actisense-file.d.ts +3 -0
  12. package/dist/bin/actisense-file.d.ts.map +1 -0
  13. package/dist/bin/actisense-file.js +49 -0
  14. package/dist/bin/actisense-file.js.map +1 -0
  15. package/dist/bin/actisense-n2k-tcp.d.ts +3 -0
  16. package/dist/bin/actisense-n2k-tcp.d.ts.map +1 -0
  17. package/dist/bin/actisense-n2k-tcp.js +46 -0
  18. package/dist/bin/actisense-n2k-tcp.js.map +1 -0
  19. package/dist/bin/actisense-serialjs.d.ts +3 -0
  20. package/dist/bin/actisense-serialjs.d.ts.map +1 -0
  21. package/dist/bin/actisense-serialjs.js +51 -0
  22. package/dist/bin/actisense-serialjs.js.map +1 -0
  23. package/dist/bin/analyzerjs.d.ts +3 -0
  24. package/dist/bin/analyzerjs.d.ts.map +1 -0
  25. package/dist/bin/analyzerjs.js +61 -0
  26. package/dist/bin/analyzerjs.js.map +1 -0
  27. package/dist/bin/candumpanalyzerjs.d.ts +3 -0
  28. package/dist/bin/candumpanalyzerjs.d.ts.map +1 -0
  29. package/dist/bin/candumpanalyzerjs.js +31 -0
  30. package/dist/bin/candumpanalyzerjs.js.map +1 -0
  31. package/dist/bin/candumpjs.d.ts +3 -0
  32. package/dist/bin/candumpjs.d.ts.map +1 -0
  33. package/dist/bin/candumpjs.js +73 -0
  34. package/dist/bin/candumpjs.js.map +1 -0
  35. package/dist/bin/cansend.d.ts +3 -0
  36. package/dist/bin/cansend.d.ts.map +1 -0
  37. package/dist/bin/cansend.js +123 -0
  38. package/dist/bin/cansend.js.map +1 -0
  39. package/dist/bin/ikonvert-serial.d.ts +3 -0
  40. package/dist/bin/ikonvert-serial.d.ts.map +1 -0
  41. package/dist/bin/ikonvert-serial.js +36 -0
  42. package/dist/bin/ikonvert-serial.js.map +1 -0
  43. package/dist/bin/to-pgn.d.ts +3 -0
  44. package/dist/bin/to-pgn.d.ts.map +1 -0
  45. package/dist/bin/to-pgn.js +57 -0
  46. package/dist/bin/to-pgn.js.map +1 -0
  47. package/dist/canId.d.ts +21 -0
  48. package/dist/canId.d.ts.map +1 -0
  49. package/dist/canId.js +66 -0
  50. package/dist/canId.js.map +1 -0
  51. package/dist/canId.test.d.ts +2 -0
  52. package/dist/canId.test.d.ts.map +1 -0
  53. package/dist/canId.test.js +58 -0
  54. package/dist/canId.test.js.map +1 -0
  55. package/dist/canbus.d.ts +17 -0
  56. package/dist/canbus.d.ts.map +1 -0
  57. package/dist/canbus.js +261 -0
  58. package/dist/canbus.js.map +1 -0
  59. package/dist/candevice.d.ts +23 -0
  60. package/dist/candevice.d.ts.map +1 -0
  61. package/dist/candevice.js +38 -0
  62. package/dist/candevice.js.map +1 -0
  63. package/dist/codes.d.ts +2 -0
  64. package/dist/codes.d.ts.map +1 -0
  65. package/dist/codes.js +24 -0
  66. package/dist/codes.js.map +1 -0
  67. package/dist/discovery.d.ts +17 -0
  68. package/dist/discovery.d.ts.map +1 -0
  69. package/dist/discovery.js +119 -0
  70. package/dist/discovery.js.map +1 -0
  71. package/dist/fromPgn.d.ts +51 -0
  72. package/dist/fromPgn.d.ts.map +1 -0
  73. package/dist/fromPgn.js +989 -0
  74. package/dist/fromPgn.js.map +1 -0
  75. package/dist/fromPgnStream.d.ts +17 -0
  76. package/dist/fromPgnStream.d.ts.map +1 -0
  77. package/dist/fromPgnStream.js +47 -0
  78. package/dist/fromPgnStream.js.map +1 -0
  79. package/dist/ikonvert.d.ts +17 -0
  80. package/dist/ikonvert.d.ts.map +1 -0
  81. package/dist/ikonvert.js +224 -0
  82. package/dist/ikonvert.js.map +1 -0
  83. package/dist/index.d.ts +31 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.js +60 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/n2k-actisense.d.ts +24 -0
  88. package/dist/n2k-actisense.d.ts.map +1 -0
  89. package/dist/n2k-actisense.js +126 -0
  90. package/dist/n2k-actisense.js.map +1 -0
  91. package/dist/n2k-actisense.test.d.ts +2 -0
  92. package/dist/n2k-actisense.test.d.ts.map +1 -0
  93. package/dist/n2k-actisense.test.js +49 -0
  94. package/dist/n2k-actisense.test.js.map +1 -0
  95. package/dist/n2kDevice.d.ts +40 -0
  96. package/dist/n2kDevice.d.ts.map +1 -0
  97. package/dist/n2kDevice.js +387 -0
  98. package/dist/n2kDevice.js.map +1 -0
  99. package/dist/ncanbus.d.ts +17 -0
  100. package/dist/ncanbus.d.ts.map +1 -0
  101. package/dist/ncanbus.js +92 -0
  102. package/dist/ncanbus.js.map +1 -0
  103. package/dist/pgns.d.ts +22 -0
  104. package/dist/pgns.d.ts.map +1 -0
  105. package/dist/pgns.js +157 -0
  106. package/dist/pgns.js.map +1 -0
  107. package/dist/pgns.test.d.ts +2 -0
  108. package/dist/pgns.test.d.ts.map +1 -0
  109. package/dist/pgns.test.js +14 -0
  110. package/dist/pgns.test.js.map +1 -0
  111. package/dist/simpleCan.d.ts +17 -0
  112. package/dist/simpleCan.d.ts.map +1 -0
  113. package/dist/simpleCan.js +125 -0
  114. package/dist/simpleCan.js.map +1 -0
  115. package/dist/stringMsg.d.ts +33 -0
  116. package/dist/stringMsg.d.ts.map +1 -0
  117. package/dist/stringMsg.js +359 -0
  118. package/dist/stringMsg.js.map +1 -0
  119. package/dist/stringMsg.test.d.ts +2 -0
  120. package/dist/stringMsg.test.d.ts.map +1 -0
  121. package/dist/stringMsg.test.js +244 -0
  122. package/dist/stringMsg.test.js.map +1 -0
  123. package/dist/toPgn.d.ts +34 -0
  124. package/dist/toPgn.d.ts.map +1 -0
  125. package/dist/toPgn.js +500 -0
  126. package/dist/toPgn.js.map +1 -0
  127. package/dist/utilities.d.ts +26 -0
  128. package/dist/utilities.d.ts.map +1 -0
  129. package/dist/utilities.js +112 -0
  130. package/dist/utilities.js.map +1 -0
  131. package/dist/utilities.test.d.ts +2 -0
  132. package/dist/utilities.test.d.ts.map +1 -0
  133. package/dist/utilities.test.js +9 -0
  134. package/dist/utilities.test.js.map +1 -0
  135. package/dist/venus-mqtt.d.ts +11 -0
  136. package/dist/venus-mqtt.d.ts.map +1 -0
  137. package/dist/venus-mqtt.js +100 -0
  138. package/dist/venus-mqtt.js.map +1 -0
  139. package/dist/venus.d.ts +11 -0
  140. package/dist/venus.d.ts.map +1 -0
  141. package/dist/venus.js +71 -0
  142. package/dist/venus.js.map +1 -0
  143. package/dist/w2k01.d.ts +17 -0
  144. package/dist/w2k01.d.ts.map +1 -0
  145. package/dist/w2k01.js +119 -0
  146. package/dist/w2k01.js.map +1 -0
  147. package/dist/yddevice.d.ts +25 -0
  148. package/dist/yddevice.d.ts.map +1 -0
  149. package/dist/yddevice.js +45 -0
  150. package/dist/yddevice.js.map +1 -0
  151. package/dist/ydgw02.d.ts +17 -0
  152. package/dist/ydgw02.d.ts.map +1 -0
  153. package/dist/ydgw02.js +163 -0
  154. package/dist/ydgw02.js.map +1 -0
  155. package/dist/ydvr.d.ts +17 -0
  156. package/dist/ydvr.d.ts.map +1 -0
  157. package/dist/ydvr.js +120 -0
  158. package/dist/ydvr.js.map +1 -0
  159. package/eslint.config.js +58 -0
  160. package/jest.config.js +5 -0
  161. package/lib/actisense-serial.ts +644 -0
  162. package/lib/bin/actisense-file.ts +53 -0
  163. package/lib/bin/actisense-n2k-tcp.ts +50 -0
  164. package/lib/bin/actisense-serialjs.ts +55 -0
  165. package/{bin/analyzerjs → lib/bin/analyzerjs.ts} +16 -15
  166. package/{bin/candumpjs → lib/bin/candumpjs.ts} +19 -20
  167. package/lib/bin/cansend.ts +131 -0
  168. package/lib/bin/ikonvert-serial.ts +44 -0
  169. package/{bin/to-pgn → lib/bin/to-pgn.ts} +23 -17
  170. package/lib/bin/ydvr-file +33 -0
  171. package/lib/canId.test.js +35 -15
  172. package/lib/canId.ts +84 -0
  173. package/lib/canbus.ts +293 -0
  174. package/lib/{candevice.js → candevice.ts} +14 -21
  175. package/lib/codes.ts +21 -0
  176. package/lib/{discovery.js → discovery.ts} +32 -30
  177. package/lib/fromPgn.ts +1207 -0
  178. package/lib/{fromPgnStream.js → fromPgnStream.ts} +17 -12
  179. package/lib/{ikonvert.js → ikonvert.ts} +90 -85
  180. package/lib/index.ts +48 -0
  181. package/lib/n2k-actisense.test.js +31 -32
  182. package/lib/n2k-actisense.ts +152 -0
  183. package/lib/n2kDevice.ts +458 -0
  184. package/lib/pgns.test.ts +12 -0
  185. package/lib/pgns.ts +191 -0
  186. package/lib/simpleCan.ts +140 -0
  187. package/lib/stringMsg.test.js +58 -41
  188. package/lib/stringMsg.ts +464 -0
  189. package/lib/toPgn.ts +597 -0
  190. package/lib/{utilities.js → utilities.ts} +48 -37
  191. package/lib/venus-mqtt.js +69 -73
  192. package/lib/venus.js +8 -8
  193. package/lib/{w2k01.js → w2k01.ts} +57 -44
  194. package/lib/{yddevice.js → yddevice.ts} +18 -13
  195. package/lib/{ydgw02.js → ydgw02.ts} +55 -47
  196. package/lib/ydvr.js +65 -147
  197. package/package.json +54 -18
  198. package/tsconfig.json +19 -0
  199. package/tsconfig.tsbuildinfo +1 -0
  200. package/bin/actisense-file +0 -47
  201. package/bin/actisense-n2k-tcp +0 -45
  202. package/bin/actisense-serialjs +0 -52
  203. package/bin/candumpanalyzerjs +0 -29
  204. package/bin/cansend +0 -130
  205. package/bin/ikonvert-serial +0 -50
  206. package/bin/ydgw-analyzerjs +0 -36
  207. package/bin/ydvr-file +0 -33
  208. package/index.js +0 -53
  209. package/lib/canId.js +0 -64
  210. package/lib/canbus.js +0 -278
  211. package/lib/codes.js +0 -69
  212. package/lib/codes.test.js +0 -17
  213. package/lib/codesMfgs.json +0 -166
  214. package/lib/fromPgn.js +0 -1027
  215. package/lib/n2k-actisense.js +0 -108
  216. package/lib/n2kDevice.js +0 -390
  217. package/lib/pgns.js +0 -196
  218. package/lib/pgns.test.js +0 -13
  219. package/lib/serial.js +0 -647
  220. package/lib/simpleCan.js +0 -105
  221. package/lib/stringMsg.js +0 -339
  222. package/lib/toPgn.js +0 -518
package/lib/fromPgn.js DELETED
@@ -1,1027 +0,0 @@
1
- /**
2
- * Copyright 2018 Scott Bender (scott@scottbender.net)
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
-
17
- const debug = require('debug')('canboatjs:fromPgn')
18
- const trace = require('debug')('canboatjs:fromPgn:trace')
19
- const EventEmitter = require('events')
20
- const pkg = require('../package.json')
21
- const _ = require('lodash')
22
- const { pgns, getCustomPgn, addCustomPgns, lookupEnumerationName, lookupFieldTypeEnumerationName, lookupBitEnumerationName, lookupFieldTypeEnumerationBits, lookupFieldTypeEnumerationValue } = require('./pgns')
23
- const BitStream = require('bit-buffer').BitStream
24
- const BitView = require('bit-buffer').BitView
25
- const Int64LE = require('int64-buffer').Int64LE
26
- const Uint64LE = require('int64-buffer').Uint64LE
27
-
28
- const { getPGNFromCanId } = require('./utilities')
29
- const { getIndustryName, getManufacturerName } = require('./codes')
30
- const { parseCanId } = require('./canId')
31
- const { parseN2kString, parseYDRAW, isN2KOver0183, parseN2KOver0183, parsePDGY, parseActisenseN2KASCII } = require('./stringMsg')
32
-
33
- var fieldTypeReaders = {}
34
- var fieldTypePostProcessors = {}
35
-
36
- const timeUnitsPerSecond = 10000
37
- const maxUint64 = new Int64LE(0xffffffff, 0xffffffff)
38
- const maxInt64 = new Int64LE(0x7fffffff, 0xffffffff)
39
-
40
- const FORMAT_PLAIN = 0
41
- const FORMAT_COALESCED = 1
42
- const RES_BINARY = 'Binary data'
43
-
44
- const FASTPACKET_INDEX = 0
45
- const FASTPACKET_SIZE = 1
46
- const FASTPACKET_BUCKET_0_SIZE = 6
47
- const FASTPACKET_BUCKET_N_SIZE = 7
48
- const FASTPACKET_BUCKET_0_OFFSET = 2
49
- const FASTPACKET_BUCKET_N_OFFSET = 1
50
- const FASTPACKET_MAX_INDEX = 0x1f
51
- const FASTPACKET_MAX_SIZE = (FASTPACKET_BUCKET_0_SIZE + FASTPACKET_BUCKET_N_SIZE * (FASTPACKET_MAX_INDEX - 1))
52
-
53
-
54
- //we can't handle these, so ignore them
55
- const ignoredPgns = []//130820, 126720 ]
56
-
57
- class Parser extends EventEmitter {
58
- constructor (opts) {
59
- super()
60
- this.options = _.isUndefined(opts) ? {} : opts
61
-
62
- if ( this.options.returnNulls === undefined ) {
63
- this.options.returnNulls = false
64
- }
65
-
66
- if ( this.options.useCamel === undefined ) {
67
- this.options.useCamel = false
68
- }
69
-
70
- if ( this.options.useCamelCompat === undefined ) {
71
- this.options.useCamelCompat = false
72
- }
73
-
74
- this.name = pkg.name
75
- this.version = pkg.version
76
- this.author = pkg.author
77
- this.license = pkg.license
78
- this.format = _.isUndefined(this.options.format) ? -1 : this.options.format
79
- this.devices = {}
80
- this.mixedFormat = this.options.mixedFormat || false
81
-
82
- if ( this.options.onPropertyValues ) {
83
- this.options.onPropertyValues('canboat-custom-pgns', values => {
84
- values.filter(v => v != null).forEach(pv => {
85
- addCustomPgns(pv.value, pv.setter)
86
- })
87
- })
88
- }
89
- }
90
-
91
- _parse(pgn, bs, len, coalesced, cb, sourceString) {
92
- if ( ignoredPgns.indexOf(pgn.pgn) != -1 ) {
93
- this.emit('warning', pgn, 'ignoring pgn')
94
- return undefined
95
- }
96
-
97
- const customPgns = getCustomPgn(pgn.pgn)
98
- let pgnList = pgns[pgn.pgn]
99
-
100
- if (!pgnList && !customPgns ) {
101
- this.emit('warning', pgn, `no conversion found for pgn ${JSON.stringify(pgn)}`)
102
- return undefined
103
- }
104
-
105
- if ( customPgns ) {
106
- pgnList = [ ...customPgns.definitions, ...(pgnList||[]) ]
107
- }
108
-
109
- let pgnData
110
- let origPGNList = pgnList
111
-
112
- if ( pgnList.length > 1 ) {
113
- pgnData = this.findMatchPgn(pgnList)
114
- }
115
-
116
- if ( !pgnData ) {
117
- pgnData = pgnList[0]
118
- }
119
-
120
- let couldBeMulti = false;
121
-
122
- if ( pgnList.length > 0 && len == 8 ) {
123
- pgnList.forEach(pgnD => {
124
- if ( pgnD.Length > 8 ) {
125
- couldBeMulti = true
126
- }
127
- })
128
- }
129
-
130
- trace(`${pgn.pgn} ${len} ${pgnData.Length} ${couldBeMulti}`)
131
- if ( coalesced || len > 0x8 || (this.format == FORMAT_COALESCED && !this.mixedFormat) ) {
132
- this.format = FORMAT_COALESCED
133
- if ( sourceString ) {
134
- pgn.input = [ sourceString ]
135
- }
136
- //} else if ( pgnData.Length > 0x8 || (len == 0x8 && (pgnData.RepeatingFields || couldBeMulti))) {
137
- } else if ( pgnData.Type === 'Fast' ) {
138
- //partial packet
139
- this.format = FORMAT_PLAIN
140
-
141
- if ( _.isUndefined(this.devices[pgn.src]) ) {
142
- this.devices[pgn.src] = {}
143
- }
144
- var packet = this.devices[pgn.src][pgn.pgn]
145
-
146
- if ( !packet ) {
147
- packet = { bufferSize:0, lastPacket: 0, src: [] }
148
- this.devices[pgn.src][pgn.pgn] = packet
149
- }
150
- if ( sourceString ) {
151
- packet.src.push(sourceString)
152
- }
153
-
154
- var start = bs.byteIndex
155
- var packetIndex = bs.view.buffer.readUInt8(FASTPACKET_INDEX)
156
- var bucket = packetIndex & FASTPACKET_MAX_INDEX;
157
-
158
- trace(`${pgn.pgn} partial ${packetIndex} ${bucket} ${packet.size}`)
159
-
160
- if ( bucket == 0 ) {
161
- packet.size = bs.view.buffer.readUInt8(FASTPACKET_SIZE)
162
- var newSize = packet.size + FASTPACKET_BUCKET_N_SIZE;
163
- if ( newSize > packet.bufferSize ) {
164
- var newBuf = Buffer.alloc(newSize)
165
- packet.bufferSize = newSize
166
- if ( packet.buffer ) {
167
- packet.buffer.copy(newBuf)
168
- }
169
- packet.buffer = newBuf
170
- }
171
- bs.view.buffer.copy(packet.buffer, 0, FASTPACKET_BUCKET_0_OFFSET, 8)
172
- trace(`${pgn.pgn} targetStart: 0 sourceStart: ${FASTPACKET_BUCKET_0_OFFSET}`)
173
- } else if ( !packet.buffer ) {
174
- //we got a non-zero bucket, but we never got the zero bucket
175
- debug(`PGN ${pgn.pgn} malformed packet for ${pgn.src} received; got a non-zero bucket first`)
176
- cb && cb(`Could not parse ${JSON.stringify(pgn)}`)
177
- bs.byteIndex = start
178
- delete this.devices[pgn.src][pgn.pgn]
179
- return
180
- } else {
181
- if (packet.lastPacket + 1 != packetIndex) {
182
- debug(`PGN ${pgn.pgn} malformed packet for ${pgn.src} received; expected ${packet.lastPacket+1} but got ${packetIndex}`)
183
- cb && cb(`Could not parse ${JSON.stringify(pgn)}`)
184
- bs.byteIndex = start
185
- delete this.devices[pgn.src][pgn.pgn]
186
- return
187
- } else {
188
- trace(`${pgn.pgn} targetStart: ${FASTPACKET_BUCKET_0_SIZE + FASTPACKET_BUCKET_N_SIZE * (bucket-1)} sourceStart: ${FASTPACKET_BUCKET_N_OFFSET} sourceEned: ${FASTPACKET_BUCKET_N_SIZE}`)
189
- bs.view.buffer.copy(
190
- packet.buffer,
191
- FASTPACKET_BUCKET_0_SIZE + FASTPACKET_BUCKET_N_SIZE * (bucket-1)
192
- , FASTPACKET_BUCKET_N_OFFSET, 8
193
- )
194
- }
195
- }
196
- packet.lastPacket = packetIndex;
197
- if (FASTPACKET_BUCKET_0_SIZE + FASTPACKET_BUCKET_N_SIZE * bucket < packet.size)
198
- {
199
- // Packet is not complete yet
200
- trace(`${pgn.pgn} not complete`)
201
- return;
202
- }
203
- var view = new BitView(packet.buffer)
204
- bs = new BitStream(view)
205
- trace(`${pgn.pgn} done`)
206
- pgn.input = packet.src
207
- delete this.devices[pgn.src][pgn.pgn]
208
- } else if ( sourceString ) {
209
- pgn.input = [ sourceString ]
210
- }
211
-
212
- let RepeatingFields = pgnData.RepeatingFieldSet1Size ? pgnData.RepeatingFieldSet1Size : 0
213
-
214
- pgn.fields = {}
215
-
216
- try {
217
- var fields = pgnData.Fields
218
-
219
- for ( var i = 0; i < fields.length-RepeatingFields; i++ ) {
220
- var field = fields[i]
221
- var hasMatch = !_.isUndefined(field.Match)
222
-
223
- var value = readField(this.options, !hasMatch, pgn, field, bs, fields)
224
-
225
- if ( hasMatch ) {
226
- //console.log(`looking for ${field.Name} == ${value}`)
227
- //console.log(JSON.stringify(pgnList, null, 2))
228
- pgnList = pgnList.filter(f => f.Fields[i].Match == value)
229
- if ( pgnList.length == 0 ) {
230
- //this.emit('warning', pgn, `no conversion found for pgn`)
231
- trace('warning no conversion found for pgn %j', pgn)
232
-
233
- let nonMatch = this.findNonMatchPgn(origPGNList)
234
- if ( nonMatch ) {
235
- pgnList = [ nonMatch ]
236
- pgnData = pgnList[0]
237
- fields = pgnData.Fields
238
- var postProcessor = fieldTypePostProcessors[field.FieldType]
239
- if ( postProcessor ) {
240
- value = postProcessor(pgnData.Fields[i], value)
241
- }
242
- } else {
243
- const ts = _.get(pgn, 'timestamp', new Date())
244
- pgn.timestamp = _.isDate(ts) ? ts.toISOString() : ts
245
- if ( !_.isUndefined(value) && (value != null ||
246
- this.options.returnNulls) ) {
247
- this.setField(pgn.fields, field, value)
248
- }
249
- this.emit('pgn', pgn)
250
- cb && cb(undefined, pgn)
251
- return pgn
252
- }
253
- } else {
254
- pgnData = pgnList[0]
255
- fields = pgnData.Fields
256
- //console.log(`using ${JSON.stringify(pgnData, null, 2)}`)
257
- value = pgnData.Fields[i].Description
258
- if ( value == null ) {
259
- value = pgnData.Fields[i].Match
260
- }
261
- RepeatingFields = pgnData.RepeatingFieldSet1Size ? pgnData.RepeatingFieldSet1Size : 0
262
- }
263
- }
264
-
265
- if ( !_.isUndefined(value) && (value != null ||
266
- this.options.returnNulls) ) {
267
- this.setField(pgn.fields, field, value)
268
- }
269
- }
270
- if ( RepeatingFields > 0 ) {
271
- var repeating = fields.slice(fields.length-RepeatingFields)
272
- pgn.fields.list = []
273
-
274
- let count
275
-
276
- if ( pgnData.RepeatingFieldSet1CountField !== undefined ) {
277
- count = pgn.fields[pgnData.Fields[pgnData.RepeatingFieldSet1CountField-1][this.options.useCamel ? 'Id' : 'Name']]
278
- } else {
279
- count = 2048
280
- }
281
-
282
- while ( bs.bitsLeft > 0 && --count >= 0 ) {
283
- var group = {}
284
- repeating.forEach(field => {
285
- if ( bs.bitsLeft > 0 ) {
286
- var value = readField(this.options, true, pgn, field, bs, fields)
287
- if ( !_.isUndefined(value) && value != null ) {
288
- this.setField(group, field, value)
289
- }
290
- }
291
- })
292
- if ( _.keys(group).length > 0 ) {
293
- pgn.fields.list.push(group)
294
- }
295
- }
296
- }
297
-
298
- pgn.description = pgnData.Description
299
-
300
- //console.log(`pgn: ${JSON.stringify(pgn)}`)
301
-
302
- // Stringify timestamp because SK Server needs it that way.
303
- const ts = _.get(pgn, 'timestamp', new Date())
304
- pgn.timestamp = _.isDate(ts) ? ts.toISOString() : ts
305
- this.emit('pgn', pgn)
306
- cb && cb(undefined, pgn)
307
- if ( pgnData.callback ) {
308
- pgnData.callback(pgn)
309
- }
310
- return pgn
311
- } catch ( error ) {
312
- this.emit('error', pgn, error)
313
- cb && cb(error)
314
- return
315
- }
316
- }
317
-
318
- setField(res, field, value) {
319
- if ( this.options.useCamelCompat ) {
320
- res[field.Id] = value
321
- res[field.Name] = value
322
- } else if ( this.options.useCamel ) {
323
- res[field.Id] = value
324
- } else {
325
- res[field.Name] = value
326
- }
327
- }
328
-
329
- findNonMatchPgn(pgnList) {
330
- return pgnList.find(f => {
331
- return !f.Fields.find(f => !_.isUndefined(f.Match))
332
- })
333
- }
334
-
335
- findMatchPgn(pgnList) {
336
- return pgnList.find(f => {
337
- return f.Fields.find(f => !_.isUndefined(f.Match))
338
- })
339
- }
340
-
341
- parse(data, cb) {
342
- if (_.isString(data) ) {
343
- return this.parseString(data, cb)
344
- } else if ( _.isBuffer(data) ) {
345
- return this.parseBuffer(data, cb)
346
- } else {
347
- return this.parsePgnData(data.pgn, data.length, data.data, data.coalesced === true, cb, data.sourceString)
348
- }
349
- }
350
-
351
- parsePgnData(pgn, length, data, coalesced, cb, sourceString) {
352
- try
353
- {
354
- var buffer = data
355
- if ( !_.isBuffer(data) ) {
356
- var array = new Int16Array(length)
357
- data.forEach((num, index) => {
358
- array[index] = parseInt(num, 16)
359
- })
360
- buffer = Buffer.from(array)
361
- }
362
-
363
- var bv = new BitView(buffer);
364
- var bs = new BitStream(bv)
365
- const res = this._parse(pgn, bs, length, coalesced, cb, sourceString);
366
- if ( res ) {
367
- debug('parsed pgn %j', pgn)
368
- }
369
- return res
370
- } catch ( error ) {
371
- cb && cb(error)
372
- this.emit('error', pgn, error)
373
- }
374
- }
375
-
376
- isN2KOver0183(sentence) {
377
- return isN2KOver0183(sentence)
378
- }
379
-
380
- parseN2KOver0183(sentence, cb) {
381
- return this.parseString(sentence, cb)
382
- }
383
-
384
- // Venus MQTT-N2K
385
- parseVenusMQTT(pgn_data, cb) {
386
- try
387
- {
388
- const pgn = {
389
- pgn: pgn_data.pgn,
390
- timestamp: new Date().toISOString(),
391
- src: pgn_data.src,
392
- dst: pgn_data.dst
393
- }
394
- const bs = new BitStream(Buffer.from(pgn_data.data, 'base64'))
395
- const res = this._parse(pgn, bs, 8, false, cb)
396
- if ( res ) {
397
- debug('parsed pgn %j', pgn)
398
- }
399
- return res
400
- } catch ( error ) {
401
- cb && cb(error)
402
- this.emit('error', pgn, error)
403
- }
404
- }
405
-
406
- //Yacht Devices NMEA2000 Wifi gateway
407
- parseYDGW02(pgn_data, cb) {
408
- try {
409
- const { data, direction, error, ...pgn } = parseYDRAW(pgn_data)
410
- if (!error && direction === 'R') {
411
- const bs = new BitStream(data)
412
- delete pgn.format
413
- const res = this._parse(pgn, bs, data.length, false, cb, pgn_data)
414
- if ( res ) {
415
- debug('parsed ydgw02 pgn %j', pgn_data)
416
- return res
417
- }
418
- } else if ( error ) {
419
- cb && cb(error)
420
- this.emit('error', pgn_data, error)
421
- }
422
- } catch ( error ) {
423
- cb && cb(error)
424
- this.emit('error', pgn_data, error)
425
- }
426
- return undefined
427
- }
428
-
429
- //Actisense W2k-1
430
- parseActisenceN2KAscii(pgn_data, cb) {
431
- try {
432
- const { data, error, ...pgn } = parseActisenseN2KASCII(pgn_data)
433
- if (!error ) {
434
- const bs = new BitStream(data)
435
- delete pgn.format
436
- const res = this._parse(pgn, bs, data.length, false, cb, pgn_data)
437
- if ( res ) {
438
- debug('parsed n2k ascii pgn %j', pgn_data)
439
- return res
440
- }
441
- } else if ( error ) {
442
- cb && cb(error)
443
- this.emit('error', pgn_data, error)
444
- }
445
- } catch ( error ) {
446
- cb && cb(error)
447
- this.emit('error', pgn_data, error)
448
- }
449
- return undefined
450
- }
451
-
452
- parsePDGY(pgn_data, cb) {
453
- if ( pgn_data[0] != '!') {
454
- return
455
- }
456
- try {
457
- const { coalesced, data, error, len, ...pgn } = parsePDGY(pgn_data)
458
- if (error) {
459
- cb && cb(error)
460
- this.emit('error', pgn, error)
461
- return
462
- }
463
-
464
- const bs = new BitStream(data)
465
- delete pgn.format
466
- delete pgn.type
467
- delete pgn.prefix
468
- const res = this._parse(pgn, bs, len || data.length, coalesced, cb, pgn_data)
469
- if (res) {
470
- debug('parsed pgn %j', pgn)
471
- }
472
- return res
473
- } catch ( error ) {
474
- cb && cb(error)
475
- this.emit('error', pgn_data, error)
476
- }
477
- }
478
-
479
- parseString (pgn_data, cb) {
480
- try {
481
- const { coalesced, data, error, len, ...pgn } = parseN2kString(pgn_data, this.options)
482
- if (error) {
483
- cb && cb(error)
484
- this.emit('error', pgn, error)
485
- return
486
- }
487
-
488
- const bs = new BitStream(data)
489
- delete pgn.format
490
- delete pgn.type
491
- delete pgn.prefix
492
- const res = this._parse(pgn, bs, len || data.length, coalesced, cb, pgn_data)
493
- if (res) {
494
- debug('parsed pgn %j', pgn)
495
- }
496
- return res
497
- } catch ( error ) {
498
- cb && cb(error)
499
- this.emit('error', pgn_data, error)
500
- }
501
- }
502
-
503
- // What uses this? What created the buffer?
504
- parseBuffer (pgn_data, cb) {
505
- try {
506
- var bv = new BitView(pgn_data);
507
- var bs = new BitStream(bv)
508
-
509
- var pgn = {}
510
-
511
- // This might be good to move to canId.js ?
512
- pgn.prio = bs.readUint8()
513
- pgn.pgn = bs.readUint8() + 256 * (bs.readUint8() + 256 * bs.readUint8());
514
- pgn.dst = bs.readUint8()
515
- pgn.src = bs.readUint8()
516
- pgn.timestamp = new Date().toISOString()
517
-
518
- var timestamp = bs.readUint32()
519
- var len = bs.readUint8()
520
- const res = this._parse(pgn, bs, len, true, cb)
521
- if ( res ) {
522
- debug('parsed pgn %j', pgn)
523
- }
524
- return res
525
- } catch ( error ) {
526
- const err = new Error(`error reading pgn ${JSON.stringify(pgn_data)} ${error}`)
527
- cb && cb(err)
528
- this.emit('error', pgn_data, error)
529
- console.error(err)
530
- return
531
- }
532
- }
533
-
534
- }
535
-
536
- function getField(pgn, index, data) {
537
- var pgnList = pgns[pgn]
538
- if ( pgnList ) {
539
- var pgn = pgnList[0]
540
- let dataList = data.list ? data.list : data.fields.list
541
-
542
- if ( pgnList.length > 1 ) {
543
- let idx = 0
544
- while ( idx < pgn.Fields.length )
545
- {
546
- field = pgn.Fields[idx]
547
- var hasMatch = !_.isUndefined(field.Match)
548
- if ( hasMatch && dataList.length > 0 ) {
549
- let param = dataList.find(f => f.Parameter === idx+1)
550
-
551
- if ( param ) {
552
- pgnList = pgnList.filter(f => f.Fields[idx].Match == param.Value)
553
- if ( pgnList.length == 0 ) {
554
- throw new Error('unable to read: ' + JSON.stringify(data))
555
- return
556
- } else {
557
- pgn = pgnList[0]
558
- }
559
- }
560
- }
561
- idx++
562
- }
563
- }
564
-
565
- if ( index >= 0 && index < pgn.Fields.length ) {
566
- return pgn.Fields[index]
567
- }
568
-
569
- const RepeatingFields = pgn.RepeatingFieldSet1Size ? pgn.RepeatingFieldSet1Size : 0
570
- if ( RepeatingFields ) {
571
- var startOfRepeatingFields = pgn.Fields.length - RepeatingFields
572
- index = startOfRepeatingFields + ((index - startOfRepeatingFields) % RepeatingFields);
573
- return pgn.Fields[index]
574
- }
575
- }
576
- return null;
577
- }
578
-
579
- function pad2(x) {
580
- x = x.toString()
581
- return x.length === 1 ? "0" + x : x
582
- }
583
-
584
- function pad(n, p, c)
585
- {
586
- n = n.toString()
587
- var pad_char = typeof c !== 'undefined' ? c : '0';
588
- var pad = new Array(1 + p).join(pad_char);
589
- return (pad + n).slice(-pad.length);
590
- }
591
-
592
- function lookup(field, value) {
593
- var name
594
- if ( field.LookupEnumeration ) {
595
- name = lookupEnumerationName(field.LookupEnumeration, value)
596
- } else {
597
- name = lookupFieldTypeEnumerationName(field.LookupFieldTypeEnumeration, value)
598
- }
599
-
600
- return name ? name : value
601
- }
602
-
603
- function readField(options, runPostProcessor, pgn, field, bs, fields) {
604
- var value
605
-
606
- var reader = fieldTypeReaders[field.FieldType]
607
- if ( reader ) {
608
- value = reader(pgn, field, bs)
609
- } else {
610
- if ( field.FieldType !== RES_BINARY && bs.bitsLeft < field.BitLength ) {
611
- //no more data
612
- bs.readBits(bs.bitsLeft, false)
613
- return
614
- }
615
- value = readValue(options, pgn, field, bs, fields)
616
- }
617
-
618
- //console.log(`${field.Name} ${value} ${field.Resolution}`)
619
-
620
- if ( value != null && !_.isUndefined(value) ) {
621
- let type = field.FieldType //hack, missing type
622
- var postProcessor = fieldTypePostProcessors[type]
623
- if ( postProcessor ) {
624
- if ( runPostProcessor ) {
625
- value = postProcessor(field, value)
626
- }
627
- } else {
628
- if ( field.Offset ) {
629
- value += field.Offset
630
- }
631
- let max
632
- if ( typeof field.RangeMax !== 'undefined'
633
- && field.Resolution ) {
634
- max = field.RangeMax / field.Resolution
635
- }
636
- if ( options.checkForInvalidFields !== false && max !== 'undefined' &&
637
- field.FieldType !== 'LOOKUP' &&
638
- field.FieldType !== 'DYNAMIC_FIELD_KEY' &&
639
- field.FieldType !== 'PGN' &&
640
- field.BitLength > 1 &&
641
- max - value < 0 ) {
642
- //console.log(`Bad field ${field.Name} ${max - value}`)
643
- value = null
644
- } if ( field.Resolution && typeof value === 'number' ) {
645
- var resolution = field.Resolution
646
-
647
- if ( _.isString(resolution) ) {
648
- resolution = Number.parseFloat(resolution)
649
- }
650
-
651
- value = (value * resolution)
652
-
653
- let precision = 0;
654
- for (let r = resolution; (r > 0.0) && (r < 1.0); r = r * 10.0)
655
- {
656
- precision++;
657
- }
658
-
659
- value = Number.parseFloat(value.toFixed(precision))
660
- }
661
-
662
- if ((field.FieldType === 'LOOKUP' ||
663
- field.FieldType === 'DYNAMIC_FIELD_KEY') &&
664
- runPostProcessor &&
665
- (_.isUndefined(options.resolveEnums) ||
666
- options.resolveEnums)) {
667
- if (field.Id === "timeStamp" && value < 60) {
668
- value = value.toString()
669
- } else {
670
- value = lookup(field, value)
671
- }
672
- }
673
-
674
- if ( field.Name === 'Industry Code' && _.isNumber(value) && runPostProcessor ) {
675
- var name = getIndustryName(value)
676
- if ( name ) {
677
- value = name
678
- }
679
- }
680
-
681
- if ( field.Unit === "kWh" ) {
682
- value *= 3.6e6; // 1 kWh = 3.6 MJ.
683
- } else if (field.Unit === "Ah") {
684
- value *= 3600.0; // 1 Ah = 3600 C.
685
- }
686
- }
687
- }
688
- return value
689
- }
690
-
691
- function readValue(options, pgn, field, bs, fields, bitLength) {
692
- var value
693
- if ( _.isUndefined(bitLength) ) {
694
- if ( field.BitLengthVariable && field.FieldType === "DYNAMIC_FIELD_VALUE" ) {
695
- bitLength = lookupKeyBitLength(pgn.fields, fields)
696
- } else {
697
- bitLength = field.BitLength
698
- }
699
- }
700
- if ( field.FieldType == 'VARIABLE' ) {
701
- return readVariableLengthField(options, pgn, field, bs)
702
- } else if (bitLength === 8) {
703
- if ( field.Signed ) {
704
- value = bs.readInt8()
705
- value = value === 0x7f ? null : value
706
- } else {
707
- value = bs.readUint8()
708
- value = value === 0xff ? null : value
709
- }
710
- } else if ( bitLength == 16 ) {
711
- if ( field.Signed ) {
712
- value = bs.readInt16()
713
- value = value === 0x7fff ? null : value
714
- } else {
715
- value = bs.readUint16()
716
- value = value === 0xffff ? null : value
717
- }
718
- } else if ( bitLength == 24 ) {
719
- var b1 = bs.readUint8()
720
- var b2 = bs.readUint8()
721
- var b3 = bs.readUint8()
722
-
723
- //debug(`24 bit ${b1.toString(16)} ${b2.toString(16)} ${b3.toString(16)}`)
724
- value = (b3 << 16) + (b2 << 8) + (b1)
725
- //debug(`value ${value.toString(16)}`)
726
- } else if ( bitLength == 32 ) {
727
- if ( field.Signed ) {
728
- value = bs.readInt32()
729
- value = value === 0x7fffffff ? null : value
730
- } else {
731
- value = bs.readUint32()
732
- value = value === 0xffffffff ? null : value
733
- }
734
- } else if ( bitLength == 48 ) {
735
- var a = bs.readUint32()
736
- var b = bs.readUint16()
737
-
738
- if ( field.Signed ) {
739
- value = a == 0xffffffff && b == 0x7fff ? null : new Int64LE(b, a)
740
- } else {
741
- value = a == 0xffffffff && b == 0xffff ? null : new Int64LE(b, a)
742
- }
743
- } else if ( bitLength == 64 ) {
744
- var x = bs.readUint32()
745
- var y = bs.readUint32()
746
-
747
- if ( field.Signed ) {
748
- value = (x === 0xffffffff || x === 0xfffffffe) && y == 0x7fffffff ? null : new Int64LE(y,x)
749
- } else {
750
- value = (x === 0xffffffff || x === 0xfffffffe) && y == 0xffffffff ? null : new Uint64LE(y,x)
751
- }
752
- } else if ( bitLength <= 64 ) {
753
- value = bs.readBits(bitLength, field.Signed)
754
- if ( bitLength > 1 && isMax(bitLength, value, field.Signed) ) {
755
- value = null
756
- }
757
- } else {
758
- if ( bs.bitsLeft < field.BitLength ) {
759
- bitLength = bs.bitsLeft
760
- }
761
-
762
- value = bs.readArrayBuffer(bitLength/8, field.Signed)
763
- value = new Uint32Array(value)
764
- .reduce(function(acc, i) {
765
- acc.push(i.toString(16));
766
- return acc;
767
- }, [])
768
- .map(x => (x.length === 1 ? "0" + x : x))
769
- .join(" ")
770
-
771
- return value
772
- }
773
-
774
- if ( value != null && typeof value !== 'undefined' && typeof value !== 'number' ) {
775
- value = Number(value)
776
- }
777
-
778
- return value
779
- }
780
-
781
- function isMax(numBits, value, signed)
782
- {
783
- if ( signed ) {
784
- numBits--
785
- }
786
-
787
- while ( numBits-- ) {
788
- if ( (value & 1) == 0 ){
789
- return false
790
- }
791
- value = value >> 1
792
- }
793
- return signed ? (value & 1) == 0 : true
794
- }
795
-
796
- function readVariableLengthField(options, pgn, field, bs) {
797
- /* PGN 126208 contains variable field length.
798
- * The field length can be derived from the PGN mentioned earlier in the message,
799
- * plus the field number.
800
- */
801
-
802
- /*
803
- * This is rather hacky. We know that the 'data' pointer points to the n-th variable field
804
- * length and thus that the field number is exactly one byte earlier.
805
- */
806
-
807
- try {
808
- var refField = getField(pgn.fields.PGN, bs.view.buffer[bs.byteIndex-1]-1, pgn)
809
-
810
- if ( refField ) {
811
- var bits = (refField.BitLength + 7) & ~7; // Round # of bits in field refField up to complete bytes: 1->8, 7->8, 8->8 etc.
812
- let res = readField(options, false, pgn, refField, bs)
813
-
814
- if ( bits > refField.BitLength ) {
815
- bs.readBits(bits - refField.BitLength, false)
816
- }
817
-
818
- return res
819
- }
820
- } catch ( error ) {
821
- debug(error)
822
- }
823
- }
824
-
825
- fieldTypeReaders[
826
- 'STRING_LAU'
827
- //'ASCII or UNICODE string starting with length and control byte'
828
- ] = (pgn, field, bs) => {
829
-
830
- if ( bs.bitsLeft >= 16 ) {
831
- const len = bs.readUint8()-2
832
- const control = bs.readUint8()
833
- let nameLen = len
834
-
835
- if ( field.Name === 'AtoN Name' && len > 20 ) {
836
- nameLen = 20
837
- } else if ( len <= 0 ) {
838
- return null
839
- }
840
-
841
- var buf = Buffer.alloc(len)
842
- var idx = 0
843
- for ( ; idx < len && bs.bitsLeft >= 8; idx++ ) {
844
- var c = bs.readUint8()
845
- buf.writeUInt8(c, idx)
846
- }
847
-
848
- if ( buf[buf.length-1] === 0 ) {
849
- nameLen = nameLen - 1
850
- }
851
-
852
- return buf.toString(control == 0 ? 'utf8' : 'ascii', 0, idx < nameLen ? idx : nameLen).trim()
853
- } else {
854
- return null
855
- }
856
- }
857
-
858
- fieldTypeReaders[
859
- 'STRING_LZ'
860
- //'ASCII string starting with length byte'
861
- ] = (pgn, field, bs) => {
862
- var len = bs.readUint8()
863
-
864
- var buf = Buffer.alloc(len)
865
- var idx = 0
866
- for ( ; idx < len && bs.bitsLeft >= 8; idx++ ) {
867
- var c = bs.readUint8()
868
- buf.writeUInt8(c, idx)
869
- }
870
-
871
- return buf.toString('utf-8', 0, idx)
872
- }
873
-
874
- fieldTypeReaders["String with start/stop byte"] = (pgn, field, bs) => {
875
- var len
876
- var first = bs.readUint8()
877
- if ( first == 0xff ) { // no name, stop reading
878
- return ''
879
- } else if ( first == 0x02 ) {
880
- var buf = Buffer.alloc(255)
881
- var c
882
- var idx = 0
883
- while ( (c = bs.readUint8()) != 0x01 ) {
884
- buf.writeUInt8(c, idx++)
885
- }
886
- return buf.toString('ascii', 0, idx)
887
- } else if ( first > 0x02 ) {
888
- var len = first
889
- var second = bs.readUint8()
890
- var buf = Buffer.alloc(len)
891
- var idx = 0
892
- if ( second == 0x01 ) {
893
- len -= 2
894
- } else {
895
- buf.writeUInt8(second)
896
- idx = 1
897
- }
898
- for ( ; idx < len; idx++ ) {
899
- var c = bs.readUint8()
900
- buf.writeUInt8(c, idx)
901
- }
902
- return buf.toString('ascii', 0, idx)
903
- }
904
- }
905
-
906
- fieldTypeReaders['STRING_FIX'] = (pgn, field, bs) => {
907
- var len = field.BitLength / 8
908
- var buf = Buffer.alloc(len)
909
-
910
- for ( var i = 0; i < len && bs.bitsLeft >= 8; i++ ) {
911
- buf.writeUInt8(bs.readUint8(), i)
912
- }
913
-
914
- var lastbyte = buf[len-1]
915
- while (len > 0 && (lastbyte == 0xff ||
916
- lastbyte == 32 ||
917
- lastbyte == 0 ||
918
- lastbyte == 64
919
- )) {
920
- len--
921
- lastbyte = buf[len-1]
922
- }
923
-
924
- //look for a zero byte, some proprietary Raymarine pgns do this
925
- let zero = 0
926
- while ( zero < len ) {
927
- if ( buf[zero] == 0 ) {
928
- len = zero
929
- break
930
- }
931
- zero++
932
- }
933
- len = zero
934
- let res = len > 0 ? buf.toString('ascii', 0, len) : undefined
935
- return res
936
- }
937
-
938
- fieldTypeReaders['BITLOOKUP'] = (pgn, field, bs) => {
939
- var value = []
940
- for ( var i = 0; i < field.BitLength; i++ ) {
941
- if ( bs.readBits(1, 0) ) {
942
- value.push(
943
- lookupBitEnumerationName(field.LookupBitEnumeration, i)
944
- )
945
- }
946
- }
947
- return value
948
- }
949
-
950
- function lookupKeyBitLength(data, fields)
951
- {
952
- let field = fields.find(field => (field.Name === 'Key'))
953
-
954
- let val = data['Key'] || data['key']
955
- if ( typeof val === 'string' ) {
956
- val = lookupFieldTypeEnumerationValue(field.LookupFieldTypeEnumeration, val)
957
- }
958
- return lookupFieldTypeEnumerationBits(field.LookupFieldTypeEnumeration, val)
959
- }
960
-
961
- fieldTypePostProcessors['DATE'] = (field, value) => {
962
- if ( value >= 0xfffd ) {
963
- value = undefined
964
- } else {
965
- var date = new Date((value) * 86400 * 1000)
966
- //var date = moment.unix(0).add(value+1, 'days').utc().toDate()
967
- value = `${date.getUTCFullYear()}.${pad2(date.getUTCMonth()+1)}.${pad2(date.getUTCDate())}`
968
- }
969
- return value
970
- }
971
-
972
- fieldTypePostProcessors['TIME'] = (field, value) => {
973
- if (value >= 0xfffffffd) {
974
- value = undefined
975
- } else {
976
- var seconds = (value * field.Resolution)
977
- var minutes = (seconds / 60);
978
- var seconds = seconds % 60;
979
- var hours = Math.floor(minutes / 60);
980
- var minutes = Math.floor(minutes % 60);
981
-
982
- value = `${pad2(hours)}:${pad2(minutes)}:${pad2(Math.floor(seconds))}`
983
-
984
- if ( seconds % 1 > 0 ) {
985
- value = value + (seconds%1).toFixed(5).substring(1)
986
- }
987
- }
988
- return value
989
- }
990
-
991
- fieldTypePostProcessors['DURATION'] = fieldTypePostProcessors['TIME']
992
-
993
- fieldTypePostProcessors['Pressure'] = (field, value) => {
994
- if (field.Unit)
995
- {
996
- switch (field.Unit[0]) {
997
- case 'h':
998
- case 'H':
999
- value *= 100;
1000
- break;
1001
- case 'k':
1002
- case 'K':
1003
- value *= 1000;
1004
- break;
1005
- case 'd':
1006
- value /= 10;
1007
- break;
1008
- }
1009
- }
1010
- return value
1011
- }
1012
-
1013
- fieldTypePostProcessors[RES_BINARY] = (field, value) => {
1014
- return value.toString()
1015
- }
1016
-
1017
- /*
1018
- fieldTypePostProcessors['Manufacturer code'] = (field, value) => {
1019
- var manufacturer = getManufacturerName(value)
1020
- return manufacturer ? manufacturer : value
1021
- }
1022
- */
1023
-
1024
- module.exports = {
1025
- Parser: Parser,
1026
- getField: getField,
1027
- }