You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
377 lines
10 KiB
JavaScript
377 lines
10 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
const crypto = require('crypto'),
|
|
http = require('http'),
|
|
https = require('https'),
|
|
fs = require('fs'),
|
|
util = require('util'),
|
|
url = require('url'),
|
|
exec = require('child_process').exec,
|
|
// mdns = require('mdns'),
|
|
sqlite3 = require('sqlite3').verbose();
|
|
db = new sqlite3.Database('/var/lib/wattsapp/collector.sqlite');
|
|
|
|
function handle_list(res, query) {
|
|
result = [];
|
|
|
|
db.each('SELECT * FROM sensors', function(err, row) {
|
|
if (err) throw err;
|
|
result.push({
|
|
'id': row['id'],
|
|
'name': row['name'],
|
|
'status': row['status'] == 0 ? "inactive" : "active",
|
|
'type': row['type'],
|
|
'unit': row['unit'],
|
|
'location': row['lat']+','+row['lon']
|
|
});
|
|
},
|
|
function() {
|
|
res.writeHead(200, {'Content-Type': 'application/json'});
|
|
res.end(JSON.stringify(result));
|
|
});
|
|
}
|
|
|
|
function handle_details(res, query) {
|
|
function foreach_value_row(err, row) {
|
|
if (err) throw err;
|
|
result[row['id']]['values'].push({
|
|
'begin': row['begin'],
|
|
'end': row['end'],
|
|
'value': row['value'],
|
|
});
|
|
};
|
|
|
|
function foreach_value_complete() {
|
|
res.writeHead(200, {'Content-Type': 'application/json'});
|
|
res.end(JSON.stringify(result));
|
|
}
|
|
|
|
function foreach_sensors_row(err, row) {
|
|
if (err) throw err;
|
|
result[row['id']] = {
|
|
'name': row['name'],
|
|
'status': row['status'] == 0 ? 'inactive' : 'active',
|
|
'type': row['type'],
|
|
'unit': row['unit'],
|
|
'location': row['lat']+","+row['lon'],
|
|
'values': []
|
|
}
|
|
}
|
|
|
|
function foreach_sensors_complete() {
|
|
var values_query = "SELECT * FROM value";
|
|
var values_param = [];
|
|
var begin_time = null;
|
|
var end_time = null;
|
|
|
|
if (query['meters'] || query['time']) {
|
|
values_query += " WHERE";
|
|
}
|
|
|
|
if (query['meters']) {
|
|
var sensors = query['meters'].split(',');
|
|
values_query += " id IN (";
|
|
values_query += sensors.map(function(e) { return "?" }).join(',');
|
|
values_query += ")";
|
|
values_param = values_param.concat(sensors);
|
|
}
|
|
|
|
if (query['meters'] && query['time']) {
|
|
values_query += " AND";
|
|
}
|
|
|
|
if (query['time']) {
|
|
var time = query['time'].split(':')
|
|
time_begin = time[0];
|
|
time_end = time[1];
|
|
|
|
if (time_begin > 0 && time_end > 0) {
|
|
values_query += " begin > ? AND end < ?";
|
|
values_param = values_param.concat([time_begin, time_end]);
|
|
} else if (time_begin > 0) {
|
|
values_query += " begin > ?";
|
|
values_param = values_param.concat([time_begin]);
|
|
} else if (time_end > 0) {
|
|
values_query += " end < ?";
|
|
values_param = values_param.concat([time_end]);
|
|
}
|
|
}
|
|
|
|
db.each(values_query, values_param, foreach_value_row, foreach_value_complete);
|
|
}
|
|
|
|
result = {};
|
|
|
|
var sensors_query = "SELECT * FROM sensors";
|
|
var sensors = [];
|
|
|
|
if (query['meters']) {
|
|
var sensors = query['meters'].split(',');
|
|
sensors_query += " WHERE id IN (";
|
|
sensors_query += sensors.map(function(e) { return "?" }).join(',');
|
|
sensors_query += ")"
|
|
}
|
|
|
|
db.each(sensors_query, sensors, foreach_sensors_row, foreach_sensors_complete);
|
|
}
|
|
|
|
function handle_sum(res, query) {
|
|
function foreach_value_row(err, row) {
|
|
if (err) throw err;
|
|
result[row['id']]['values'].push({
|
|
'begin': row['begin'],
|
|
'end': row['end'],
|
|
'value': row['value'],
|
|
});
|
|
};
|
|
|
|
function foreach_value_complete() {
|
|
res.writeHead(200, {'Content-Type': 'application/json'});
|
|
res.end(JSON.stringify(result));
|
|
}
|
|
|
|
function foreach_sensors_row(err, row) {
|
|
if (err) throw err;
|
|
result[row['id']] = {
|
|
'name': row['name'],
|
|
'status': row['status'] == 0 ? 'inactive' : 'active',
|
|
'type': row['type'],
|
|
'unit': row['unit'],
|
|
'location': row['lat']+","+row['lon'],
|
|
'values': []
|
|
}
|
|
}
|
|
|
|
function foreach_sensors_complete() {
|
|
var values_query = "SELECT id, MIN(begin) AS begin, MAX(end) AS end, SUM(value) AS value FROM value";
|
|
var values_param = [];
|
|
var begin_time = null;
|
|
var end_time = null;
|
|
|
|
if (query['meters'] || query['time']) {
|
|
values_query += " WHERE";
|
|
}
|
|
|
|
if (query['meters']) {
|
|
var sensors = query['meters'].split(',');
|
|
values_query += " id IN (";
|
|
values_query += sensors.map(function(e) { return "?" }).join(',');
|
|
values_query += ")";
|
|
values_param = values_param.concat(sensors);
|
|
}
|
|
|
|
if (query['meters'] && query['time']) {
|
|
values_query += " AND";
|
|
}
|
|
|
|
if (query['time']) {
|
|
var time = query['time'].split(':')
|
|
time_begin = time[0];
|
|
time_end = time[1];
|
|
|
|
if (time_begin > 0 && time_end > 0) {
|
|
values_query += " begin > ? AND end < ?";
|
|
values_param = values_param.concat([time_begin, time_end]);
|
|
} else if (time_begin > 0) {
|
|
values_query += " begin > ?";
|
|
values_param = values_param.concat([time_begin]);
|
|
} else if (time_end > 0) {
|
|
values_query += " end < ?";
|
|
values_param = values_param.concat([time_end]);
|
|
}
|
|
}
|
|
|
|
values_query += " GROUP BY id";
|
|
|
|
db.each(values_query, values_param, foreach_value_row, foreach_value_complete);
|
|
}
|
|
|
|
result = {};
|
|
|
|
var sensors_query = "SELECT * FROM sensors";
|
|
var sensors = [];
|
|
|
|
if (query['meters']) {
|
|
var sensors = query['meters'].split(',');
|
|
sensors_query += " WHERE id IN (";
|
|
sensors_query += sensors.map(function(e) { return "?" }).join(',');
|
|
sensors_query += ")"
|
|
}
|
|
|
|
db.each(sensors_query, sensors, foreach_sensors_row, foreach_sensors_complete);
|
|
}
|
|
|
|
function handle_blacklist(res, query) {
|
|
var blacklist_query = "UPDATE sensors SET status=0 WHERE id=?";
|
|
|
|
if (!query['sensor']) {
|
|
res.writeHead(200, {'Content-Type': 'application/json'});
|
|
res.end(JSON.stringify([]));
|
|
return;
|
|
}
|
|
|
|
db.run(blacklist_query, query['sensor'], function(err) {
|
|
if (err) throw err;
|
|
|
|
var result_query = "SELECT * FROM sensors WHERE id=?";
|
|
|
|
db.get(result_query, query['sensor'], function(err, row) {
|
|
res.writeHead(200, {'Content-Type': 'application/json'});
|
|
res.end(JSON.stringify(row));
|
|
});
|
|
});
|
|
}
|
|
|
|
function handle_unblacklist(res, query) {
|
|
var blacklist_query = "UPDATE sensors SET status=1 WHERE id=?";
|
|
|
|
if (!query['sensor']) {
|
|
res.writeHead(200, {'Content-Type': 'application/json'});
|
|
res.end(JSON.stringify([]));
|
|
return;
|
|
}
|
|
|
|
db.run(blacklist_query, query['sensor'], function(err) {
|
|
if (err) throw err;
|
|
|
|
var result_query = "SELECT * FROM sensors WHERE id=?";
|
|
|
|
db.get(result_query, query['sensor'], function(err, row) {
|
|
res.writeHead(200, {'Content-Type': 'application/json'});
|
|
res.end(JSON.stringify(row));
|
|
});
|
|
});
|
|
}
|
|
|
|
function handle_rename(res, query) {
|
|
var rename_query = "UPDATE sensors SET name=? WHERE id=?";
|
|
|
|
if (!query['sensor'] || !query['name']) {
|
|
res.writeHead(200, {'Content-Type': 'application/json'});
|
|
res.end(JSON.stringify([]));
|
|
return;
|
|
}
|
|
|
|
db.run(rename_query, query['name'], query['sensor'], function(err) {
|
|
if (err) throw err;
|
|
|
|
var result_query = "SELECT * FROM sensors WHERE id=?";
|
|
|
|
db.get(result_query, query['sensor'], function(err, row) {
|
|
res.writeHead(200, {'Content-Type': 'application/json'});
|
|
res.end(JSON.stringify(row));
|
|
});
|
|
});
|
|
}
|
|
|
|
function handle_relocate(res, query) {
|
|
var rename_query = "UPDATE sensors SET lat=?, lon=? WHERE id=?";
|
|
|
|
if (!query['sensor'] || !query['location']) {
|
|
res.writeHead(200, {'Content-Type': 'application/json'});
|
|
res.end(JSON.stringify([]));
|
|
return;
|
|
}
|
|
|
|
var loc = query['location'].split(',');
|
|
|
|
if (!loc[0] || !loc[1]) {
|
|
res.writeHead(200, {'Content-Type': 'application/json'});
|
|
res.end(JSON.stringify([]));
|
|
return;
|
|
}
|
|
|
|
db.run(rename_query, loc[0], loc[1], query['sensor'], function(err) {
|
|
if (err) throw err;
|
|
|
|
var result_query = "SELECT * FROM sensors WHERE id=?";
|
|
|
|
db.get(result_query, query['sensor'], function(err, row) {
|
|
res.writeHead(200, {'Content-Type': 'application/json'});
|
|
res.end(JSON.stringify(row));
|
|
});
|
|
});
|
|
}
|
|
|
|
function request_handler(req, res) {
|
|
if (!req.connection.authorized) {
|
|
res.writeHead(403, {'Content-Type': 'text/plain'});
|
|
res.end("invalid ssl client certificate");
|
|
return;
|
|
}
|
|
|
|
parsed = url.parse(req.url, true);
|
|
|
|
methods = {
|
|
'/list': handle_list,
|
|
'/details': handle_details,
|
|
'/sum': handle_sum,
|
|
'/blacklist': handle_blacklist,
|
|
'/unblacklist': handle_unblacklist,
|
|
'/rename': handle_rename,
|
|
'/relocate': handle_relocate
|
|
}
|
|
|
|
console.log(req.url);
|
|
|
|
if (parsed['pathname'] in methods) {
|
|
methods[parsed['pathname']](res, parsed['query'])
|
|
} else {
|
|
res.writeHead(501, {'Content-Type': 'application/json'});
|
|
res.end("")
|
|
}
|
|
};
|
|
|
|
/*
|
|
function poll_sensors() {
|
|
fs.readFile('sensors.json', 'utf8', function (err, data) {
|
|
data = JSON.parse(data);
|
|
|
|
for (hosts in data) {
|
|
var options = {
|
|
host: hosts['host'],
|
|
port: hosts['port'],
|
|
path: '/details',
|
|
method: 'GET'
|
|
}
|
|
|
|
var request = http.request(options);
|
|
|
|
request.on('response', function (res) {
|
|
console.log("success");
|
|
});
|
|
|
|
request.on('error', function(e) {
|
|
console.log(e.message);
|
|
});
|
|
|
|
request.end();
|
|
}
|
|
});
|
|
}
|
|
|
|
setInterval(poll_sensors, 1000*3600); // once per hour
|
|
*/
|
|
|
|
/*
|
|
mdns.createAdvertisement('https', 8443).start();
|
|
*/
|
|
|
|
/*
|
|
child = exec("avahi-publish-service collector _https._tcp 8443 \"ns=wattsapp;ip=2001:638:709:5::5\"", function(error, stdout, stderr) {});
|
|
*/
|
|
|
|
var options = {
|
|
key: fs.readFileSync('/var/lib/wattsapp/collector.key'),
|
|
cert: fs.readFileSync('/var/lib/wattsapp/collector.crt'),
|
|
ca: fs.readdirSync('/var/lib/wattsapp/collector_clients').map(function(x) {
|
|
return fs.readFileSync('/var/lib/wattsapp/collector_clients/'+x);
|
|
}),
|
|
requestCert: true,
|
|
// rejectUnauthorized: true
|
|
};
|
|
|
|
var server = https.createServer(options);
|
|
server.addListener("request", request_handler);
|
|
server.listen(8443);
|