-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
156 lines (136 loc) · 3.44 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
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
144
145
146
147
148
149
150
151
152
153
154
155
156
var gpio = require('rpi-gpio');
var types = {};
types.switch = function(node, value, initial, config) {
node.publish(undefined, value);
};
types.press = function(node, value, initial, config) {
var delta_min = 5;
var delta_max = 800;
if (typeof config.delta_min === "number") delta_min = config.delta_min;
if (typeof config.delta_max === "number") delta_max = config.delta_max;
if (initial) {
return;
}
// calculate delta to last event:
var delta = new Date()*1 - node.state_time;
console.log("delta", delta, node.value, value);
// remove spices:
//if (delta < min_spice) return;
// debouncing:
// state == on
if (node.state === 1) {
// (off->on) delta < delta_min => ignore
if (delta < delta_min)
return;
// ignore raising edge, as already in state on:
if (value) return;
// set state on falling edge:
node.state = 0;
node.state_time = new Date()*1;
// state == off
} else {
// (on->off) delta < delta_min => ignore
if (delta < delta_min)
return;
// ignore falling edge, as already in state off:
if (!value) return;
// set state on raising edge.
node.state = 1;
node.state_time = new Date()*1;
}
if (node.state === 0 && delta <= delta_max) {
// todo: toggle:
var v = 1;
if (node.value) v = 0;
console.log("pressed", v);
node.publish(undefined, v);
}
};
types.longpress_time = function(node, value, initial, config) {
types.press(node, value, initial, {
delta_min: 800
});
};
types.longpress = function(node, value, initial, config) {
var delta_min = 1000;
if (typeof config.delta_min === "number") delta_min = config.delta_min;
if (initial) {
return;
}
if (node.longpress_t) {
clearTimeout(node.longpress_t);
node.longpress_t = null;
}
// raising edge:
if (value) {
node.longpress_t = setTimeout(function() {
node.longpress_t = null;
var v = 1;
if (node.value) v = 0;
console.log("long pressed", v);
node.publish(undefined, v);
}, delta_min);
}
// falling edge:
else {
}
};
exports.init = function(node, app_config, main, host_info) {
var _this = this;
var pin = 7;
if (typeof app_config.pin === "number")
pin = app_config.pin;
var action = [{type: 'switch'}];
if (typeof app_config.action === "string") {
action = [ {type: app_config.action} ];
}
if (Array.isArray(app_config.action)) {
action = app_config.action;
}
if (!Array.isArray(action)) {
throw new Error("action is not array.");
}
var invert = !!app_config.invert;
node.announce([{
"type": "gpio.input.app",
}, app_config.metadata]);
var map = node.map(app_config, null, false, function(c) {
return c.type;
}, function(n, metadata, c) {
n.announce({
"type": c.type + ".input"
}, metadata);
});
// todo: map:
var set = function(value, initial) {
node.publish(undefined, value);
types.forEach(function(a) {
if (typeof types[a] !== "function")
throw new Error("type not found: " + a.type);
var cb = types[a].bind(_this);
let n = map.node(a);
if (n) {
cb(n, value ^ invert, initial, n._config);
}
});
};
gpio.on('change', function(channel, value) {
if (channel == pin) {
set(value, false);
}
});
gpio.setup(pin, gpio.DIR_IN, gpio.EDGE_BOTH, function(error) {
if (error)
return console.warn("Setup Error: ", error);
gpio.read(pin, function(error, value) {
if (error)
return console.warn("Read Error: ", error);
set(value, true);
});
});
return [node, function() {
gpio.destroy(function(err) {
if (err) console.error(err);
});
}];
};