aboutsummaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2016-03-05 16:47:32 +0100
committerTrygve Laugstøl <trygvis@inamo.no>2016-03-05 16:47:32 +0100
commit7ca173de3de046501d79164da0c8c8871a03089b (patch)
tree16d857cf2ab7fd8b7b3c29efbacd6b01c2eacec7 /web
parentdda9ef2ae7971bceaa792e328c8489cb0695b77e (diff)
downloaddiller-server-7ca173de3de046501d79164da0c8c8871a03089b.tar.gz
diller-server-7ca173de3de046501d79164da0c8c8871a03089b.tar.bz2
diller-server-7ca173de3de046501d79164da0c8c8871a03089b.tar.xz
diller-server-7ca173de3de046501d79164da0c8c8871a03089b.zip
web:
o Adding an API method to get per-hour aggregate values. Doesn't use the by_hour table yet. o Adding a simple line graph component that can graph a single property's value.
Diffstat (limited to 'web')
-rw-r--r--web/static/app/DillerRpc.js40
-rw-r--r--web/static/app/diller/client.js72
-rw-r--r--web/static/app/diller/global.js60
-rw-r--r--web/static/app/diller/line-chart.js62
-rw-r--r--web/static/app/diller/web.js (renamed from web/static/app/app.js)63
-rw-r--r--web/static/app/templates/property.html30
-rw-r--r--web/templates/index.jade9
-rw-r--r--web/templates/wat.html2
8 files changed, 315 insertions, 23 deletions
diff --git a/web/static/app/DillerRpc.js b/web/static/app/DillerRpc.js
index f865dc5..eddbbf9 100644
--- a/web/static/app/DillerRpc.js
+++ b/web/static/app/DillerRpc.js
@@ -1,52 +1,82 @@
function DillerRpc($http, DillerConfig) {
var baseUrl = DillerConfig.baseUrl;
- function getDevices() {
+ function getDevicesReq() {
var req = {};
req.method = 'get';
req.url = baseUrl + '/api/device';
+ return req;
+ }
+
+ function getDevices() {
+ var req = getDevicesReq();
return $http(req);
}
- function getDevice(deviceId) {
+ function getDeviceReq(deviceId) {
var req = {};
req.method = 'get';
req.url = baseUrl + '/api/device/:deviceId';
req.url = req.url.replace(/:deviceId/, deviceId);
+ return req;
+ }
+
+ function getDevice(deviceId) {
+ var req = getDeviceReq(deviceId);
return $http(req);
}
- function patchDevice(deviceId, payload) {
+ function patchDeviceReq(deviceId, payload) {
var req = {};
req.method = 'patch';
req.url = baseUrl + '/api/device/:deviceId';
req.url = req.url.replace(/:deviceId/, deviceId);
req.data = payload;
+ return req;
+ }
+
+ function patchDevice(deviceId, payload) {
+ var req = patchDeviceReq(deviceId, payload);
return $http(req);
}
- function getValues(propertyId) {
+ function getValuesReq(propertyId) {
var req = {};
req.method = 'get';
req.url = baseUrl + '/api/property/:propertyId/values';
req.url = req.url.replace(/:propertyId/, propertyId);
+ return req;
+ }
+
+ function getValues(propertyId) {
+ var req = getValuesReq(propertyId);
return $http(req);
}
- function patchProperty(propertyId, payload) {
+ function patchPropertyReq(propertyId, payload) {
var req = {};
req.method = 'patch';
req.url = baseUrl + '/api/property/:propertyId/values';
req.url = req.url.replace(/:propertyId/, propertyId);
req.data = payload;
+ return req;
+ }
+
+ function patchProperty(propertyId, payload) {
+ var req = patchPropertyReq(propertyId, payload);
return $http(req);
}
return {
+ getDevicesReq: getDevicesReq,
getDevices: getDevices,
+ getDeviceReq: getDeviceReq,
getDevice: getDevice,
+ patchDeviceReq: patchDeviceReq,
patchDevice: patchDevice,
+ getValuesReq: getValuesReq,
getValues: getValues,
+ patchPropertyReq: patchPropertyReq,
patchProperty: patchProperty
};
}
diff --git a/web/static/app/diller/client.js b/web/static/app/diller/client.js
new file mode 100644
index 0000000..6641ffb
--- /dev/null
+++ b/web/static/app/diller/client.js
@@ -0,0 +1,72 @@
+(function () {
+ function extractData(res) {
+ return res && res.data;
+ }
+
+ function Property($http, DillerRpc, propertyId) {
+ function getInterval(interval) {
+
+ // moment().subtract(24, 'hour')
+ var req = DillerRpc.getValuesReq(propertyId);
+ req.params = {
+ from: interval.getFrom().toISOString()
+ };
+ return $http(req).then(extractData);
+ }
+
+ /** @lends Property.prototype */
+ return {
+ getInterval: getInterval
+ };
+ }
+
+ function Device($http, DillerRpc, deviceId) {
+ var properties = {};
+
+ /**
+ * @param propertyId
+ * @returns {Property}
+ */
+ function getProperty(propertyId) {
+ var p = properties[propertyId];
+
+ if (!p) {
+ p = new Property($http, DillerRpc, propertyId);
+ properties[propertyId] = p;
+ }
+
+ return p;
+ }
+
+ /** @lends Device.prototype */
+ return {
+ getProperty: getProperty
+ };
+ }
+
+ function DillerClient($timeout, $http, DillerRpc) {
+
+ var devices = {};
+
+ function getDevice(deviceId) {
+ var d = devices[deviceId];
+
+ if (!d) {
+ d = new Device($http, DillerRpc, deviceId);
+ devices[deviceId] = d;
+ }
+
+ return d;
+ }
+
+ /** @lends DillerClient.prototype */
+ return {
+ getDevice: getDevice
+ };
+ }
+
+ angular
+ .module('diller.client', [])
+ .service('DillerClient', DillerClient)
+ .service('DillerRpc', window.DillerRpc);
+})();
diff --git a/web/static/app/diller/global.js b/web/static/app/diller/global.js
new file mode 100644
index 0000000..0da8da7
--- /dev/null
+++ b/web/static/app/diller/global.js
@@ -0,0 +1,60 @@
+(function () {
+ var Diller = window.Diller = window.Diller || {};
+
+ function toDate(unknown) {
+ if (!unknown) {
+ return undefined;
+ } else if (moment.isMoment(unknown)) {
+ return unknown;
+ } else if (typeof unknown === 'string') {
+ unknown = unknown.trim();
+
+ if (unknown == '') {
+ return moment();
+ }
+
+ return moment(unknown, 'YYYY-MM-DDTHH:mm.sssZ');
+ } else if (typeof unknown === 'string' || moment.isDate(unknown)) {
+ return moment(unknown);
+ } else {
+ return undefined;
+ }
+ }
+
+ Diller.Interval = function (from, to) {
+ var f = toDate(from),
+ t = toDate(to);
+
+ if (f.isAfter(t)) {
+ var tmp = f;
+ f = t;
+ t = tmp;
+ }
+
+ return {
+ getFrom: function () {
+ return f || moment();
+ },
+ getTo: function () {
+ return t || moment();
+ },
+ toString: function () {
+ return 'yo'
+ }
+ };
+ };
+
+ Diller.Interval.create = function (value) {
+ if (value instanceof Diller.Interval) {
+ return value;
+ }
+
+ return new Diller.Interval.hours(24);
+ };
+
+ Diller.Interval.hours = function (hours) {
+ var to = moment();
+ var from = to.subtract(hours, 'hours');
+ return new Diller.Interval(from, to);
+ };
+})();
diff --git a/web/static/app/diller/line-chart.js b/web/static/app/diller/line-chart.js
new file mode 100644
index 0000000..69b6f77
--- /dev/null
+++ b/web/static/app/diller/line-chart.js
@@ -0,0 +1,62 @@
+(function () {
+
+ var isoFormat = 'YYYY-MM-DDTHH:mm:ss';
+
+ function DlLineChartDirective($timeout, DillerClient) {
+ var id_seq = 0;
+
+ return {
+ restrict: 'E',
+ scope: {
+ device: '=',
+ property: '=',
+ value: '=',
+ interval: '='
+ },
+ replace: true,
+ template: '<div/>',
+ link: function (scope, element, attrs) {
+ var elementId = element.attr('id');
+ if (!elementId) {
+ elementId = 'dl-line-chart-' + id_seq++;
+ element.attr('id', elementId);
+ }
+
+ var deviceId = scope.device;
+ var propertyId = scope.property;
+ var interval = Diller.Interval.create(scope.interval);
+ var property = DillerClient.getDevice(deviceId).getProperty(propertyId);
+
+ var options = {
+ axisX: {
+ showLabel: true,
+ showGrid: true,
+ labelInterpolationFnc: function (value, index) {
+ return index % 4 === 0 ? value.format('HH:mm') : null;
+ }
+ }
+ };
+
+ property.getInterval(interval).then(function (data) {
+ var avgs = _.pluck(data.values, 'avg');
+ var timestamps = _.map(data.values, function (row) {
+ return moment(row.timestamp, isoFormat);
+ });
+
+ var chartData = {
+ labels: timestamps,
+ series: [
+ avgs
+ ]
+ };
+
+ var chart = new Chartist.Line('#' + elementId, chartData, options);
+ });
+ }
+ };
+ }
+
+ angular
+ .module('diller.line-chart', ['diller.client'])
+ .directive('dlLineChart', DlLineChartDirective);
+})();
diff --git a/web/static/app/app.js b/web/static/app/diller/web.js
index 22c7f83..4b173ad 100644
--- a/web/static/app/app.js
+++ b/web/static/app/diller/web.js
@@ -1,4 +1,6 @@
(function () {
+ var isoFormat = 'YYYY-MM-DDTHH:mm:ss';
+
function FrontPageController(devices) {
var ctrl = this;
@@ -87,7 +89,63 @@
bindToController: true,
templateUrl: 'app/templates/edit-attribute.modal.html'
});
+ };
+
+ ctrl.interval = Diller.Interval.hours(5);
+
+ // ctrl.values24h = values24h.data.values;
+
+ function chartist() {
+ var avgs = _.pluck(ctrl.values24h, 'avg');
+ var timestamps = _.map(ctrl.values24h, function(row) {
+ var m = moment(row.timestamp, isoFormat);
+ return m.format('HH:mm');
+ });
+
+ var data = {
+ labels: timestamps,
+ series: [
+ avgs
+ ]
+ };
+
+ var options = {
+ axisX: {
+ showLabel: false,
+ showGrid: false
+ }
+ };
+
+// options.lineSmooth = Chartist.Interpolation.cardinal({
+// fillHoles: true,
+// })
+
+ options.axisX = {
+ showLabel: true,
+ showGrid: true,
+ labelInterpolationFnc: function(value, index) {
+ return index % 4 === 0 ? value : null;
+ }
+ };
+
+ var chartData = {
+ series: [[]],
+ labels: []
+ };
+
+ // var chart = new Chartist.Line('#values-chart', chartData, options);
+ // console.log('chart', chart);
+/*
+ $timeout(function() {
+ chartData = data;
+ // console.log(data);
+ var chart = new Chartist.Line('#values-chart', chartData, options);
+ console.log('chart', chart);
+ });
+*/
}
+
+ // chartist();
}
function TimestampFilter() {
@@ -168,12 +226,11 @@
}
angular
- .module('Diller', ['ngRoute', 'ui.bootstrap'])
+ .module('diller.web', ['ngRoute', 'ui.bootstrap', 'diller.line-chart'])
.config(config)
.run(run)
.filter('timestamp', TimestampFilter)
.directive('dlTimestamp', DlTimestampDirective)
.directive('dlDots', DlDotsDirective)
- .service('DillerConfig', DillerConfig)
- .service('DillerRpc', DillerRpc);
+ .service('DillerConfig', DillerConfig);
})();
diff --git a/web/static/app/templates/property.html b/web/static/app/templates/property.html
index 969734b..3f3424f 100644
--- a/web/static/app/templates/property.html
+++ b/web/static/app/templates/property.html
@@ -20,20 +20,25 @@
</a>
</p>
- <dl>
- <dt class="col-sm-3">Key</dt>
- <dd class="col-sm-9">
- {{ctrl.property.key}}
- &nbsp;
- </dd>
+ <div class="row">
+ <dl>
+ <dt class="col-sm-3">Key</dt>
+ <dd class="col-sm-9">
+ {{ctrl.property.key}}
+ &nbsp;
+ </dd>
- <dt class="col-sm-3">Created</dt>
- <dd class="col-sm-9">
- {{ctrl.property.created_timestamp | date:'medium'}}
- &nbsp;
- </dd>
- </dl>
+ <dt class="col-sm-3">Created</dt>
+ <dd class="col-sm-9">
+ {{ctrl.property.created_timestamp | date:'medium'}}
+ &nbsp;
+ </dd>
+ </dl>
+ </div>
+ <dl-line-chart class="ct-golden" device="ctrl.device.id" property="ctrl.property.id" interval="ctrl.interval"></dl-line-chart>
+
+ <!--
<h3>
Latest Values
<small ng-hide="ctrl.loading">
@@ -68,5 +73,6 @@
</tr>
</tbody>
</table>
+ -->
</div>
diff --git a/web/templates/index.jade b/web/templates/index.jade
index 1b2adbc..84c31dc 100644
--- a/web/templates/index.jade
+++ b/web/templates/index.jade
@@ -17,14 +17,19 @@ html(lang='en')
script(src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js", type="application/javascript")
script(src="bower_components/lodash/lodash.js", type="application/javascript")
script(src="bower_components/moment/moment.js", type="application/javascript")
+ script(src="bower_components/chartist/dist/chartist.js", type="application/javascript")
script(src="app/DillerRpc.js", type="application/javascript")
- script(src="app/app.js", type="application/javascript")
+ script(src="app/diller/global.js", type="application/javascript")
+ script(src="app/diller/client.js", type="application/javascript")
+ script(src="app/diller/web.js", type="application/javascript")
+ script(src="app/diller/line-chart.js", type="application/javascript")
link(href="app/app.css", rel="stylesheet")
link(rel="stylesheet", href="bower_components/font-awesome/css/font-awesome.min.css")
+ link(rel="stylesheet", href="bower_components/chartist/dist/chartist.css")
- body(ng-app="Diller")
+ body(ng-app="diller.web")
.container
nav.navbar.navbar-dark.bg-inverse
a.navbar-brand(href='#/') Diller
diff --git a/web/templates/wat.html b/web/templates/wat.html
index fd504a7..0e77077 100644
--- a/web/templates/wat.html
+++ b/web/templates/wat.html
@@ -17,7 +17,7 @@
<script src="./bower_components/lodash/lodash.js" type="application/javascript"></script>
<script src="../static/app/DillerRpc.js" type="application/javascript"></script>
- <script src="../static/app/app.js" type="application/javascript"></script>
+ <script src="../static/app/diller/app.js" type="application/javascript"></script>
</head>
<body ng-app="Diller" ng-view>
Loading Diller ...