CO2 Sensor Uplink Decoder

Recommended decoder

1
function Decoder (hexData) {
2
let deviceData = {};
3
try {
4
const commandsReadingHelper = (deviceData, hexData, payloadLength) => {
5
6
let resultToPass = {};
7
let data = hexData.slice(0, -payloadLength);
8
let commands = data.match(/.{1,2}/g);
9
let command_len = 0;
10
commands.map((command, i) => {
11
switch (command.toLowerCase()) {
12
case '15':
13
{
14
try {
15
command_len = 2;
16
let data = { temperatureRangeSettings: { min: parseInt(commands[i + 1], 16), max: parseInt(commands[i + 2], 16) } };
17
Object.assign(resultToPass, { ...resultToPass }, { ...data });
18
} catch (e) {
19
// console.log(e)
20
}
21
}
22
break;
23
24
case '14':
25
{
26
try {
27
command_len = 1;
28
let data = { childLock: toBool(parseInt(commands[i + 1], 16)) };
29
Object.assign(resultToPass, { ...resultToPass }, { ...data });
30
} catch (e) {
31
// console.log(e)
32
}
33
}
34
break;
35
36
case '12':
37
{
38
try {
39
command_len = 1;
40
let data = { keepAliveTime: parseInt(commands[i + 1], 16) };
41
Object.assign(resultToPass, { ...resultToPass }, { ...data });
42
} catch (e) {
43
// console.log(e)
44
}
45
}
46
break;
47
48
case '13':
49
{
50
try {
51
command_len = 2;
52
let enabled = toBool(parseInt(commands[i + 1], 16));
53
let duration = parseInt(commands[i + 2], 16) * 5;
54
let tmp = ("0" + commands[i + 4].toString(16)).substr(-2);
55
let motorPos2 = ("0" + commands[i + 3].toString(16)).substr(-2);
56
let motorPos1 = tmp[0];
57
let motorPosition = parseInt(`0x${motorPos1}${motorPos2}`, 16);
58
let delta = Number(tmp[1]);
59
60
let data = { openWindowParams: { enabled: enabled, duration: duration, motorPosition: motorPosition, delta: delta } };
61
Object.assign(resultToPass, { ...resultToPass }, { ...data });
62
} catch (e) {
63
// console.log(e)
64
}
65
}
66
break;
67
68
case '18':
69
{
70
try {
71
command_len = 1;
72
let data = { operationalMode: (commands[i + 1]).toString() };
73
Object.assign(resultToPass, { ...resultToPass }, { ...data });
74
} catch (e) {
75
// console.log(e)
76
}
77
}
78
break;
79
80
case '16':
81
{
82
try {
83
command_len = 2;
84
let data = { internalAlgoParams: { period: parseInt(commands[i + 1], 16), pFirstLast: parseInt(commands[i + 2], 16), pNext: parseInt(commands[i + 3], 16) } };
85
Object.assign(resultToPass, { ...resultToPass }, { ...data });
86
} catch (e) {
87
// console.log(e)
88
}
89
}
90
break;
91
92
case '17':
93
{
94
try {
95
command_len = 2;
96
let data = { internalAlgoTdiffParams: { warm: parseInt(commands[i + 1], 16), cold: parseInt(commands[i + 2], 16) } };
97
Object.assign(resultToPass, { ...resultToPass }, { ...data });
98
} catch (e) {
99
// console.log(e)
100
}
101
}
102
break;
103
104
case '1b':
105
{
106
try {
107
command_len = 1;
108
let data = { uplinkType: commands[i + 1] };
109
Object.assign(resultToPass, { ...resultToPass }, { ...data });
110
} catch (e) {
111
// console.log(e)
112
}
113
}
114
break;
115
116
case '19':
117
{
118
try {
119
command_len = 1;
120
let commandResponse = parseInt(commands[i + 1], 16);
121
let periodInMinutes = (commandResponse * 5) / 60;
122
let data = { joinRetryPeriod: periodInMinutes };
123
Object.assign(resultToPass, { ...resultToPass }, { ...data });
124
} catch (e) {
125
// console.log(e)
126
}
127
}
128
break;
129
130
case '1d':
131
{
132
try {
133
command_len = 2;
134
// get default keepalive if it is not available in data
135
let deviceKeepAlive = deviceData.keepAliveTime ? deviceData.keepAliveTime : 5;
136
let wdpC = commands[i + 1] == '00' ? false : (commands[i + 1] * deviceKeepAlive) + 7;
137
let wdpUc = commands[i + 2] == '00' ? false : parseInt(commands[i + 2], 16);
138
let data = { watchDogParams: { wdpC, wdpUc } };
139
Object.assign(resultToPass, { ...resultToPass }, { ...data });
140
} catch (e) {
141
// console.log(e)
142
}
143
}
144
break;
145
146
case '04':
147
{
148
try {
149
command_len = 2;
150
// console.log(hexData)
151
let hardwareVersion = commands[i + 1];
152
let softwareVersion = commands[i + 2];
153
let data = { deviceVersions: { hardware: Number(hardwareVersion), software: Number(softwareVersion) } };
154
Object.assign(resultToPass, { ...resultToPass }, { ...data });
155
} catch (e) {
156
// console.log(e)
157
}
158
}
159
break;
160
case '1f':
161
{
162
try {
163
command_len = 4;
164
let good_medium = parseInt(`${commands[i + 1]}${commands[i + 2]}`, 16);
165
let medium_bad = parseInt(`${commands[i + 3]}${commands[i + 4]}`, 16);
166
167
let data = { boundaryLevels: { good_medium: Number(good_medium), medium_bad: Number(medium_bad) } };
168
Object.assign(resultToPass, { ...resultToPass }, { ...data });
169
170
} catch (e) {
171
// console.log(e)
172
}
173
}
174
break;
175
case '21':
176
{
177
try {
178
command_len = 2;
179
let data = { autoZeroValue: parseInt(`${commands[i + 1]}${commands[i + 2]}`, 16) };
180
Object.assign(resultToPass, { ...resultToPass }, { ...data });
181
} catch (e) {
182
// console.log(e)
183
}
184
}
185
break;
186
case '23':
187
{
188
try {
189
command_len = 3;
190
let good_zone = parseInt(commands[i + 1], 16);
191
let medium_zone = parseInt(commands[i + 2], 16);
192
let bad_zone = parseInt(commands[i + 3], 16);
193
194
let data = { notifyPeriod: { good_zone: Number(good_zone), medium_zone: Number(medium_zone), bad_zone: Number(bad_zone) } };
195
Object.assign(resultToPass, { ...resultToPass }, { ...data });
196
} catch (e) {
197
// console.log(e)
198
}
199
}
200
break;
201
case '25':
202
{
203
try {
204
command_len = 3;
205
let good_zone = parseInt(commands[i + 1], 16);
206
let medium_zone = parseInt(commands[i + 2], 16);
207
let bad_zone = parseInt(commands[i + 3], 16);
208
209
let data = { measurementPeriod: { good_zone: Number(good_zone), medium_zone: Number(medium_zone), bad_zone: Number(bad_zone) } };
210
Object.assign(resultToPass, { ...resultToPass }, { ...data });
211
} catch (e) {
212
// console.log(e)
213
}
214
}
215
break;
216
case '27':
217
{
218
try {
219
command_len = 9;
220
let duration_good_beeping = parseInt(commands[i + 1], 16);
221
let duration_good_loud = parseInt(commands[i + 2], 16) * 10;
222
let duration_good_silent = parseInt(commands[i + 3], 16) * 10;
223
224
let duration_medium_beeping = parseInt(commands[i + 4], 16);
225
let duration_medium_loud = parseInt(commands[i + 5], 16) * 10;
226
let duration_medium_silent = parseInt(commands[i + 6], 16) * 10;
227
228
let duration_bad_beeping = parseInt(commands[i + 7], 16);
229
let duration_bad_loud = parseInt(commands[i + 8], 16) * 10;
230
let duration_bad_silent = parseInt(commands[i + 9], 16) * 10;
231
232
let data = { buzzerNotification: {
233
duration_good_beeping: Number(duration_good_beeping), duration_good_loud: Number(duration_good_loud), duration_good_silent: Number(duration_good_silent),
234
duration_medium_beeping: Number(duration_medium_beeping), duration_medium_loud: Number(duration_medium_loud), duration_medium_silent: Number(duration_medium_silent),
235
duration_bad_beeping: Number(duration_bad_beeping), duration_bad_loud: Number(duration_bad_loud), duration_bad_silent: Number(duration_bad_silent) } };
236
237
Object.assign(resultToPass, { ...resultToPass }, { ...data });
238
} catch (e) {
239
// console.log(e)
240
}
241
}
242
break;
243
case '29':
244
{
245
try {
246
command_len = 15;
247
let red_good = parseInt(commands[i + 1], 16);
248
let green_good = parseInt(commands[i + 2], 16);
249
let blue_good = parseInt(commands[i + 3], 16);
250
let duration_good = parseInt(`${commands[i + 4]}${commands[i + 5]}`, 16) * 10;
251
252
let red_medium = parseInt(commands[i + 6], 16);
253
let green_medium = parseInt(commands[i + 7], 16);
254
let blue_medium = parseInt(commands[i + 8], 16);
255
let duration_medium = parseInt(`${commands[i + 9]}${commands[i + 10]}`, 16) * 10;
256
257
let red_bad = parseInt(commands[i + 11], 16);
258
let green_bad = parseInt(commands[i + 12], 16);
259
let blue_bad = parseInt(commands[i + 13], 16);
260
let duration_bad = parseInt(`${commands[i + 14]}${commands[i + 15]}`, 16) * 10;
261
262
let data = { ledNotification: {
263
red_good: Number(red_good), green_good: Number(green_good), blue_good: Number(blue_good), duration_good: Number(duration_good),
264
red_medium: Number(red_medium), green_medium: Number(green_medium), blue_medium: Number(blue_medium), duration_medium: Number(duration_medium),
265
red_bad: Number(red_bad), green_bad: Number(green_bad), blue_bad: Number(blue_bad), duration_bad: Number(duration_bad) } };
266
267
Object.assign(resultToPass, { ...resultToPass }, { ...data });
268
269
} catch (e) {
270
// console.log(e)
271
}
272
}
273
break;
274
case '2b':
275
{
276
try {
277
command_len = 1;
278
let data = { autoZeroPeriod: parseInt(commands[i + 1], 16) };
279
Object.assign(resultToPass, { ...resultToPass }, { ...data });
280
} catch (e) {
281
// console.log(e)
282
}
283
}
284
break;
285
286
default:
287
break;
288
}
289
commands.splice(i,command_len);
290
291
})
292
293
return resultToPass;
294
}
295
const handleKeepAliveData = (hexData) => {
296
var co2 = parseInt(hexData.substr(2,4),16);
297
var temperature = (parseInt(hexData.substr(6,4),16) - 400) / 10;
298
var humidity = Number(((parseInt(hexData.substr(10,2),16) * 100) / 256).toFixed(2));
299
var voltage = Number((((parseInt(hexData.substr(12,2),16) * 8) + 1600)/1000).toFixed(2));
300
301
let keepaliveData = {
302
CO2: co2,
303
temperature: temperature,
304
humidity: humidity,
305
voltage: voltage
306
};
307
Object.assign(deviceData, { ...deviceData }, { ...keepaliveData })
308
}
309
310
if (hexData) {
311
let byteArray = hexData.match(/.{1,2}/g).map(byte => { return parseInt(byte, 16) })
312
if (byteArray[0] == 1) {
313
handleKeepAliveData(hexData);
314
} else {
315
// parse command answers
316
let data = commandsReadingHelper(deviceData, hexData, 14);
317
Object.assign(deviceData, { ...deviceData }, { ...data });
318
319
// get only keepalive from device response
320
let keepaliveData = hexData.slice(-14);
321
handleKeepAliveData(keepaliveData);
322
}
323
324
return deviceData;
325
}
326
} catch (e) {
327
console.log(e)
328
console.log(`Unhandled data: ${hexData}`)
329
}
330
}
Copied!

JS ESC5 decoder

1
function Decoder(bytes){
2
var hexData = bytes.map(function(byte){
3
let num = byte.toString(16);
4
if(num.length<2){
5
num = "0"+num;
6
}
7
return num
8
})
9
hexData = String(hexData).split(",").join("")
10
11
var co2 = parseInt(hexData.substr(2,4),16);
12
var temperature = (parseInt(hexData.substr(6,4),16) - 400) / 10;
13
var humidity = Number(((parseInt(hexData.substr(10,2),16) * 100) / 256).toFixed(2));
14
var battery = Number((((parseInt(hexData.substr(12,2),16) * 8) + 1600)/1000).toFixed(2));
15
16
return {
17
"co2":co2,
18
"temperature": temperature,
19
"humidity": humidity,
20
"battery": battery
21
}
22
}
Copied!