-
Notifications
You must be signed in to change notification settings - Fork 1
/
app.js
193 lines (161 loc) · 5.32 KB
/
app.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// Include node modules
var fs = require('fs');
var request = require('request');
var gpio = require('pi-gpio');
var sleep = require('sleep');
var pyShell = require('python-shell');
var express = require('express');
var exec = require('child_process').exec;
var spawn = require('child_process').spawn;
var bodyParser = require('body-parser');
var processQueue = [];
var processCount = 0;
// Global vaiables
var app = express();
var router = express.Router();
var webHookMapping = {};
var PI_DEVICE_ID;
var PI_PORT;
function makeResponse(message, data, status) {
data = data || [];
status = status || 'ok';
return {
data: data,
message: message,
status: status
};
}
function registerAPIServer(serverConfig) {
var url = 'http://' + serverConfig.host + ':' + serverConfig.port + serverConfig.endpoint;
var piInfo = {
device_id: PI_DEVICE_ID,
device_type: 'pi',
port: PI_PORT
};
var options = {
url: url,
json: piInfo
};
console.log('Register ourselves to APIServer@%s:%d', serverConfig.host, serverConfig.port);
request.post(
options,
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log('Registered successfully');
} else {
console.log('Error occured %s: %s', response.statusCode, body.message ? body.message : '');
}
}
);
}
var getRangeSensorData = function(req, res) {
var id = processCount;
processCount++;
processQueue.push(id);
while(processQueue[0] != id){}
console.log('Read range sensor data');
pyShell.run('measure.py', function (err, results) {
if (err) throw err;
var result = {
distanceCm: parseFloat(results[0]),
distanceInches: parseFloat(results[0]) * 0.393701,
};
processQueue.shift();
res.json(makeResponse('Success', result));
});
};
var setupMotionHook = function(req, res) {
var address = String(req.body.address);
var child;
console.log('Adding new motion hook (' + address + ')');
if (!webHookMapping.hasOwnProperty(address)) {
child = spawn('sudo', ['python', 'python/waitForMotion.py', address], { detached: true });
console.log('Script started successfully!');
webHookMapping[address] = child.pid;
res.json(makeResponse('Registered', {'address': address}));
}
else{
console.log('Ignored duplicate request');
res.status(400).json(makeResponse('Hook already set', {'address': address}, 'error'));
}
};
var removeMotionHook = function(req, res) {
var address = String(req.body.address);
if (webHookMapping.hasOwnProperty(address)) {
console.log('Killing motion hook for ' + address);
exec('sudo kill ' + webHookMapping[address], function (error, stdout, stderr){
delete webHookMapping[address];
console.log('Killed motion hook ' + address);
res.json(makeResponse('Deleted', {'address': address}));
});
} else {
console.log('Hook to delete not found:' + address);
res.status(400).json(makeResponse('Hook not registered', {'address': address}, 'error'));
}
};
var getGPIOValue = function(req, res) {
var pinNumber = parseInt(req.params.gpioNumber);
var pinPath = '/sys/devices/virtual/gpio/gpio' + pinNumber + '/value';
var value = parseInt(fs.readFileSync(pinPath, {encoding: 'utf8'}).charAt(0));
console.log('Read GPIO%d: %d', pinNumber, value);
res.json(makeResponse('Success', {'value': value}));
};
var setGPIOValue = function(req, res) {
var pinNumber = parseInt(req.params.gpioNumber);
var value = parseInt(req.body.value);
var pinPath = '/sys/devices/virtual/gpio/gpio' + pinNumber + '/value';
console.log('Set GPIO%d to %d', pinNumber, value);
gpio.write(pinNumber, value, function(err){
if (err) {
res.status(500).json(makeResponse(err.message, [], 'error'));
} else {
res.json(makeResponse('Success', {'value': value}));
}
});
};
var toggleIOPin = function(req, res) {
var pinNumber = parseInt(req.params.gpioNumber);
var pinPath = '/sys/devices/virtual/gpio/gpio' + pinNumber + '/value';
var status = fs.readFileSync(pinPath, {encoding: 'utf8'}).charAt(0);
var value = status === '0' ? 1 : 0;
console.log('Set GPIO%d to %d', pinNumber, value);
gpio.write(pinNumber, 0, function(err){
if (err) {
res.status(500).json(makeResponse(err.message, [], 'error'));
} else {
res.json(makeResponse('Success', {'value': value}));
}
});
};
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// simple logger for this router's requests
router.use(function(req, res, next) {
console.log('------\n%s %s from %s', req.method, req.url, req.hostname);
next();
});
// Routes
router.route('/motionHook')
.post(setupMotionHook)
.delete(removeMotionHook);
router.route('/rangeSensor')
.get(getRangeSensorData);
router.route('/gpio/:gpioNumber')
.get(getGPIOValue)
.post(setGPIOValue);
router.route('/gpio/:gpioNumber/toggle')
.get(toggleIOPin);
app.all('*', router);
// load api server config file
fs.readFile('pi.config', 'utf8', function (err, data) {
if (err) {
return console.log(err);
}
var config = JSON.parse(data);
PI_PORT = config.port || 8080;
PI_DEVICE_ID = config.deviceIDSeed;
registerAPIServer(config.apiServer);
// Start the server
app.listen(PI_PORT);
console.log('Pi Server up and running on port %d', PI_PORT);
});