-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.js
108 lines (91 loc) · 2.96 KB
/
index.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
const SerialPort = require('serialport');
const EventEmitter = require('events');
const BYTES_readCO2 = [0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00];
const BYTES_calibrateTo400 = [0xFF, 0x01, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00];
const BYTES_ABCOn = [0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00];
const BYTES_ABCOff = [0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00];
class MHZ19B extends EventEmitter {
constructor(port = '/dev/serial0') {
super();
this.serialPort = new SerialPort(port, { baudRate: 9600 });
this.buffer = [];
this.resolve;
this.reject;
this.serialPort.on('close', () => {
console.log('MH-Z19B port closed');
this.close();
});
this.serialPort.on('error', (err) => {
console.log('MH-Z19B error', err);
this.close();
});
this.serialPort.on('data', (data) => {
this.buffer.push(...data);
if (this.buffer.length < 9) {
return;
}
const reading = this.buffer.splice(0, 9);
this.buffer = [];
if (getChecksum(reading) != reading[8]) {
console.log('MH-Z19B - Bad checksum');
if (this.reject) {
this.reject('Bad checksum');
this.reject = null;
}
return;
}
const co2 = (reading[2] * 256) + reading[3];
this.emit('data', {co2});
if (this.resolve) {
this.resolve(co2);
this.resolve = null;
return;
}
})
}
_sendPacket(packet) {
const packetClone = [...packet];
appendChecksum(packetClone);
this.serialPort.write(packetClone, function (err) {
if (err) console.log('MH-Z19B send command error', err);
});
}
readCO2() {
this._sendPacket(BYTES_readCO2);
return new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
})
}
calibrate() {
console.log('Calibrating MH-Z19B sensor to 400 ppm...');
this._sendPacket(BYTES_calibrateTo400);
}
abcOn() {
console.log('Turning MH-Z19B ABC mode ON...');
this._sendPacket(BYTES_ABCOn);
}
abcOff() {
console.log('Turning MH-Z19B ABC mode OFF...');
this._sendPacket(BYTES_ABCOff);
}
}
function toHexStr(number) {
let result = `0x${number.toString(16)}`;
if (result.length == 3) result += '0';
return result;
}
function appendChecksum(packet) {
packet.push(toHexStr(getChecksum(packet)));
}
function getChecksum(packet) {
let checksum = 0;
for (i = 1; i < 8; i++) {
checksum += packet[i];
if (checksum >= 256) checksum -= 256;
}
checksum = 0xff - checksum;
checksum += 1;
return checksum;
}
module.exports = MHZ19B;