-
Notifications
You must be signed in to change notification settings - Fork 7
/
app.js
129 lines (101 loc) · 3.5 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
// libraries
var mongoose = require('mongoose')
, express = require('express')
, app = express()
, server = require('http').createServer(app)
, request = require('request')
, debug = require('debug')('lelylan')
, Device = require('./app/models/devices/device');
var mqtt = require('mqtt');
var host = process.env.MOSCA_HOST
, port = '1883';
var ascoltatori = require('ascoltatori')
, ascoltatore;
var settings = {
type: 'redis',
redis: require('redis'),
db: 12,
port: 6379,
return_buffers: true,
host: process.env.REDIS_HOST
};
// ---------------
// Express Server
// ---------------
app.configure(function() {
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/app/assets'))
});
server.listen(process.env.PORT, function() {
debug('Nodes server listening on port', process.env.PORT);
});
// ---------------
// Live page test
// ---------------
app.get('/', function(req, res) {
res.sendfile(__dirname + '/index.html')
});
// -------------------------------------------
// From Lelylan to the Physical Device (/GET)
// -------------------------------------------
app.put('/mqtt/devices/:id', function(req, res) {
var status = 401;
debug('Receiving request', req.body);
Device.findOne({ _id: req.params.id, secret: req.get('X-Physical-Secret') }, function (err, doc) {
if (err) console.log(err.message);
if (doc) {
status = 202;
publish(req, '/get/')
// BAD HACK
//var client = mqtt.createClient(port, host, { username: req.params.id, password: req.get('X-Physical-Secret') });
//client.on('connect', function() {
//client.publish('devices/' + req.params.id + '/get', JSON.stringify(req.body));
//client.end();
//})
};
res.status(status).json({status:status});
});
});
var publish = function(req, mode) {
// Needed to work with Redis (and Mosca default settings)
// * Hex transformation for the JSON body
// * Binary definition for Redis to understand the stored format type
payload = { message: new Buffer(JSON.stringify(req.body)).toString('hex'), binary: true };
var topic = 'devices/' + req.params.id + mode;
ascoltatore.publish(topic, payload, function() {
console.log('[API REQ] Message published to the topic', topic, payload);
});
}
// -------------------------------------------
// From the Physical Device to Lelylan (/SET)
// -------------------------------------------
ascoltatori.build(settings, function (_ascoltatore) {
ascoltatore = _ascoltatore;
ascoltatore.subscribe('devices/*', function() {
debug('TOPIC', arguments['0'], 'PAYLOAD', arguments['1']);
var data = arguments['0'].split('/');
if (data[2] == 'set')
syncLelylan(data[1], arguments['1']);
});
});
var syncLelylan = function(id, payload) {
var uri = process.env.LELYLAN_API_URL + '/devices/' + id + '/properties';
var json = JSON.parse(new Buffer(payload.message, 'hex').toString('utf8')); // needed with Redis
var options = { uri: uri, method: 'PUT', body: json, json: true };
Device.findOne({ _id: id }, function (err, doc) {
if (err) console.log('ERROR', err.message);
if (doc) {
options.headers = setHeaders(doc.secret);
request(options, function(err, response, body) {
if (err) console.log('ERROR', err.message);
debug('Sent request to', uri, json)
});
}
});
}
var setHeaders = function(secret) {
return { 'X-Physical-Secret': secret, 'Content-Type': 'application/json' }
}
module.exports = app;