forked from fivdi/gpio-button
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbutton.js
82 lines (60 loc) · 1.83 KB
/
button.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
'use strict';
var events = require('events'),
fs = require('fs'),
glob = require('glob'),
util = require('util');
var EVENT_FILE_PREFIX = '/dev/input/by-path/platform-*',
EVENT_FILE_SUFFIX = '*-event',
EVENT_DATA_SIZE = 32,
EVENT_TYPE_INDEX = 12;
function Button(name) {
var eventFilePattern;
if (!(this instanceof Button)) {
return new Button(name);
}
this._pressed = false;
this._held = false;
eventFilePattern = EVENT_FILE_PREFIX + name + EVENT_FILE_SUFFIX;
glob(eventFilePattern, null, function (err, matches) {
var data = new Buffer(0);
if (err) {
return this.emit('error', err);
}
if (matches.length === 0) {
return this.emit('error', new Error('Event file \'' + eventFilePattern + '\' not found'));
}
if (matches.length > 1) {
return this.emit('error', new Error('Multiple event files \'' + eventFilePattern + '\' found'));
}
fs.createReadStream(matches[0]).on('data', function (buf) {
data = Buffer.concat([data, buf]);
while (data.length >= EVENT_DATA_SIZE) {
if (data[EVENT_TYPE_INDEX] === 0) {
this._pressed = false;
this._held = false;
this.emit('release');
} else if (data[EVENT_TYPE_INDEX] === 1) {
this._pressed = true;
this.emit('press');
} else if (data[EVENT_TYPE_INDEX] === 2) {
this._held = true;
this.emit('hold');
}
data = data.slice(EVENT_DATA_SIZE);
}
}.bind(this));
// TODO: handle errors from stream
this.emit('ready');
}.bind(this));
}
util.inherits(Button, events.EventEmitter);
Button.prototype.pressed = function () {
return this._pressed;
}
Button.prototype.held = function () {
return this._held;
}
Button.prototype.released = function () {
return !this.pressed();
}
module.exports = Button;