-
Notifications
You must be signed in to change notification settings - Fork 25
/
main.js
113 lines (89 loc) · 3.71 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
const EventEmitter = require('events');
const util = require('util');
let { SerialPort } = require('serialport');
const { DelimiterParser } = require('@serialport/parser-delimiter');
let connectedToSmartMeter = false;
let constructor;
const parsePacket = require('./lib/parsePacket');
const debug = require('./lib/debug');
const config = require('./config/config.json');
function P1Reader(options) {
if (typeof options !== 'object' || options.port == "" || options.baudRate == "" || options.parity == "" || options.dataBits == "" || options.stopBits == "") {
console.error("Parameters 'port', 'baudRate', 'parity', 'dataBits' and 'stopBit' are required since version 2.x.x to instantiate the module");
}
if (options.debug) {
debug.enableDebugMode();
}
// Overwrite serialport module when emulator mode is set
if (options.emulator) {
SerialPort = require('./lib/emulateSerialport');
SerialPort.setEmulatorOverrides(options.emulatorOverrides);
}
constructor = this;
EventEmitter.call(this);
_setupSerialConnection(options.port, options.baudRate, options.parity, options.dataBits, options.stopBits);
}
util.inherits(P1Reader, EventEmitter);
module.exports = P1Reader;
/**
* Setup serial port connection
*/
function _setupSerialConnection(port, baudRate, parity, dataBits, stopBits) {
debug.log('Trying to connect to Smart Meter via port: ' + port + ' (BaudRate: ' + baudRate + ', Parity: ' + parity + ', Databits: ' + dataBits + ', Stopbits: ' + stopBits + ')');
// Open serial port connection
const sp = new SerialPort({
path: port,
baudRate: baudRate,
parity: parity,
dataBits: dataBits,
stopBits: stopBits
});
const connectionTimeout = setTimeout(() => {
if (!connectedToSmartMeter) {
debug.log('Could not establish a connection with the Smart Meter (connection timeout)');
constructor.emit('error', 'Connection timeout');
}
}, 11000); // Set time for 11 seconds, since we should receive at least one message every 10 seconds from the Smart Meter
const parser = sp.pipe(new DelimiterParser({
delimiter: config.stopCharacter
}));
parser.on('data', data => {
const received = data.toString();
const startCharPos = received.indexOf(config.startCharacter);
if (startCharPos === -1) {
debug.log('no message start found in', received);
return;
}
const packet = received.substring(startCharPos);
const parsedPacket = parsePacket(packet);
// Emit a 'connected' event when we have actually successfully parsed our first data
if (!connectedToSmartMeter && parsedPacket.timestamp !== null) {
debug.log('Connection with Smart Meter established');
constructor.emit('connected');
connectedToSmartMeter = true;
clearTimeout(connectionTimeout);
}
debug.writeToLogFile(packet, parsedPacket);
constructor.emit('reading-raw', packet);
if (parsedPacket.timestamp !== null) {
constructor.emit('reading', parsedPacket);
} else {
constructor.emit('error', 'Invalid reading');
}
});
sp.on('open', () => {
debug.log('Serialport connection opened, trying to receive data from the Smart Meter...');
});
sp.on('error', (error) => {
debug.log('Error emitted: ' + error);
constructor.emit('error', error);
});
sp.on('close', () => {
debug.log('Connection closed');
constructor.emit('close');
});
constructor.close = (cb) => {
debug.log('Closing connection');
sp.close(cb);
};
}