-
Notifications
You must be signed in to change notification settings - Fork 3
/
otgwdec.js
70 lines (66 loc) · 2.33 KB
/
otgwdec.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
module.exports = function(RED) {
function popcount(x)
{
var mask = 1, count = 0;
while (mask)
{
if (x & mask) count++;
mask <<= 1;
}
return count;
}
function OTGWDec(config) {
RED.nodes.createNode(this,config);
var node = this;
this.on('input', function(msg,send,done) {
// If this is pre-node-red-1.0, 'send' will be undefined, so fallback to node.send
send = send || function() { node.send.apply(node,arguments) }
var raw = msg.payload.toString().toUpperCase();
// Perform sanity check on message
// Length should by message type + 8 hex characters
if (raw.length != 9)
{
node.warn("Illegal message length '"+raw+"'");
return;
}
const M_THERMOSTAT = 0;
const M_BOILER = 1;
const M_REQ_BOILER = 2;
const M_RSP_THERMOSTAT = 3;
const msgMap = {"T": M_THERMOSTAT, "B": M_BOILER, "R": M_REQ_BOILER, "A": M_RSP_THERMOSTAT};
// Get type and validate
var type = raw.charAt(0);
if (-1 == Object.keys(msgMap).indexOf(type))
{
node.warn("Illegal message type '"+raw+"'");
return;
}
// Extract message and validate it's hex
var message = raw.slice(1);
var hexregex = /[0-9A-F]+/g;
if(! hexregex.test(message))
{
node.warn("Illegal message content '"+raw+"'");
return;
}
// Verify parity -- The parity bit should be set or cleared such the
// total number of '1' bits in the entire 32 bits of the message is even.
if (popcount(parseInt(message, 16)) % 2 != 0)
{
node.warn("Illegal message parity '"+raw+"'");
return;
}
// Extract values
msg.msgtype = (parseInt(message.slice(0,2), 16) & 0x70) >> 4;
msg.dataid = parseInt(message.slice(2,4), 16);
msg.datavalue = parseInt(message.slice(4,8), 16);
send(msg);
// Check done exists (1.0+)
if (done)
{
done();
}
});
}
RED.nodes.registerType("otgwdec",OTGWDec);
}