diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2016-03-05 16:47:32 +0100 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2016-03-05 16:47:32 +0100 |
commit | 7ca173de3de046501d79164da0c8c8871a03089b (patch) | |
tree | 16d857cf2ab7fd8b7b3c29efbacd6b01c2eacec7 /web | |
parent | dda9ef2ae7971bceaa792e328c8489cb0695b77e (diff) | |
download | diller-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.js | 40 | ||||
-rw-r--r-- | web/static/app/diller/client.js | 72 | ||||
-rw-r--r-- | web/static/app/diller/global.js | 60 | ||||
-rw-r--r-- | web/static/app/diller/line-chart.js | 62 | ||||
-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.html | 30 | ||||
-rw-r--r-- | web/templates/index.jade | 9 | ||||
-rw-r--r-- | web/templates/wat.html | 2 |
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}} - - </dd> + <div class="row"> + <dl> + <dt class="col-sm-3">Key</dt> + <dd class="col-sm-9"> + {{ctrl.property.key}} + + </dd> - <dt class="col-sm-3">Created</dt> - <dd class="col-sm-9"> - {{ctrl.property.created_timestamp | date:'medium'}} - - </dd> - </dl> + <dt class="col-sm-3">Created</dt> + <dd class="col-sm-9"> + {{ctrl.property.created_timestamp | date:'medium'}} + + </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 ... |