aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2015-10-31 12:04:28 +0100
committerTrygve Laugstøl <trygvis@inamo.no>2015-10-31 12:04:28 +0100
commit02d6e77bd180cbbf6f7f6e1a69c670e922d8204d (patch)
treec55847b71e589f79ce6537f2b61f3691fe8bf220 /src
parentdd72e7992f126c4a42a0791228400738072f297d (diff)
downloaddiller-server-02d6e77bd180cbbf6f7f6e1a69c670e922d8204d.tar.gz
diller-server-02d6e77bd180cbbf6f7f6e1a69c670e922d8204d.tar.bz2
diller-server-02d6e77bd180cbbf6f7f6e1a69c670e922d8204d.tar.xz
diller-server-02d6e77bd180cbbf6f7f6e1a69c670e922d8204d.zip
web:
o Starting on edit button for device name.
Diffstat (limited to 'src')
-rw-r--r--src/Diller.js23
-rw-r--r--src/DillerDao.js33
-rw-r--r--src/web/DillerWeb.js76
3 files changed, 115 insertions, 17 deletions
diff --git a/src/Diller.js b/src/Diller.js
index e73bf46..d52e3f1 100644
--- a/src/Diller.js
+++ b/src/Diller.js
@@ -1,5 +1,11 @@
var di = require('di');
+/**
+ * @param config DillerConfig
+ * @param db DillerDb
+ * @returns {{onMessage: onMessage, updateDeviceName: updateDeviceName}}
+ * @constructor
+ */
function Diller(config, db) {
var log = config.log();
@@ -51,6 +57,20 @@ function Diller(config, db) {
});
}
+ function updateDeviceName(deviceId, name) {
+ log.info('Updating device name', {deviceId: deviceId, name: name});
+ return db()
+ .tx(function (tx) {
+ var dao = new DillerDao(tx);
+
+ return dao.updateDevice(deviceId, {name: name})
+ .then(function (res) {
+ log.info('Device name updated', {deviceId: deviceId, name: name});
+ return res;
+ });
+ })
+ }
+
function onMessage(topic, message, payload) {
var parts = topic.split(/\//);
@@ -118,7 +138,8 @@ function Diller(config, db) {
}
return {
- onMessage: onMessage
+ onMessage: onMessage,
+ updateDeviceName: updateDeviceName
}
}
diff --git a/src/DillerDao.js b/src/DillerDao.js
index cae80d7..2133dfc 100644
--- a/src/DillerDao.js
+++ b/src/DillerDao.js
@@ -1,3 +1,5 @@
+var _ = require('lodash');
+
function DillerDao(tx) {
var deviceColumns = 'id, key, created_timestamp';
@@ -24,6 +26,30 @@ function DillerDao(tx) {
return tx.one("INSERT INTO device(id, key, created_timestamp) VALUES(DEFAULT, $1, CURRENT_TIMESTAMP) RETURNING " + deviceColumns, key);
}
+ function updateDevice(id, attributes) {
+
+ var values = [id];
+ var i = 2;
+ var fields = _.map(attributes, function (value, name) {
+ console.log('name', name, 'value', value, 'i', i);
+ if (name == 'name') {
+ values.push(value);
+ return 'name = $' + i++;
+ }
+ });
+
+ if (fields.length == 0) {
+ return; // TODO: return an empty promise;
+ }
+
+ fields = _.collect(fields);
+
+ var x = 'UPDATE device SET ' + fields.join(', ') + ' WHERE id = $1';
+ console.log('x', x);
+ console.log('values', values);
+ return tx.none(x, values);
+ }
+
// -------------------------------------------------------------------------------------------------------------------
// Device Property
// -------------------------------------------------------------------------------------------------------------------
@@ -70,10 +96,10 @@ function DillerDao(tx) {
function updateHourAggregatesForProperty(propertyId, timestamp) {
return tx.none('DELETE FROM value_by_hour WHERE property=$1 AND timestamp=DATE_TRUNC(\'hour\', $2::TIMESTAMPTZ)', [propertyId, timestamp])
- .then(function() {
+ .then(function () {
return tx.oneOrNone('INSERT INTO value_by_hour(property, timestamp, count, max, min, avg) ' +
'SELECT property, DATE_TRUNC(\'hour\', timestamp) AS timestamp, COUNT(value_numeric) AS count, MAX(value_numeric) AS max, MIN(value_numeric) AS min, AVG(value_numeric) AS avg ' +
- 'FROM value WHERE property=$1 AND DATE_TRUNC(\'hour\', timestamp)=DATE_TRUNC(\'hour\', $2::TIMESTAMPTZ) AND value_numeric IS NOT NULL ' +
+ 'FROM value WHERE property=$1 AND DATE_TRUNC(\'hour\', timestamp)=DATE_TRUNC(\'hour\', $2::TIMESTAMPTZ) AND value_numeric IS NOT NULL ' +
'GROUP BY property, DATE_TRUNC(\'hour\', timestamp) ' +
'RETURNING *;', [propertyId, timestamp]);
});
@@ -81,7 +107,7 @@ function DillerDao(tx) {
function updateMinuteAggregatesForProperty(propertyId, timestamp) {
return tx.none('DELETE FROM value_by_minute WHERE property=$1 AND timestamp=DATE_TRUNC(\'minute\', $2::TIMESTAMPTZ)', [propertyId, timestamp])
- .then(function() {
+ .then(function () {
return tx.oneOrNone('INSERT INTO value_by_minute(property, timestamp, count, max, min, avg) ' +
'SELECT property, DATE_TRUNC(\'minute\', timestamp) AS timestamp, COUNT(value_numeric) AS count, MAX(value_numeric) AS max, MIN(value_numeric) AS min, AVG(value_numeric) AS avg ' +
'FROM value ' +
@@ -96,6 +122,7 @@ function DillerDao(tx) {
deviceById: deviceById,
deviceByKey: deviceByKey,
insertDevice: insertDevice,
+ updateDevice: updateDevice,
devicePropertyById: devicePropertyById,
devicePropertyByDeviceIdAndKey: devicePropertyByDeviceIdAndKey,
diff --git a/src/web/DillerWeb.js b/src/web/DillerWeb.js
index c261af7..95bcbb6 100644
--- a/src/web/DillerWeb.js
+++ b/src/web/DillerWeb.js
@@ -14,16 +14,26 @@ function DillerWeb(diller, db, config) {
var calls = [];
var app;
+ function genericErrorHandler(res) {
+ return function (data) {
+ log.warn('fail', data);
+ return res.status(500).json({message: 'fail', data: data})
+ }
+ }
+
function getDevices(req, res) {
db().tx(function (pg) {
var dao = new DillerDao(pg);
return dao.devices();
}).then(function (devices) {
res.json({devices: devices});
- }, function (err) {
- log.warn('fail', err);
- res.status(500).json({message: 'fail'});
- });
+ }, genericErrorHandler(res));
+ }
+
+ function deviceResponse(data) {
+ var device = data[0];
+ device.properties = data[1];
+ return {device: device};
}
function getDevice(req, res) {
@@ -36,13 +46,36 @@ function DillerWeb(diller, db, config) {
dao.devicePropertiesByDeviceId(deviceId)]
);
}).then(function (data) {
+ res.json(deviceResponse(data));
+ }, genericErrorHandler(res));
+ }
+
+ function patchDevice(req, res) {
+ db().tx(function (tx) {
+ var deviceId = req.params.deviceId;
+
+ var body = req.body;
+
+ if (body.attribute == 'name') {
+ diller.updateDeviceName(deviceId, body.value)
+ .then(function () {
+ var dao = new DillerDao(tx);
+ return tx.batch([
+ dao.deviceById(deviceId),
+ dao.devicePropertiesByDeviceId(deviceId)]
+ );
+ })
+ .then(function (data) {
+ res.json(deviceResponse(data));
+ }, genericErrorHandler(res));
+ } else {
+ res.status(400).json({message: 'Required keys: "attribute" and "value".'});
+ }
+ }).then(function (data) {
var device = data[0];
device.properties = data[1];
res.json({device: device});
- }, function (err) {
- log.warn('fail', err);
- res.status(500).json({message: 'fail'});
- });
+ }, genericErrorHandler(res));
}
function getValues(req, res) {
@@ -76,19 +109,34 @@ function DillerWeb(diller, db, config) {
api[method](path, callback);
var layer = _.last(api.stack);
+ var methodWithPayloads = {
+ put: true,
+ post: true,
+ patch: true
+ };
+
+ var keys = _.map(layer.keys, function (key) {
+ return key.name;
+ });
+
+ var hasPayload = methodWithPayloads[method];
+ if (hasPayload) {
+ keys.push('payload');
+ }
+
calls.push({
name: name,
method: method,
path: path,
layer: layer,
- keys: _.map(layer.keys, function (key) {
- return key.name;
- })
+ hasPayload: hasPayload,
+ keys: keys
});
}
addApi('getDevices', 'get', '/device', getDevices);
addApi('getDevice', 'get', '/device/:deviceId', getDevice);
+ addApi('patchDevice', 'patch', '/device/:deviceId', patchDevice);
addApi('getValues', 'get', '/property/:propertyId/values', getValues);
var templates = express.Router();
@@ -116,8 +164,6 @@ function DillerWeb(diller, db, config) {
s += _.map(calls, function (call) {
- //console.error(call);
- //console.error('call.layer', call.layer);
var s = ' function ' + call.name + '(' + call.keys.join(', ') + ') {\n' +
' var req = {};\n' +
' req.method = \'' + call.method + '\';\n' +
@@ -127,6 +173,10 @@ function DillerWeb(diller, db, config) {
return ' req.url = req.url.replace(/:' + key.name + '/, ' + key.name + ');\n'
}).join('\n');
+ if (call.hasPayload) {
+ s += ' req.data = payload;\n';
+ }
+
s +=
' return $http(req);\n' +
' }\n';