@signalk/vedirect-serial-usb 1.4.0 → 1.6.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 (63) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +13 -24
  3. package/dist/Parser.d.ts +50 -0
  4. package/dist/Parser.d.ts.map +1 -0
  5. package/dist/Parser.js +350 -0
  6. package/dist/Parser.js.map +1 -0
  7. package/dist/constants.d.ts +5 -0
  8. package/dist/constants.d.ts.map +1 -0
  9. package/dist/constants.js +14 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/fields.d.ts +14 -0
  12. package/dist/fields.d.ts.map +1 -0
  13. package/dist/fields.js +438 -0
  14. package/dist/fields.js.map +1 -0
  15. package/dist/index.d.ts +4 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +209 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/productIds.d.ts +9 -0
  20. package/dist/productIds.d.ts.map +1 -0
  21. package/dist/productIds.js +95 -0
  22. package/dist/productIds.js.map +1 -0
  23. package/dist/serial.d.ts +5 -0
  24. package/dist/serial.d.ts.map +1 -0
  25. package/dist/serial.js +78 -0
  26. package/dist/serial.js.map +1 -0
  27. package/dist/standalone.d.ts +22 -0
  28. package/dist/standalone.d.ts.map +1 -0
  29. package/dist/standalone.js +69 -0
  30. package/dist/standalone.js.map +1 -0
  31. package/dist/tcp.d.ts +5 -0
  32. package/dist/tcp.d.ts.map +1 -0
  33. package/dist/tcp.js +106 -0
  34. package/dist/tcp.js.map +1 -0
  35. package/dist/types.d.ts +159 -0
  36. package/dist/types.d.ts.map +1 -0
  37. package/dist/types.js +15 -0
  38. package/dist/types.js.map +1 -0
  39. package/dist/udp.d.ts +5 -0
  40. package/dist/udp.d.ts.map +1 -0
  41. package/dist/udp.js +67 -0
  42. package/dist/udp.js.map +1 -0
  43. package/docs/screenshots/1_config.png +0 -0
  44. package/logo.svg +46 -0
  45. package/package.json +79 -19
  46. package/.github/FUNDING.yml +0 -1
  47. package/.travis.yml +0 -13
  48. package/index.js +0 -154
  49. package/lib/Parser.js +0 -391
  50. package/lib/fields.js +0 -501
  51. package/lib/filestream.js +0 -38
  52. package/lib/productIds.json +0 -84
  53. package/lib/serial.js +0 -48
  54. package/lib/tcp.js +0 -47
  55. package/lib/udp.js +0 -26
  56. package/log/one.txt +0 -18
  57. package/log/run-log.js +0 -7
  58. package/log/sampleOutput.txt +0 -297
  59. package/migration.js +0 -54
  60. package/run.js +0 -10
  61. package/standalone.js +0 -67
  62. package/test/index.js +0 -52
  63. package/todo.md +0 -14
package/lib/Parser.js DELETED
@@ -1,391 +0,0 @@
1
- const debug = require('debug')
2
- const EventEmitter = require('events')
3
-
4
- const defaults = {
5
- productIds: require('./productIds.json'),
6
- fields: require('./fields'),
7
- defaultUnitId: 'victronDevice',
8
- mainBatt: 'house',
9
- auxBatt: 'starter',
10
- solar: 'solar'
11
- }
12
-
13
- class VEDirectParser extends EventEmitter {
14
- constructor (opts) {
15
- super()
16
- this.options = Object.assign({}, defaults, opts || {})
17
- this.fields = this.options.fields
18
- this.debug = debug('signalk-vedirect-parser')
19
- this.line = []
20
- this.data = {}
21
- this.cache = ''
22
- this.sum = 0
23
- }
24
-
25
- addChunk (buf, items) {
26
- if (!Buffer.isBuffer(buf)) {
27
- return this.warn('addChunk: incoming data is not a buffer: ' + typeof buf)
28
- }
29
-
30
- const chunk = buf.toString('ascii')
31
-
32
- buf.forEach(b => {
33
- this.sum += b
34
- })
35
-
36
- this.cache += chunk
37
- if (chunk.toLowerCase().includes('checksum')) {
38
- // Last line of block. Verify checksum of block in cache and parse line-by-line if checksum is correct.
39
- this._verifyCacheAndParse(items)
40
- }
41
- }
42
-
43
- parse (line) {
44
- if (typeof line !== 'string') {
45
- return
46
- }
47
- this.line = line.trim().split('\t')
48
- this._parse()
49
- }
50
-
51
- set (key, value) {
52
- this.data[key] = value
53
- this.emit('change', Object.assign({}, this.data))
54
- this.emit('set', { key, value })
55
- }
56
-
57
- get (key) {
58
- return this.data[key]
59
- }
60
-
61
- unset (key) {
62
- if (!this.data.hasOwnProperty(key)) {
63
- return
64
- }
65
-
66
- this.debug(`Unsetting ${key}`)
67
- this.emit('change', Object.assign({}, this.data))
68
- this.emit('unset', key)
69
-
70
- this.data[key] = null
71
- delete this.data[key]
72
- }
73
-
74
- getData () {
75
- return Object.assign({}, this.data)
76
- }
77
-
78
- _verifyCacheAndParse (items) {
79
- // Verify checksum if ignoreChecksum isn't true.
80
- if (this.options.vedirect[items].ignoreChecksum !== true && this.sum % 256 !== 0) {
81
- this.warn(`block checksum doesn't equal 0: ${this.sum % 256}`)
82
- this.cache = ''
83
- this.sum = 0
84
- return
85
- }
86
-
87
- this.cache
88
- .trim()
89
- .split('\n')
90
- .map(line => line.trim())
91
- .filter(line => line !== '')
92
- .forEach(line => {
93
- this.line = line.split('\t')
94
- this._parse()
95
- })
96
-
97
- this.cache = ''
98
- this.sum = 0
99
- this.generateDelta(items)
100
- }
101
-
102
- _parse () {
103
- let field = null
104
- let data = null
105
- let converted = null
106
-
107
- if (!Array.isArray(this.line) || this.line.length !== 2) {
108
- return this.warn('_parse() called on invalid line: ' + JSON.stringify({ line: this.line }))
109
- }
110
-
111
- field = String(this.line[0]).toUpperCase()
112
-
113
- if (!Object.keys(this.fields).includes(field) || typeof this.fields[field] !== 'object' || this.fields[field] === null) {
114
- return this.warn(`No field definition for: ${field}, ignoring`)
115
- }
116
-
117
- field = this.fields[field]
118
- data = this.line[1]
119
-
120
- if (data === undefined || data === null) {
121
- return this.warn(`Data is NULL, ignoring`)
122
- }
123
-
124
- if (typeof field.value === 'function') {
125
- converted = field.value(data, this)
126
- } else {
127
- converted = data
128
- }
129
-
130
- if (typeof converted !== 'undefined' && converted !== null) {
131
- this.set(field.name, Object.assign({}, field, {
132
- value: converted
133
- }))
134
- }
135
- }
136
-
137
- getAlarmReason (alarmReason) {
138
- alarmReason = parseInt(alarmReason, 10)
139
-
140
- switch (alarmReason) {
141
- case 1:
142
- return 'Low voltage'
143
-
144
- case 2:
145
- return 'High voltage'
146
-
147
- case 4:
148
- return 'Low state-of-charge'
149
-
150
- case 8:
151
- return 'Low starter voltage'
152
-
153
- case 16:
154
- return 'High starter voltage'
155
-
156
- case 32:
157
- return 'Low temperature'
158
-
159
- case 64:
160
- return 'High temperature'
161
-
162
- case 128:
163
- return 'Mid voltage'
164
-
165
- case 256:
166
- return 'Overload'
167
-
168
- case 512:
169
- return 'DC ripple'
170
-
171
- case 1024:
172
- return 'Low V AC out'
173
-
174
- case 2048:
175
- return 'High V AC out'
176
-
177
- default:
178
- return null
179
- }
180
- }
181
-
182
- getErrorString (err) {
183
- err = parseInt(err, 10)
184
-
185
- switch (err) {
186
- case 2:
187
- return 'Battery voltage too high'
188
-
189
- case 17:
190
- return 'Charger temperature too high'
191
-
192
- case 18:
193
- return 'Charger overcurrent'
194
-
195
- // Can be ignored according to victron protocol
196
- // case 19:
197
- // return 'Charger current reversed'
198
-
199
- case 20:
200
- return 'Bulk time limit exceeded'
201
-
202
- // Can be ignored according to victron protocol
203
- // case 21:
204
- // return 'Current sensor issue (sensor bias/sensor broken)'
205
-
206
- case 26:
207
- return 'Terminals overheated'
208
-
209
- case 33:
210
- return 'Input voltage too high (solar panel)'
211
-
212
- case 34:
213
- return 'Input current too high (solar panel)'
214
-
215
- case 38:
216
- return 'Input shutdown (due to excessive battery voltage)'
217
-
218
- case 116:
219
- return 'Factory calibration data lost'
220
-
221
- case 117:
222
- return 'Invalid/incompatible firmware'
223
-
224
- case 119:
225
- return 'User settings invalid'
226
-
227
- default:
228
- return null
229
- }
230
- }
231
-
232
- getMode (mode) {
233
- mode = parseInt(mode, 10)
234
-
235
- switch (mode) {
236
- case 2:
237
- return 'on'
238
-
239
- case 4:
240
- return 'off'
241
-
242
- case 5:
243
- return 'eco'
244
-
245
- default:
246
- return null
247
- }
248
- }
249
-
250
- getStateOfOperation (cs) {
251
- cs = parseInt(cs, 10)
252
-
253
- switch (cs) {
254
- case 0:
255
- return 'off'
256
-
257
- case 1:
258
- return 'low power'
259
-
260
- case 2:
261
- return 'fault'
262
-
263
- case 3:
264
- return 'bulk'
265
-
266
- case 4:
267
- return 'absorption'
268
-
269
- case 5:
270
- return 'float'
271
-
272
- case 9:
273
- return 'inverting'
274
-
275
- default:
276
- return null
277
- }
278
- }
279
-
280
- getTrackerOperationMode (mppt) {
281
- mppt = parseInt(mppt, 10)
282
-
283
- switch (mppt) {
284
- case 0:
285
- return 'off'
286
-
287
- case 1:
288
- return 'voltage or current limited'
289
-
290
- case 2:
291
- return 'mpp tracker active'
292
-
293
- default:
294
- return null
295
- }
296
- }
297
-
298
- getProductLongname (pid) {
299
- pid = String(pid)
300
-
301
- if (!pid.includes('0x')) {
302
- pid = `0x${pid}`
303
- }
304
-
305
- if (!Object.keys(this.options.productIds).includes(pid)) {
306
- return 'Unknown'
307
- }
308
-
309
- return this.options.productIds[pid]
310
- }
311
-
312
- generateDelta (items) {
313
- const keys = Object.keys(this.data)
314
-
315
- const values = keys.map(name => {
316
- const path = this.getPath(name, items)
317
- if (path === null) {
318
- return null
319
- }
320
- return {
321
- path,
322
- value: this.data[name].value
323
- }
324
- }).filter(update => update !== null)
325
-
326
- if (values.length === 0) {
327
- return this.warn('No mutations in this delta')
328
- }
329
-
330
- this.emit('delta', {
331
- context: 'vessels.self',
332
- updates: [
333
- {
334
- source: {
335
- label: '@signalk/vedirect-serial-usb',
336
- type: 'VE.direct'
337
- },
338
- timestamp: new Date().toISOString(),
339
- values
340
- }
341
- ]
342
- })
343
- }
344
-
345
- getPath (name, items) {
346
- return Object.keys(this.fields).reduce((found, key) => {
347
- const field = this.fields[key]
348
- if (field.name === name && field.hasOwnProperty('path')) {
349
- let unitID = ''
350
- found = field.path
351
-
352
- if (field.hasOwnProperty('unitId')) {
353
- if (field.unitId === 'mainBatt' && this.options.hasOwnProperty('mainBatt')) {
354
- unitID = this.options.vedirect[items].mainBatt
355
- }
356
-
357
- if (field.unitId === 'auxBatt' && this.options.hasOwnProperty('auxBatt')) {
358
- unitID = this.options.vedirect[items].auxBatt
359
- }
360
-
361
- if (field.unitId === 'solar' && this.options.hasOwnProperty('solar')) {
362
- unitID = this.options.vedirect[items].solar
363
- }
364
-
365
- if ((!unitID || unitID === '') && this.options.hasOwnProperty('defaultUnitId') && typeof this.options.defaultUnitId === 'string') {
366
- unitID = this.options.defaultUnitId
367
- }
368
-
369
- if (this.options.hasOwnProperty('overrideUnitId') && typeof this.options.overrideUnitId === 'string') {
370
- unitID = this.options.overrideUnitId
371
- }
372
-
373
- found = found.replace('*', unitID)
374
- }
375
- }
376
- return found
377
- }, null)
378
- }
379
-
380
- warn (message) {
381
- this.debug(`Warning: ${message}`)
382
- this.emit('warn', message)
383
- }
384
-
385
- error (err) {
386
- this.debug(`Error: ${err.message}`)
387
- this.emit('error', err)
388
- }
389
- }
390
-
391
- module.exports = VEDirectParser