-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsequence-detector.js
106 lines (98 loc) · 3.93 KB
/
sequence-detector.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
module.exports = function(RED) {
function SequenceDetector(config) {
RED.nodes.createNode(this,config);
if(config.sequence){
this.sequence = config.sequence.split("\n");
}else{
this.sequence = [];
}
this.watch = config.watch != undefined ? config.watch : "payload" ;
this.timeout = config.timeout != undefined ? config.timeout : 2000 ;
this.matchMessage = config.matchMessage != undefined ? config.matchMessage : "match" ;
this.resetMessage = config.resetMessage != undefined ? config.resetMessage : "reset" ;
this.timeoutMessage = config.timeoutMessage != undefined ? config.timeoutMessage : "timeout" ;
this.indexCheck = 0;
var node = this;
setStatus(node,"grey");
node.on('input', function(msg, send, done) {
try{
if(node.timeoutHandle){
clearTimeout(node.timeoutHandle);
}
send = send || function() { node.send.apply(node,arguments) } //For backwards compatibility with node-red 0.x
var messageMatchesCurrentIndex = messageMatches(node.watch, msg, node.sequence[node.indexCheck]);
var isLastIndex = node.indexCheck == node.sequence.length - 1;
if(messageMatchesCurrentIndex){
if(isLastIndex){
node.indexCheck = 0;
node.lastMatch = new Date();
msg.payload = node.matchMessage;
setStatus(node,"green");
send([msg, null]);
}else{
node.indexCheck = node.indexCheck+1;
setStatus(node,"blue");
node.timeoutHandle = setTimeout(function(){
node.indexCheck = 0;
msg.payload = node.timeoutMessage;
setStatus(node,"yellow");
send([null, msg]);
}, node.timeout)
//swallows message
}
}else{
if(node.indexCheck != 0){
node.indexCheck = 0;
msg.payload = node.resetMessage;
setStatus(node,"yellow");
send([null, msg]);
}
//otherwise swallow message
}
if (node.done) {
node.done();
}
}catch(err){
if(done){
node.done(err);
}
else
node.error(err, msg)
}
});
}
function setStatus(node,fill){
node.status({fill:fill,shape:"dot",text: getStatusString(node)});
}
function getStatusString(node){
if(node.sequence){
text = "Match:" +node.indexCheck + "/" + node.sequence.length;
if(node.lastMatch){
text = text + " Last Match: " + getPrettyDate(node.lastMatch);
}
return text;
}
else
return "No sequence set";
}
function getPrettyDate(date) {
return date.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
hour12: false,
hour: 'numeric',
minute: 'numeric'
});
}
function messageMatches(watch, msg, matchValue){
var payloadMatchesCurrentIndex = (msg.payload == matchValue)
var topicMatchesCurrentIndex = (msg.topic == matchValue)
if(watch == "payload")
return payloadMatchesCurrentIndex;
else if(watch == "topic")
return topicMatchesCurrentIndex;
else
return payloadMatchesCurrentIndex || topicMatchesCurrentIndex;
}
RED.nodes.registerType("sequence-detector",SequenceDetector);
}