@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/dist/index.js ADDED
@@ -0,0 +1,209 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ /**
36
+ * Signal K server plugin entry point.
37
+ *
38
+ * Reads VE.Direct data over Serial, UDP or TCP, parses it (src/Parser.ts) and
39
+ * forwards the resulting Signal K deltas to the host. Supports several
40
+ * connections at once (`options.vedirect[]`) and keeps an in-memory fallback
41
+ * for the legacy single-connection config format.
42
+ */
43
+ const serial = __importStar(require("./serial"));
44
+ const udp = __importStar(require("./udp"));
45
+ const tcp = __importStar(require("./tcp"));
46
+ const Parser_1 = require("./Parser");
47
+ const constants_1 = require("./constants");
48
+ const createPlugin = function (app) {
49
+ const parser = [];
50
+ let shaddow = null;
51
+ function startConnection(conn, connectionIndex) {
52
+ const instance = new Parser_1.VEDirectParser(shaddow ?? undefined);
53
+ parser[connectionIndex] = instance;
54
+ instance.on('delta', (delta) => {
55
+ app.handleMessage(constants_1.PLUGIN_ID, delta);
56
+ });
57
+ if (conn.device === 'Serial') {
58
+ serial.open(conn.connection, parser, app.debug, connectionIndex);
59
+ }
60
+ else if (conn.device === 'UDP') {
61
+ udp.listen(conn.port, parser, app.debug, connectionIndex);
62
+ }
63
+ else if (conn.device === 'TCP') {
64
+ tcp.connect(conn.connection, conn.port, parser, app.debug, connectionIndex);
65
+ }
66
+ }
67
+ // Builds the current multi-connection config from a legacy flat config so
68
+ // that installations predating the `vedirect[]` rework keep working without
69
+ // a persisted migration.
70
+ function fromLegacy(options) {
71
+ const base = {
72
+ ignoreChecksum: options.ignoreChecksum ?? true,
73
+ mainBatt: options.mainBatt ?? 'House',
74
+ auxBatt: options.auxBatt ?? 'Starter',
75
+ bmv: options.bmv ?? 'bmv',
76
+ solar: options.solar ?? 'Main',
77
+ deviceType: options.deviceType
78
+ };
79
+ if (options.device) {
80
+ return { device: 'Serial', connection: options.device, port: 0, ...base };
81
+ }
82
+ if (options.udpPort) {
83
+ return {
84
+ device: 'UDP',
85
+ connection: 'localhost',
86
+ port: options.udpPort,
87
+ ...base
88
+ };
89
+ }
90
+ if (options.host) {
91
+ return {
92
+ device: 'TCP',
93
+ connection: options.host,
94
+ port: options.tcpPort ?? 0,
95
+ ...base
96
+ };
97
+ }
98
+ return null;
99
+ }
100
+ const plugin = {
101
+ id: constants_1.PLUGIN_ID,
102
+ name: 'VE.Direct to Signal K',
103
+ description: 'VE.Direct to Signal K',
104
+ start(options) {
105
+ shaddow = options;
106
+ if (options.vedirect !== undefined) {
107
+ options.vedirect.forEach((conn, connectionIndex) => {
108
+ startConnection(conn, connectionIndex);
109
+ });
110
+ return;
111
+ }
112
+ const legacy = fromLegacy(options);
113
+ if (legacy !== null) {
114
+ shaddow = { ...options, vedirect: [legacy] };
115
+ startConnection(legacy, 0);
116
+ }
117
+ },
118
+ stop() {
119
+ if (!shaddow) {
120
+ return;
121
+ }
122
+ if (shaddow.vedirect !== undefined) {
123
+ shaddow.vedirect.forEach((conn, connectionIndex) => {
124
+ parser[connectionIndex]?.removeAllListeners();
125
+ delete parser[connectionIndex];
126
+ if (conn.device === 'Serial') {
127
+ serial.close(app.debug, connectionIndex);
128
+ }
129
+ else if (conn.device === 'UDP') {
130
+ udp.close(app.debug, connectionIndex);
131
+ }
132
+ else {
133
+ tcp.close(app.debug, connectionIndex);
134
+ }
135
+ });
136
+ }
137
+ shaddow = null;
138
+ },
139
+ schema: {
140
+ type: 'object',
141
+ properties: {
142
+ vedirect: {
143
+ type: 'array',
144
+ title: 'Connections',
145
+ description: 'Connections to VE.Direct devices',
146
+ items: {
147
+ type: 'object',
148
+ required: [],
149
+ properties: {
150
+ device: {
151
+ type: 'string',
152
+ default: 'Serial',
153
+ title: 'Select device',
154
+ enum: ['Serial', 'UDP', 'TCP']
155
+ },
156
+ connection: {
157
+ type: 'string',
158
+ title: 'Connection details',
159
+ description: 'Serial: e.g. /dev/ttyUSB0, UDP: ignored or TCP: IP address',
160
+ default: '/dev/ttyUSB0'
161
+ },
162
+ port: {
163
+ type: 'number',
164
+ title: 'Port',
165
+ description: 'Serial: ignored, UDP/TCP: port',
166
+ default: 7878
167
+ },
168
+ deviceType: {
169
+ type: 'string',
170
+ title: 'Device type',
171
+ description: 'Battery monitor keeps V/I under electrical.batteries; Solar charger (MPPT) routes V/I under electrical.solar to avoid clashing with a battery monitor on the same bank',
172
+ default: 'Battery monitor',
173
+ enum: ['Battery monitor', 'Solar charger']
174
+ },
175
+ ignoreChecksum: {
176
+ type: 'boolean',
177
+ title: 'Ignore Checksum',
178
+ default: true
179
+ },
180
+ mainBatt: {
181
+ type: 'string',
182
+ title: 'Main Battery name in SK path',
183
+ default: 'House'
184
+ },
185
+ auxBatt: {
186
+ type: 'string',
187
+ title: 'Aux Battery name in SK path',
188
+ default: 'Starter'
189
+ },
190
+ bmv: {
191
+ type: 'string',
192
+ title: 'BMV name in SK path',
193
+ default: 'bmv'
194
+ },
195
+ solar: {
196
+ type: 'string',
197
+ title: 'Solar name in SK path',
198
+ default: 'Main'
199
+ }
200
+ }
201
+ }
202
+ }
203
+ }
204
+ }
205
+ };
206
+ return plugin;
207
+ };
208
+ module.exports = createPlugin;
209
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Victron product ID (PID) to human-readable model name.
3
+ *
4
+ * Kept as a TypeScript module rather than a JSON asset so that `tsc` emits
5
+ * it into `dist/` like any other source file (tsc does not copy `.json`
6
+ * files to the output directory).
7
+ */
8
+ export declare const productIds: Record<string, string>;
9
+ //# sourceMappingURL=productIds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"productIds.d.ts","sourceRoot":"","sources":["../src/productIds.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAmF7C,CAAA"}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.productIds = void 0;
4
+ /**
5
+ * Victron product ID (PID) to human-readable model name.
6
+ *
7
+ * Kept as a TypeScript module rather than a JSON asset so that `tsc` emits
8
+ * it into `dist/` like any other source file (tsc does not copy `.json`
9
+ * files to the output directory).
10
+ */
11
+ exports.productIds = {
12
+ '0x203': 'BMV-700',
13
+ '0x204': 'BMV-702',
14
+ '0x205': 'BMV-700H',
15
+ '0x300': 'BlueSolar MPPT 70/15',
16
+ '0xA040': 'BlueSolar MPPT 75/50',
17
+ '0xA041': 'BlueSolar MPPT 150/35',
18
+ '0xA042': 'BlueSolar MPPT 75/15',
19
+ '0xA043': 'BlueSolar MPPT 100/15',
20
+ '0xA044': 'BlueSolar MPPT 100/30',
21
+ '0xA045': 'BlueSolar MPPT 100/50',
22
+ '0xA046': 'BlueSolar MPPT 150/70',
23
+ '0xA047': 'BlueSolar MPPT 150/100',
24
+ '0xA049': 'BlueSolar MPPT 100/50 rev2',
25
+ '0xA04A': 'BlueSolar MPPT 100/30 rev2',
26
+ '0xA04B': 'BlueSolar MPPT 150/35 rev2',
27
+ '0xA04C': 'BlueSolar MPPT 75/10',
28
+ '0xA04D': 'BlueSolar MPPT 150/45',
29
+ '0xA04E': 'BlueSolar MPPT 150/60',
30
+ '0xA04F': 'BlueSolar MPPT 150/85',
31
+ '0xA050': 'SmartSolar MPPT 250/100',
32
+ '0xA051': 'SmartSolar MPPT 150/100*',
33
+ '0xA052': 'SmartSolar MPPT 150/85*',
34
+ '0xA053': 'SmartSolar MPPT 75/15',
35
+ '0xA054': 'SmartSolar MPPT 75/10',
36
+ '0xA055': 'SmartSolar MPPT 100/15',
37
+ '0xA056': 'SmartSolar MPPT 100/30',
38
+ '0xA057': 'SmartSolar MPPT 100/50',
39
+ '0xA058': 'SmartSolar MPPT 150/35',
40
+ '0xA059': 'SmartSolar MPPT 150/100 rev2',
41
+ '0xA05A': 'SmartSolar MPPT 150/85 rev2',
42
+ '0xA05B': 'SmartSolar MPPT 250/70',
43
+ '0xA05C': 'SmartSolar MPPT 250/85',
44
+ '0xA05D': 'SmartSolar MPPT 250/60',
45
+ '0xA05E': 'SmartSolar MPPT 250/45',
46
+ '0xA05F': 'SmartSolar MPPT 100/20',
47
+ '0xA060': 'SmartSolar MPPT 100/20 48V',
48
+ '0xA061': 'SmartSolar MPPT 150/45',
49
+ '0xA062': 'SmartSolar MPPT 150/60',
50
+ '0xA063': 'SmartSolar MPPT 150/70',
51
+ '0xA064': 'SmartSolar MPPT 250/85 rev2',
52
+ '0xA065': 'SmartSolar MPPT 250/100 rev2',
53
+ '0xA201': 'Phoenix Inverter 12V 250VA 230V*',
54
+ '0xA202': 'Phoenix Inverter 24V 250VA 230V*',
55
+ '0xA204': 'Phoenix Inverter 48V 250VA 230V*',
56
+ '0xA211': 'Phoenix Inverter 12V 375VA 230V*',
57
+ '0xA212': 'Phoenix Inverter 24V 375VA 230V*',
58
+ '0xA214': 'Phoenix Inverter 48V 375VA 230V*',
59
+ '0xA221': 'Phoenix Inverter 12V 500VA 230V*',
60
+ '0xA222': 'Phoenix Inverter 24V 500VA 230V*',
61
+ '0xA224': 'Phoenix Inverter 48V 500VA 230V*',
62
+ '0xA231': 'Phoenix Inverter 12V 250VA 230V',
63
+ '0xA232': 'Phoenix Inverter 24V 250VA 230V',
64
+ '0xA234': 'Phoenix Inverter 48V 250VA 230V',
65
+ '0xA239': 'Phoenix Inverter 12V 250VA 120V',
66
+ '0xA23A': 'Phoenix Inverter 24V 250VA 120V',
67
+ '0xA23C': 'Phoenix Inverter 48V 250VA 120V',
68
+ '0xA241': 'Phoenix Inverter 12V 375VA 230V',
69
+ '0xA242': 'Phoenix Inverter 24V 375VA 230V',
70
+ '0xA244': 'Phoenix Inverter 48V 375VA 230V',
71
+ '0xA249': 'Phoenix Inverter 12V 375VA 120V',
72
+ '0xA24A': 'Phoenix Inverter 24V 375VA 120V',
73
+ '0xA24C': 'Phoenix Inverter 48V 375VA 120V',
74
+ '0xA251': 'Phoenix Inverter 12V 500VA 230V',
75
+ '0xA252': 'Phoenix Inverter 24V 500VA 230V',
76
+ '0xA254': 'Phoenix Inverter 48V 500VA 230V',
77
+ '0xA259': 'Phoenix Inverter 12V 500VA 120V',
78
+ '0xA25A': 'Phoenix Inverter 24V 500VA 120V',
79
+ '0xA25C': 'Phoenix Inverter 48V 500VA 120V',
80
+ '0xA261': 'Phoenix Inverter 12V 800VA 230V',
81
+ '0xA262': 'Phoenix Inverter 24V 800VA 230V',
82
+ '0xA264': 'Phoenix Inverter 48V 800VA 230V',
83
+ '0xA269': 'Phoenix Inverter 12V 800VA 120V',
84
+ '0xA26A': 'Phoenix Inverter 24V 800VA 120V',
85
+ '0xA26C': 'Phoenix Inverter 48V 800VA 120V',
86
+ '0xA271': 'Phoenix Inverter 12V 1200VA 230V',
87
+ '0xA272': 'Phoenix Inverter 24V 1200VA 230V',
88
+ '0xA274': 'Phoenix Inverter 48V 1200VA 230V',
89
+ '0xA279': 'Phoenix Inverter 12V 1200VA 120V',
90
+ '0xA27A': 'Phoenix Inverter 24V 1200VA 120V',
91
+ '0xA27C': 'Phoenix Inverter 48V 1200VA 120V',
92
+ '0xA345': 'Phoenix Smart Charger 12V 30A 3 rev2',
93
+ '0xA381': 'BMV-712 Smart'
94
+ };
95
+ //# sourceMappingURL=productIds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"productIds.js","sourceRoot":"","sources":["../src/productIds.ts"],"names":[],"mappings":";;;AAAA;;;;;;GAMG;AACU,QAAA,UAAU,GAA2B;IAChD,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,UAAU;IACnB,OAAO,EAAE,sBAAsB;IAC/B,QAAQ,EAAE,sBAAsB;IAChC,QAAQ,EAAE,uBAAuB;IACjC,QAAQ,EAAE,sBAAsB;IAChC,QAAQ,EAAE,uBAAuB;IACjC,QAAQ,EAAE,uBAAuB;IACjC,QAAQ,EAAE,uBAAuB;IACjC,QAAQ,EAAE,uBAAuB;IACjC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,4BAA4B;IACtC,QAAQ,EAAE,4BAA4B;IACtC,QAAQ,EAAE,4BAA4B;IACtC,QAAQ,EAAE,sBAAsB;IAChC,QAAQ,EAAE,uBAAuB;IACjC,QAAQ,EAAE,uBAAuB;IACjC,QAAQ,EAAE,uBAAuB;IACjC,QAAQ,EAAE,yBAAyB;IACnC,QAAQ,EAAE,0BAA0B;IACpC,QAAQ,EAAE,yBAAyB;IACnC,QAAQ,EAAE,uBAAuB;IACjC,QAAQ,EAAE,uBAAuB;IACjC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,8BAA8B;IACxC,QAAQ,EAAE,6BAA6B;IACvC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,4BAA4B;IACtC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,6BAA6B;IACvC,QAAQ,EAAE,8BAA8B;IACxC,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,iCAAiC;IAC3C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,sCAAsC;IAChD,QAAQ,EAAE,eAAe;CAC1B,CAAA"}
@@ -0,0 +1,5 @@
1
+ import type { VEDirectParser } from './Parser';
2
+ import type { DebugFn } from './types';
3
+ export declare function open(device: string, parser: VEDirectParser[], debug: DebugFn, connectionIndex: number): void;
4
+ export declare function close(debug: DebugFn, connectionIndex: number): void;
5
+ //# sourceMappingURL=serial.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serial.d.ts","sourceRoot":"","sources":["../src/serial.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAQtC,wBAAgB,IAAI,CAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,cAAc,EAAE,EACxB,KAAK,EAAE,OAAO,EACd,eAAe,EAAE,MAAM,GACtB,IAAI,CA4CN;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,CAGnE"}
package/dist/serial.js ADDED
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.open = open;
4
+ exports.close = close;
5
+ /**
6
+ * Serial (VE.Direct to USB) transport.
7
+ *
8
+ * Opens a serial port per connection index, splits the stream on `\r`
9
+ * (VE.Direct line terminator) and feeds each line into the matching parser.
10
+ * If the port closes unexpectedly (e.g. the USB cable is unplugged) it is
11
+ * re-opened after a back-off, unless it was deliberately closed via `close()`
12
+ * (which clears the slot and cancels any pending reconnect). Ports are tracked
13
+ * by connection index so several connections can run side by side.
14
+ */
15
+ const serialport_1 = require("serialport");
16
+ const parser_delimiter_1 = require("@serialport/parser-delimiter");
17
+ const BAUD_RATE = 19200;
18
+ const RECONNECT_DELAY_MS = 10000;
19
+ const port = [];
20
+ const reconnectTimer = [];
21
+ function open(device, parser, debug, connectionIndex) {
22
+ closePort(connectionIndex);
23
+ debug(`Serial: connecting to ${device}`);
24
+ const sp = new serialport_1.SerialPort({ path: device, baudRate: BAUD_RATE });
25
+ port[connectionIndex] = sp;
26
+ sp.on('open', () => {
27
+ debug(`Connected to ${device}`);
28
+ });
29
+ sp.on('data', (chunk) => {
30
+ debug(`${chunk}`);
31
+ });
32
+ const parsed = sp.pipe(new parser_delimiter_1.DelimiterParser({ delimiter: '\r', includeDelimiter: true }));
33
+ parsed.on('data', (chunk) => {
34
+ // Chunk is a node.js Buffer
35
+ parser[connectionIndex]?.addChunk(chunk, connectionIndex);
36
+ debug(`${chunk}`);
37
+ });
38
+ sp.on('error', (err) => {
39
+ debug(`SerialPort error on ${device}: ${err.message}`);
40
+ });
41
+ sp.on('close', () => {
42
+ // Reconnect only if this is still the active port for the slot. A deliberate
43
+ // close() clears the slot first, and a re-open replaces it, so in both cases
44
+ // the stale port must not trigger a reconnect.
45
+ if (port[connectionIndex] === sp) {
46
+ debug(`Serial port ${device} closed; reconnecting in ${RECONNECT_DELAY_MS}ms`);
47
+ reconnectTimer[connectionIndex] = setTimeout(() => {
48
+ reconnectTimer[connectionIndex] = undefined;
49
+ open(device, parser, debug, connectionIndex);
50
+ }, RECONNECT_DELAY_MS);
51
+ }
52
+ });
53
+ }
54
+ function close(debug, connectionIndex) {
55
+ closePort(connectionIndex);
56
+ debug('Serial port closed');
57
+ }
58
+ // Cancels any pending reconnect and closes the active port for a slot. The slot
59
+ // is cleared before close() so the port's 'close' handler does not schedule a
60
+ // reconnect for a deliberate teardown.
61
+ function closePort(connectionIndex) {
62
+ const timer = reconnectTimer[connectionIndex];
63
+ if (timer !== undefined) {
64
+ clearTimeout(timer);
65
+ reconnectTimer[connectionIndex] = undefined;
66
+ }
67
+ const sp = port[connectionIndex];
68
+ if (sp !== undefined) {
69
+ port[connectionIndex] = undefined;
70
+ try {
71
+ sp.close();
72
+ }
73
+ catch {
74
+ // best-effort: the port may already be gone
75
+ }
76
+ }
77
+ }
78
+ //# sourceMappingURL=serial.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serial.js","sourceRoot":"","sources":["../src/serial.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Standalone library wrapper.
3
+ *
4
+ * Shims the signalk-server host so the plugin can be consumed as a plain
5
+ * Node.js library (see the README "Usage as a library" section). The plugin's
6
+ * `app.handleMessage` deltas are re-emitted as `delta` events on this
7
+ * EventEmitter; functionality is otherwise identical to running inside
8
+ * signalk-server.
9
+ */
10
+ import { EventEmitter } from 'events';
11
+ import type { VEDirectConfig } from './types';
12
+ declare class VEDirect extends EventEmitter {
13
+ private readonly _debug;
14
+ private readonly app;
15
+ private readonly plugin;
16
+ constructor(config?: VEDirectConfig, _debug?: boolean);
17
+ start(): void;
18
+ stop(): void;
19
+ debug(...args: unknown[]): void;
20
+ }
21
+ export = VEDirect;
22
+ //# sourceMappingURL=standalone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standalone.d.ts","sourceRoot":"","sources":["../src/standalone.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAErC,OAAO,KAAK,EAKV,cAAc,EACf,MAAM,SAAS,CAAA;AAEhB,cAAM,QAAS,SAAQ,YAAY;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA0C;IAC9D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;gBAEnB,MAAM,GAAE,cAAmB,EAAE,MAAM,UAAQ;IAoCvD,KAAK,IAAI,IAAI;IASb,IAAI,IAAI,IAAI;IASZ,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;CAKhC;AAED,SAAS,QAAQ,CAAA"}
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ /**
3
+ * Standalone library wrapper.
4
+ *
5
+ * Shims the signalk-server host so the plugin can be consumed as a plain
6
+ * Node.js library (see the README "Usage as a library" section). The plugin's
7
+ * `app.handleMessage` deltas are re-emitted as `delta` events on this
8
+ * EventEmitter; functionality is otherwise identical to running inside
9
+ * signalk-server.
10
+ */
11
+ const events_1 = require("events");
12
+ const createPlugin = require("./index");
13
+ class VEDirect extends events_1.EventEmitter {
14
+ _debug;
15
+ app;
16
+ plugin;
17
+ constructor(config = {}, _debug = false) {
18
+ super();
19
+ this._debug = _debug;
20
+ const options = {
21
+ device: 'Serial',
22
+ connection: '/dev/ttyUSB0',
23
+ port: 7878,
24
+ ignoreChecksum: true,
25
+ mainBatt: 'House',
26
+ auxBatt: 'Starter',
27
+ bmv: 'bmv',
28
+ solar: 'Main',
29
+ ...config
30
+ };
31
+ this.app = {
32
+ handleMessage: (kind, data) => {
33
+ // The plugin posts its parsed deltas under its own id; re-emit those as
34
+ // `delta` events. Anything else the host might receive passes through
35
+ // on a channel named for its kind.
36
+ if (kind === this.plugin.id) {
37
+ this.emit('delta', data);
38
+ return;
39
+ }
40
+ this.emit(kind, data);
41
+ },
42
+ debug: (msg) => this.debug(msg),
43
+ options
44
+ };
45
+ this.plugin = createPlugin(this.app);
46
+ this.start();
47
+ }
48
+ start() {
49
+ if (typeof this.plugin.start !== 'function') {
50
+ this.debug("Plugin not initialised, can't start");
51
+ return;
52
+ }
53
+ this.plugin.start(this.app.options);
54
+ }
55
+ stop() {
56
+ if (typeof this.plugin.stop !== 'function') {
57
+ this.debug("Plugin not initialised, can't stop");
58
+ return;
59
+ }
60
+ this.plugin.stop();
61
+ }
62
+ debug(...args) {
63
+ if (this._debug) {
64
+ console.log(...args);
65
+ }
66
+ }
67
+ }
68
+ module.exports = VEDirect;
69
+ //# sourceMappingURL=standalone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standalone.js","sourceRoot":"","sources":["../src/standalone.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;AACH,mCAAqC;AACrC,wCAAwC;AASxC,MAAM,QAAS,SAAQ,qBAAY;IAChB,MAAM,CAAS;IACf,GAAG,CAA0C;IAC7C,MAAM,CAAQ;IAE/B,YAAY,SAAyB,EAAE,EAAE,MAAM,GAAG,KAAK;QACrD,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QAEpB,MAAM,OAAO,GAAmB;YAC9B,MAAM,EAAE,QAAQ;YAChB,UAAU,EAAE,cAAc;YAC1B,IAAI,EAAE,IAAI;YACV,cAAc,EAAE,IAAI;YACpB,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,SAAS;YAClB,GAAG,EAAE,KAAK;YACV,KAAK,EAAE,MAAM;YACb,GAAG,MAAM;SACV,CAAA;QAED,IAAI,CAAC,GAAG,GAAG;YACT,aAAa,EAAE,CAAC,IAAY,EAAE,IAAa,EAAE,EAAE;gBAC7C,wEAAwE;gBACxE,sEAAsE;gBACtE,mCAAmC;gBACnC,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;oBAC5B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;oBACxB,OAAM;gBACR,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YACvB,CAAC;YACD,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;YACvC,OAAO;SACR,CAAA;QAED,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACpC,IAAI,CAAC,KAAK,EAAE,CAAA;IACd,CAAC;IAED,KAAK;QACH,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAA;YACjD,OAAM;QACR,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAwB,CAAC,CAAA;IACtD,CAAC;IAED,IAAI;QACF,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC3C,IAAI,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAA;YAChD,OAAM;QACR,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;IACpB,CAAC;IAED,KAAK,CAAC,GAAG,IAAe;QACtB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAA;QACtB,CAAC;IACH,CAAC;CACF;AAED,iBAAS,QAAQ,CAAA"}
package/dist/tcp.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import type { VEDirectParser } from './Parser';
2
+ import type { DebugFn } from './types';
3
+ export declare function connect(host: string, port: number, parser: VEDirectParser[], debug: DebugFn, connectionIndex: number): void;
4
+ export declare function close(debug: DebugFn, connectionIndex: number): void;
5
+ //# sourceMappingURL=tcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tcp.d.ts","sourceRoot":"","sources":["../src/tcp.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAkDtC,wBAAgB,OAAO,CACrB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,cAAc,EAAE,EACxB,KAAK,EAAE,OAAO,EACd,eAAe,EAAE,MAAM,GACtB,IAAI,CAsBN;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,CAanE"}
package/dist/tcp.js ADDED
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.connect = connect;
37
+ exports.close = close;
38
+ /**
39
+ * TCP transport.
40
+ *
41
+ * Connects to a host:port that bridges a remote VE.Direct device onto the
42
+ * network and feeds the received bytes into the matching parser. On close the
43
+ * socket is re-dialled after a back-off, unless it was deliberately closed via
44
+ * `close()` (which clears the slot and cancels any pending reconnect).
45
+ */
46
+ const Net = __importStar(require("net"));
47
+ const RECONNECT_DELAY_MS = 10000;
48
+ const SOCKET_TIMEOUT_MS = 5000;
49
+ const client = [];
50
+ const reconnectTimer = [];
51
+ function makeConnection(host, port, debug, connectionIndex) {
52
+ const socket = new Net.Socket();
53
+ socket.connect({ port, host });
54
+ socket.setTimeout(SOCKET_TIMEOUT_MS);
55
+ debug(`Connection to ${host}:${port}`);
56
+ client[connectionIndex] = socket;
57
+ return socket;
58
+ }
59
+ function onData(msg, parser, debug, connectionIndex) {
60
+ parser[connectionIndex]?.addChunk(msg, connectionIndex);
61
+ debug(`${msg}`);
62
+ }
63
+ function onClose(host, port, parser, debug, connectionIndex) {
64
+ // Only reconnect if the slot is still active (not cleared by close()). The
65
+ // timer handle is tracked so close() can cancel a pending reconnect.
66
+ if (client[connectionIndex] !== undefined) {
67
+ reconnectTimer[connectionIndex] = setTimeout(() => {
68
+ reconnectTimer[connectionIndex] = undefined;
69
+ debug(`Trying to reconnect to ${host}:${port}`);
70
+ connect(host, port, parser, debug, connectionIndex);
71
+ }, RECONNECT_DELAY_MS);
72
+ }
73
+ }
74
+ function connect(host, port, parser, debug, connectionIndex) {
75
+ const socket = makeConnection(host, port, debug, connectionIndex);
76
+ socket.on('data', (msg) => {
77
+ onData(msg, parser, debug, connectionIndex);
78
+ });
79
+ socket.on('close', () => {
80
+ debug(`TCP connection to ${host}:${port} closed`);
81
+ socket.destroy();
82
+ onClose(host, port, parser, debug, connectionIndex);
83
+ });
84
+ socket.on('error', (err) => {
85
+ debug(`TCP connection error ${host}:${port}: ${err.message}`);
86
+ socket.destroy();
87
+ });
88
+ socket.on('timeout', () => {
89
+ debug(`TCP connection timeout ${host}:${port}`);
90
+ socket.destroy();
91
+ });
92
+ }
93
+ function close(debug, connectionIndex) {
94
+ const timer = reconnectTimer[connectionIndex];
95
+ if (timer !== undefined) {
96
+ clearTimeout(timer);
97
+ reconnectTimer[connectionIndex] = undefined;
98
+ }
99
+ const socket = client[connectionIndex];
100
+ if (socket !== undefined) {
101
+ client[connectionIndex] = undefined;
102
+ socket.destroy();
103
+ debug('TCP port closed');
104
+ }
105
+ }
106
+ //# sourceMappingURL=tcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tcp.js","sourceRoot":"","sources":["../src/tcp.ts"],"names":[],"mappings":"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"}