-
Notifications
You must be signed in to change notification settings - Fork 1
/
gpioUtil.js
137 lines (114 loc) · 4.32 KB
/
gpioUtil.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
var fs = require("fs"),
path = require("path"),
exec = require("child_process").exec;
var readallParser = require("./readallParser.js");
// name/path of Wiring Pi gpio utility, see
// http://wiringpi.com/download-and-install/
// and http://wiringpi.com/the-gpio-utility/
const gpioExe = "gpio";
// path to the virtual device
const sysFsPath = "/sys/devices/virtual/gpio";
// regular expressions for crude input validation
const validParam = {
'pin' : /^20|(1?[0-9])$/,
'mode' : /^(in|out|pwm|clock|up|down|tri)$/,
'onoff' : /^[01]$/,
'pwmVal' : /^(10(2[0-3]|[01][0-9]))|([0-9]{1,3})$/, // 0..1023, hopefully
'inout' : /^(in|out)$/,
'edge' : /^(rising|falling|both|none)$/
};
function gpioExec(command, params, callback) {
params.forEach(function(param) {
var name = param[0];
var value = param[1];
if (!validParam[name].test(value)) {
throw new Error("invalid param: " + name + "('" + value + + "')");
}
});
var execString = gpioExe + " " + command + params.reduce(function(string, param) {
return string + " " + param[1];
}, "");
exec(execString, function(err, stdout, stderr) {
if (err) {
console.error("ERROR [gpioUtil] exec failed: '" + execString + "':");
console.error(stderr);
}
(callback || function noop(){})(err, stdout, stderr);
});
}
function parseWarning(cmd) {
console.error("WARNING [gpioUtil] unexpected result from '" + cmd + "'");
}
var gpioUtil = {
version: function(callback) {
gpioExec("-v", [], function(err, stdout, stderr) {
var versionMatch = /gpio version: (.*)/.exec(stdout);
// version number is substring match -> stored in vM[1]
if (versionMatch.length !== 2) {
parseWarning("version");
}
(callback || function noop(){})(err, stdout, stderr, versionMatch[1]);
});
},
mode: function(pin, mode, callback) {
gpioExec("mode", [['pin', pin], ['mode', mode]], callback);
},
write: function(pin, onoff, callback) {
if (typeof onoff === 'boolean') onoff = onoff ? 1 : 0;
gpioExec("write", [['pin', pin], ['onoff', onoff]], callback);
},
pwm: function(pin, pwmVal, callback) {
gpioExec("pwm", [['pin', pin], ['pwmVal', pwmVal]], callback);
},
read: function(pin, callback) {
gpioExec("read", [['pin', pin]], function(err, stdout, stderr) {
var val;
if (stdout.trim() === '0') {
val = false;
} else if (stdout.trim() === '1') {
val = true;
} else {
parseWarning("read pin " + pin);
}
callback(err, stdout, stderr, val);
});
},
readall: function(callback) {
gpioExec("readall", [], function(err, stdout, stderr) {
var pins = readallParser.parse(stdout);
(callback || function noop(){})(err, stdout, stderr, pins);
});
},
export: function(pin, inout, callback) {
gpioExec("export", [['pin', pin], ['inout', inout]], callback);
},
unexport: function(pin, callback) {
gpioExec("unexport", [['pin', pin]], callback);
},
unexportall: function(callback) {
gpioExec("unexportall", [], callback);
},
exports: function(callback) {
gpioExec("exports", [], function(err, stdout, stderr) {
var lines = stdout.split('\n').slice(1, -1);
var exports = [];
const lineRegex = /([0-9]{1,2}):\s(in|out)\s+(\w)\s+(\w+)/;
lines.forEach(function(line) {
var tokens = lineRegex.exec(line);
if (tokens === null || tokens.length !== 5) {
parseWarning("exports (line: '" + line + "')");
} else {
exports.push({ 'pin': tokens[1],
'direction': tokens[2],
'value': tokens[3],
'pull': tokens[4] });
}
});
(callback || function noop(){})(err, stdout, stderr, exports);
});
},
edge: function(pin, edge, callback) {
gpioExec("edge", [['pin', pin], ['edge', edge]], callback);
}
};
module.exports = gpioUtil;