@signalk/vedirect-serial-usb 1.5.0 → 1.7.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/LICENSE +201 -0
- package/README.md +36 -24
- package/dist/Parser.d.ts +50 -0
- package/dist/Parser.d.ts.map +1 -0
- package/dist/Parser.js +350 -0
- package/dist/Parser.js.map +1 -0
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +14 -0
- package/dist/constants.js.map +1 -0
- package/dist/fields.d.ts +14 -0
- package/dist/fields.d.ts.map +1 -0
- package/dist/fields.js +439 -0
- package/dist/fields.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +305 -0
- package/dist/index.js.map +1 -0
- package/dist/productIds.d.ts +9 -0
- package/dist/productIds.d.ts.map +1 -0
- package/dist/productIds.js +95 -0
- package/dist/productIds.js.map +1 -0
- package/dist/serial.d.ts +14 -0
- package/dist/serial.d.ts.map +1 -0
- package/dist/serial.js +106 -0
- package/dist/serial.js.map +1 -0
- package/dist/standalone.d.ts +22 -0
- package/dist/standalone.d.ts.map +1 -0
- package/dist/standalone.js +73 -0
- package/dist/standalone.js.map +1 -0
- package/dist/tcp.d.ts +5 -0
- package/dist/tcp.d.ts.map +1 -0
- package/dist/tcp.js +106 -0
- package/dist/tcp.js.map +1 -0
- package/dist/types.d.ts +181 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +15 -0
- package/dist/types.js.map +1 -0
- package/dist/udp.d.ts +5 -0
- package/dist/udp.d.ts.map +1 -0
- package/dist/udp.js +67 -0
- package/dist/udp.js.map +1 -0
- package/docs/screenshots/1_config.png +0 -0
- package/logo.svg +46 -0
- package/package.json +79 -19
- package/.github/FUNDING.yml +0 -1
- package/.travis.yml +0 -13
- package/index.js +0 -159
- package/lib/Parser.js +0 -396
- package/lib/fields.js +0 -503
- package/lib/filestream.js +0 -38
- package/lib/productIds.json +0 -84
- package/lib/serial.js +0 -48
- package/lib/tcp.js +0 -53
- package/lib/udp.js +0 -26
- package/log/one.txt +0 -18
- package/log/run-log.js +0 -7
- package/log/sampleOutput.txt +0 -297
- package/migration.js +0 -57
- package/run.js +0 -10
- package/standalone.js +0 -68
- package/test/index.js +0 -52
- package/todo.md +0 -14
package/dist/index.js
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
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
|
+
// VE.Direct HEX "Set" frames toggling the BMV-7xx built-in relay (register
|
|
49
|
+
// 0x034E), exposing it as a writable Signal K switch for other plugins.
|
|
50
|
+
//
|
|
51
|
+
// : 8 4E03 00 VV CC \n
|
|
52
|
+
// | Set reg LE flags val checksum
|
|
53
|
+
//
|
|
54
|
+
// CC is chosen so (0x08 + every payload byte) & 0xFF == 0x55 (VE.Direct HEX
|
|
55
|
+
// checksum): on -> val 0x01 -> :84E030001FB, off -> val 0x00 -> :84E030000FC.
|
|
56
|
+
// The BMV only acts on these once its relay is set to remote control.
|
|
57
|
+
const RELAY_ON = ':84E030001FB\n';
|
|
58
|
+
const RELAY_OFF = ':84E030000FC\n';
|
|
59
|
+
// Maps a Signal K relay PUT value to its VE.Direct command. Accepts the numeric
|
|
60
|
+
// 1/0 the relay state is published as (see the RELAY field in src/fields.ts) and
|
|
61
|
+
// boolean true/false for convenience. Returns null for any out-of-range value so
|
|
62
|
+
// the handler can reject it.
|
|
63
|
+
function relayCommand(value) {
|
|
64
|
+
if (value === 1 || value === true) {
|
|
65
|
+
return RELAY_ON;
|
|
66
|
+
}
|
|
67
|
+
if (value === 0 || value === false) {
|
|
68
|
+
return RELAY_OFF;
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
const createPlugin = function (app) {
|
|
73
|
+
const parser = [];
|
|
74
|
+
// Unregister callbacks for the relay PUT handlers, indexed by connection like
|
|
75
|
+
// `parser`, so stop() can tear each one down.
|
|
76
|
+
const putUnregister = [];
|
|
77
|
+
// Relay paths already claimed by a registered handler. Two serial connections
|
|
78
|
+
// configured with the same BMV name resolve to the same path; the host keeps
|
|
79
|
+
// only one handler, so a PUT could drive the wrong port. The duplicate is
|
|
80
|
+
// refused instead. Cleared on stop().
|
|
81
|
+
const registeredRelayPaths = new Set();
|
|
82
|
+
let shaddow = null;
|
|
83
|
+
// Builds the PUT handler for one serial connection's BMV relay. It writes the
|
|
84
|
+
// matching VE.Direct HEX command and reports failure (rather than a false 200)
|
|
85
|
+
// when the value is out of range or the serial port is not open. A 200 means
|
|
86
|
+
// the frame was written to the port, not that the relay switched: the BMV sends
|
|
87
|
+
// no acknowledgement and acts only when its relay is in remote control, so the
|
|
88
|
+
// reply says "sent", not "confirmed". Each outcome is logged so a command that
|
|
89
|
+
// looks accepted but changes nothing is still diagnosable from the plugin log.
|
|
90
|
+
function relayPutHandler(connectionIndex) {
|
|
91
|
+
return (_context, path, value) => {
|
|
92
|
+
const command = relayCommand(value);
|
|
93
|
+
if (command === null) {
|
|
94
|
+
app.debug(`Relay PUT on ${path} rejected: ${JSON.stringify(value)} is not 0/1 or true/false`);
|
|
95
|
+
return {
|
|
96
|
+
state: 'COMPLETED',
|
|
97
|
+
statusCode: 400,
|
|
98
|
+
message: `Invalid relay value ${JSON.stringify(value)} for ${path}; expected 0/1 or true/false`
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
const desired = command === RELAY_ON ? 'on' : 'off';
|
|
102
|
+
if (!serial.write(command, connectionIndex)) {
|
|
103
|
+
app.debug(`Relay PUT on ${path} ignored: serial connection ${connectionIndex} is not open`);
|
|
104
|
+
return {
|
|
105
|
+
state: 'COMPLETED',
|
|
106
|
+
statusCode: 503,
|
|
107
|
+
message: `Serial connection ${connectionIndex} is not open; relay unchanged`
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
app.debug(`Relay PUT on ${path}: ${desired} command sent to serial connection ${connectionIndex} (the BMV applies it only when its relay is in remote control)`);
|
|
111
|
+
return {
|
|
112
|
+
state: 'COMPLETED',
|
|
113
|
+
statusCode: 200,
|
|
114
|
+
message: `Relay ${desired} command sent; takes effect only when the BMV relay is set to remote control`
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
// Exposes the BMV relay as a writable Signal K path for one serial connection,
|
|
119
|
+
// anchored on the configured BMV name (matching the RELAY read field's path,
|
|
120
|
+
// electrical.batteries.<bmv>). The relay belongs to the BMV-7xx, so it is
|
|
121
|
+
// registered only for battery monitors (the default when deviceType is unset),
|
|
122
|
+
// never for a solar charger, and only when a BMV name is configured to anchor
|
|
123
|
+
// the path. The skipped cases are logged rather than silent: the RELAY field
|
|
124
|
+
// still publishes the relay state, so a writable path that is quietly absent
|
|
125
|
+
// would be a mystery to whoever tries to PUT to it.
|
|
126
|
+
function registerRelayHandler(conn, connectionIndex) {
|
|
127
|
+
if (conn.deviceType === 'Solar charger') {
|
|
128
|
+
app.debug(`Serial connection ${connectionIndex} is a solar charger, not a BMV; relay control disabled`);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (!conn.bmv) {
|
|
132
|
+
app.debug(`Serial connection ${connectionIndex} has no BMV name; relay control disabled`);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const path = `electrical.batteries.${conn.bmv}.relay`;
|
|
136
|
+
if (registeredRelayPaths.has(path)) {
|
|
137
|
+
app.debug(`Relay path ${path} is already registered by another connection; relay control disabled for serial connection ${connectionIndex}`);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
registeredRelayPaths.add(path);
|
|
141
|
+
putUnregister[connectionIndex] = app.registerPutHandler('vessels.self', path, relayPutHandler(connectionIndex));
|
|
142
|
+
}
|
|
143
|
+
function startConnection(conn, connectionIndex) {
|
|
144
|
+
const instance = new Parser_1.VEDirectParser(shaddow ?? undefined);
|
|
145
|
+
parser[connectionIndex] = instance;
|
|
146
|
+
instance.on('delta', (delta) => {
|
|
147
|
+
app.handleMessage(constants_1.PLUGIN_ID, delta);
|
|
148
|
+
});
|
|
149
|
+
if (conn.device === 'Serial') {
|
|
150
|
+
serial.open(conn.connection, parser, app.debug, connectionIndex);
|
|
151
|
+
registerRelayHandler(conn, connectionIndex);
|
|
152
|
+
}
|
|
153
|
+
else if (conn.device === 'UDP') {
|
|
154
|
+
udp.listen(conn.port, parser, app.debug, connectionIndex);
|
|
155
|
+
}
|
|
156
|
+
else if (conn.device === 'TCP') {
|
|
157
|
+
tcp.connect(conn.connection, conn.port, parser, app.debug, connectionIndex);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Builds the current multi-connection config from a legacy flat config so
|
|
161
|
+
// that installations predating the `vedirect[]` rework keep working without
|
|
162
|
+
// a persisted migration.
|
|
163
|
+
function fromLegacy(options) {
|
|
164
|
+
const base = {
|
|
165
|
+
ignoreChecksum: options.ignoreChecksum ?? true,
|
|
166
|
+
mainBatt: options.mainBatt ?? 'House',
|
|
167
|
+
auxBatt: options.auxBatt ?? 'Starter',
|
|
168
|
+
bmv: options.bmv ?? 'bmv',
|
|
169
|
+
solar: options.solar ?? 'Main',
|
|
170
|
+
deviceType: options.deviceType
|
|
171
|
+
};
|
|
172
|
+
if (options.device) {
|
|
173
|
+
return { device: 'Serial', connection: options.device, port: 0, ...base };
|
|
174
|
+
}
|
|
175
|
+
if (options.udpPort) {
|
|
176
|
+
return {
|
|
177
|
+
device: 'UDP',
|
|
178
|
+
connection: 'localhost',
|
|
179
|
+
port: options.udpPort,
|
|
180
|
+
...base
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
if (options.host) {
|
|
184
|
+
return {
|
|
185
|
+
device: 'TCP',
|
|
186
|
+
connection: options.host,
|
|
187
|
+
port: options.tcpPort ?? 0,
|
|
188
|
+
...base
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
const plugin = {
|
|
194
|
+
id: constants_1.PLUGIN_ID,
|
|
195
|
+
name: 'VE.Direct to Signal K',
|
|
196
|
+
description: 'VE.Direct to Signal K',
|
|
197
|
+
start(options) {
|
|
198
|
+
shaddow = options;
|
|
199
|
+
if (options.vedirect !== undefined) {
|
|
200
|
+
options.vedirect.forEach((conn, connectionIndex) => {
|
|
201
|
+
startConnection(conn, connectionIndex);
|
|
202
|
+
});
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const legacy = fromLegacy(options);
|
|
206
|
+
if (legacy !== null) {
|
|
207
|
+
shaddow = { ...options, vedirect: [legacy] };
|
|
208
|
+
startConnection(legacy, 0);
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
stop() {
|
|
212
|
+
if (!shaddow) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (shaddow.vedirect !== undefined) {
|
|
216
|
+
shaddow.vedirect.forEach((conn, connectionIndex) => {
|
|
217
|
+
parser[connectionIndex]?.removeAllListeners();
|
|
218
|
+
delete parser[connectionIndex];
|
|
219
|
+
putUnregister[connectionIndex]?.();
|
|
220
|
+
delete putUnregister[connectionIndex];
|
|
221
|
+
if (conn.device === 'Serial') {
|
|
222
|
+
serial.close(app.debug, connectionIndex);
|
|
223
|
+
}
|
|
224
|
+
else if (conn.device === 'UDP') {
|
|
225
|
+
udp.close(app.debug, connectionIndex);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
tcp.close(app.debug, connectionIndex);
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
registeredRelayPaths.clear();
|
|
232
|
+
}
|
|
233
|
+
shaddow = null;
|
|
234
|
+
},
|
|
235
|
+
schema: {
|
|
236
|
+
type: 'object',
|
|
237
|
+
properties: {
|
|
238
|
+
vedirect: {
|
|
239
|
+
type: 'array',
|
|
240
|
+
title: 'Connections',
|
|
241
|
+
description: 'Connections to VE.Direct devices',
|
|
242
|
+
items: {
|
|
243
|
+
type: 'object',
|
|
244
|
+
required: [],
|
|
245
|
+
properties: {
|
|
246
|
+
device: {
|
|
247
|
+
type: 'string',
|
|
248
|
+
default: 'Serial',
|
|
249
|
+
title: 'Select device',
|
|
250
|
+
enum: ['Serial', 'UDP', 'TCP']
|
|
251
|
+
},
|
|
252
|
+
connection: {
|
|
253
|
+
type: 'string',
|
|
254
|
+
title: 'Connection details',
|
|
255
|
+
description: 'Serial: e.g. /dev/ttyUSB0, UDP: ignored or TCP: IP address',
|
|
256
|
+
default: '/dev/ttyUSB0'
|
|
257
|
+
},
|
|
258
|
+
port: {
|
|
259
|
+
type: 'number',
|
|
260
|
+
title: 'Port',
|
|
261
|
+
description: 'Serial: ignored, UDP/TCP: port',
|
|
262
|
+
default: 7878
|
|
263
|
+
},
|
|
264
|
+
deviceType: {
|
|
265
|
+
type: 'string',
|
|
266
|
+
title: 'Device type',
|
|
267
|
+
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',
|
|
268
|
+
default: 'Battery monitor',
|
|
269
|
+
enum: ['Battery monitor', 'Solar charger']
|
|
270
|
+
},
|
|
271
|
+
ignoreChecksum: {
|
|
272
|
+
type: 'boolean',
|
|
273
|
+
title: 'Ignore Checksum',
|
|
274
|
+
default: true
|
|
275
|
+
},
|
|
276
|
+
mainBatt: {
|
|
277
|
+
type: 'string',
|
|
278
|
+
title: 'Main Battery name in SK path',
|
|
279
|
+
default: 'House'
|
|
280
|
+
},
|
|
281
|
+
auxBatt: {
|
|
282
|
+
type: 'string',
|
|
283
|
+
title: 'Aux Battery name in SK path',
|
|
284
|
+
default: 'Starter'
|
|
285
|
+
},
|
|
286
|
+
bmv: {
|
|
287
|
+
type: 'string',
|
|
288
|
+
title: 'BMV name in SK path',
|
|
289
|
+
default: 'bmv'
|
|
290
|
+
},
|
|
291
|
+
solar: {
|
|
292
|
+
type: 'string',
|
|
293
|
+
title: 'Solar name in SK path',
|
|
294
|
+
default: 'Main'
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
return plugin;
|
|
303
|
+
};
|
|
304
|
+
module.exports = createPlugin;
|
|
305
|
+
//# 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"}
|
package/dist/serial.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
/**
|
|
6
|
+
* Writes a raw command to a connection's serial port, used for outbound
|
|
7
|
+
* VE.Direct HEX control frames (e.g. setting the BMV relay). Returns true only
|
|
8
|
+
* when the port is open and the write was issued; false when no open port
|
|
9
|
+
* exists for the index (including the gap while an unexpectedly-closed port
|
|
10
|
+
* awaits reconnect) so the caller can report failure instead of assuming the
|
|
11
|
+
* command reached the device.
|
|
12
|
+
*/
|
|
13
|
+
export declare function write(message: string, connectionIndex: number): boolean;
|
|
14
|
+
//# 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;AAED;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAkBvE"}
|
package/dist/serial.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.open = open;
|
|
4
|
+
exports.close = close;
|
|
5
|
+
exports.write = write;
|
|
6
|
+
/**
|
|
7
|
+
* Serial (VE.Direct to USB) transport.
|
|
8
|
+
*
|
|
9
|
+
* Opens a serial port per connection index, splits the stream on `\r`
|
|
10
|
+
* (VE.Direct line terminator) and feeds each line into the matching parser.
|
|
11
|
+
* If the port closes unexpectedly (e.g. the USB cable is unplugged) it is
|
|
12
|
+
* re-opened after a back-off, unless it was deliberately closed via `close()`
|
|
13
|
+
* (which clears the slot and cancels any pending reconnect). Ports are tracked
|
|
14
|
+
* by connection index so several connections can run side by side.
|
|
15
|
+
*/
|
|
16
|
+
const serialport_1 = require("serialport");
|
|
17
|
+
const parser_delimiter_1 = require("@serialport/parser-delimiter");
|
|
18
|
+
const BAUD_RATE = 19200;
|
|
19
|
+
const RECONNECT_DELAY_MS = 10000;
|
|
20
|
+
const port = [];
|
|
21
|
+
const reconnectTimer = [];
|
|
22
|
+
function open(device, parser, debug, connectionIndex) {
|
|
23
|
+
closePort(connectionIndex);
|
|
24
|
+
debug(`Serial: connecting to ${device}`);
|
|
25
|
+
const sp = new serialport_1.SerialPort({ path: device, baudRate: BAUD_RATE });
|
|
26
|
+
port[connectionIndex] = sp;
|
|
27
|
+
sp.on('open', () => {
|
|
28
|
+
debug(`Connected to ${device}`);
|
|
29
|
+
});
|
|
30
|
+
sp.on('data', (chunk) => {
|
|
31
|
+
debug(`${chunk}`);
|
|
32
|
+
});
|
|
33
|
+
const parsed = sp.pipe(new parser_delimiter_1.DelimiterParser({ delimiter: '\r', includeDelimiter: true }));
|
|
34
|
+
parsed.on('data', (chunk) => {
|
|
35
|
+
// Chunk is a node.js Buffer
|
|
36
|
+
parser[connectionIndex]?.addChunk(chunk, connectionIndex);
|
|
37
|
+
debug(`${chunk}`);
|
|
38
|
+
});
|
|
39
|
+
sp.on('error', (err) => {
|
|
40
|
+
debug(`SerialPort error on ${device}: ${err.message}`);
|
|
41
|
+
});
|
|
42
|
+
sp.on('close', () => {
|
|
43
|
+
// Reconnect only if this is still the active port for the slot. A deliberate
|
|
44
|
+
// close() clears the slot first, and a re-open replaces it, so in both cases
|
|
45
|
+
// the stale port must not trigger a reconnect.
|
|
46
|
+
if (port[connectionIndex] === sp) {
|
|
47
|
+
debug(`Serial port ${device} closed; reconnecting in ${RECONNECT_DELAY_MS}ms`);
|
|
48
|
+
reconnectTimer[connectionIndex] = setTimeout(() => {
|
|
49
|
+
reconnectTimer[connectionIndex] = undefined;
|
|
50
|
+
open(device, parser, debug, connectionIndex);
|
|
51
|
+
}, RECONNECT_DELAY_MS);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function close(debug, connectionIndex) {
|
|
56
|
+
closePort(connectionIndex);
|
|
57
|
+
debug('Serial port closed');
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Writes a raw command to a connection's serial port, used for outbound
|
|
61
|
+
* VE.Direct HEX control frames (e.g. setting the BMV relay). Returns true only
|
|
62
|
+
* when the port is open and the write was issued; false when no open port
|
|
63
|
+
* exists for the index (including the gap while an unexpectedly-closed port
|
|
64
|
+
* awaits reconnect) so the caller can report failure instead of assuming the
|
|
65
|
+
* command reached the device.
|
|
66
|
+
*/
|
|
67
|
+
function write(message, connectionIndex) {
|
|
68
|
+
const sp = port[connectionIndex];
|
|
69
|
+
if (sp === undefined || !sp.isOpen) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
sp.write(message);
|
|
74
|
+
// True means the write was issued, not flushed: serialport surfaces most
|
|
75
|
+
// write failures asynchronously via the 'error' event, which this
|
|
76
|
+
// synchronous boolean cannot reflect. The isOpen guard above covers the
|
|
77
|
+
// common "port not open" case, which is the failure mode worth reporting.
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// The port can still drop between the isOpen check and the write; treat
|
|
82
|
+
// that as a failed write rather than a thrown error to the PUT requester.
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Cancels any pending reconnect and closes the active port for a slot. The slot
|
|
87
|
+
// is cleared before close() so the port's 'close' handler does not schedule a
|
|
88
|
+
// reconnect for a deliberate teardown.
|
|
89
|
+
function closePort(connectionIndex) {
|
|
90
|
+
const timer = reconnectTimer[connectionIndex];
|
|
91
|
+
if (timer !== undefined) {
|
|
92
|
+
clearTimeout(timer);
|
|
93
|
+
reconnectTimer[connectionIndex] = undefined;
|
|
94
|
+
}
|
|
95
|
+
const sp = port[connectionIndex];
|
|
96
|
+
if (sp !== undefined) {
|
|
97
|
+
port[connectionIndex] = undefined;
|
|
98
|
+
try {
|
|
99
|
+
sp.close();
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// best-effort: the port may already be gone
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# 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;IAwCvD,KAAK,IAAI,IAAI;IASb,IAAI,IAAI,IAAI;IASZ,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;CAKhC;AAED,SAAS,QAAQ,CAAA"}
|