-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathcatena-message-port2-decoder-node-red.js
143 lines (123 loc) · 3.56 KB
/
catena-message-port2-decoder-node-red.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// JavaScript source code
// This Node-RED decoding function decodes the record sent by the Catena 4612
// simple sensor app.
// calculate dewpoint (degrees C) given temperature (C) and relative humidity (0..100)
// from http://andrew.rsmas.miami.edu/bmcnoldy/Humidity.html
// rearranged for efficiency and to deal sanely with very low (< 1%) RH
function dewpoint(t, rh) {
var c1 = 243.04;
var c2 = 17.625;
var h = rh / 100;
if (h <= 0.01)
h = 0.01;
else if (h > 1.0)
h = 1.0;
var lnh = Math.log(h);
var tpc1 = t + c1;
var txc2 = t * c2;
var txc2_tpc1 = txc2 / tpc1;
var tdew = c1 * (lnh + txc2_tpc1) / (c2 - lnh - txc2_tpc1);
return tdew;
}
var b;
if ("payload_raw" in msg) {
// the console already decoded this
b = msg.payload_raw; // pick up data for convenience
// msg.payload_fields still has the decoded data
}
else {
// no console debug
b = msg.payload; // pick up data for conveneince
}
// an empty table to which we'll add result fields:
//
// result.vBat: the battery voltage (if present)
// result.vBus: the USB charger voltage (if provided)
// result.boot: the system boot counter, modulo 256
// result.t: temperature in degrees C
// result.p: station pressure in hPa (millibars). Note that this is not
// adjusted for the height above sealevel so can't be directly compared
// to weather.gov "barometric pressure"
// result.rh: relative humidity (in %)
// result.lux: light level, in lux
// result.aqi: air quality index
var result = {};
// check the message type byte
if (msg.port != 2) {
// not one of ours: report an error, return without a value,
// so that Node-RED doesn't propagate the message any further.
node.error("not ours! " + msg.port.toString());
return;
}
// i is used as the index into the message. Start with the flag byte.
var i = 0;
// fetch the bitmap.
var flags = b[i++];
if (flags & 0x1) {
// set vRaw to a uint16, and increment pointer
var vRaw = (b[i] << 8) + b[i + 1];
i += 2;
// interpret uint16 as an int16 instead.
if (vRaw & 0x8000)
vRaw += -0x10000;
// scale and save in result.
result.Vbat = vRaw / 4096.0;
}
if (flags & 0x2) {
var vRaw = (b[i] << 8) + b[i + 1];
i += 2;
if (vRaw & 0x8000)
vRaw += -0x10000;
result.VDD = vRaw / 4096.0;
}
if (flags & 0x4) {
var iBoot = b[i];
i += 1;
result.boot = iBoot;
}
if (flags & 0x8) {
// we have temp, pressure, RH
var tRaw = (b[i] << 8) + b[i + 1];
if (tRaw & 0x8000)
tRaw = -0x10000 + tRaw;
i += 2;
var pRaw = (b[i] << 8) + b[i + 1];
i += 2;
var hRaw = b[i++];
result.t = tRaw / 256;
result.p = pRaw * 4 / 100.0;
result.rh = hRaw / 256 * 100;
result.tDew = dewpoint(result.t, result.rh);
}
if (flags & 0x10) {
// we have light irradiance info
var irradiance = {};
result.irradiance = irradiance;
var lightRaw = (b[i] << 8) + b[i + 1];
i += 2;
irradiance.IR = lightRaw;
lightRaw = (b[i] << 8) + b[i + 1];
i += 2;
irradiance.White = lightRaw;
lightRaw = (b[i] << 8) + b[i + 1];
i += 2;
irradiance.UV = lightRaw;
}
if (flags & 0x20) {
var vRaw = (b[i] << 8) + b[i + 1];
i += 2;
if (vRaw & 0x8000)
vRaw += -0x10000;
result.vBus = vRaw / 4096.0;
}
// now update msg with the new payload and new .local field
// the old msg.payload is overwritten.
msg.payload = result;
msg.local =
{
nodeType: "Catena 4612",
platformType: "Catena 461x",
radioType: "Murata",
applicationName: "Simple sensor"
};
return msg;