From e8ec4001ce1297d5a3db6d3fc8af8de47daa6a61 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 25 Oct 2015 00:33:41 +0200 Subject: wip --- .bowerrc | 2 +- .gitignore | 6 ++- diller-web.js | 12 ++++- package.json | 1 + src/Diller.js | 3 +- src/DillerConfig.js | 1 + src/DillerDao.js | 8 +-- src/web/DillerWeb.js | 83 ++++++++++++++++++++------------ web/app/DillerRpc.js | 41 ---------------- web/app/app.js | 60 ----------------------- web/app/templates/device.html | 21 -------- web/app/templates/front-page.html | 24 --------- web/app/templates/property.html | 36 -------------- web/index.html | 24 --------- web/static/app/DillerRpc.js | 43 +++++++++++++++++ web/static/app/app.css | 3 ++ web/static/app/app.js | 72 +++++++++++++++++++++++++++ web/static/app/templates/device.html | 34 +++++++++++++ web/static/app/templates/front-page.html | 23 +++++++++ web/static/app/templates/property.html | 42 ++++++++++++++++ web/templates/index.jade | 52 ++++++++++++++++++++ web/templates/wat.html | 25 ++++++++++ 22 files changed, 370 insertions(+), 246 deletions(-) delete mode 100644 web/app/DillerRpc.js delete mode 100644 web/app/app.js delete mode 100644 web/app/templates/device.html delete mode 100644 web/app/templates/front-page.html delete mode 100644 web/app/templates/property.html delete mode 100644 web/index.html create mode 100644 web/static/app/DillerRpc.js create mode 100644 web/static/app/app.css create mode 100644 web/static/app/app.js create mode 100644 web/static/app/templates/device.html create mode 100644 web/static/app/templates/front-page.html create mode 100644 web/static/app/templates/property.html create mode 100644 web/templates/index.jade create mode 100644 web/templates/wat.html diff --git a/.bowerrc b/.bowerrc index 80e4029..4c64c6a 100644 --- a/.bowerrc +++ b/.bowerrc @@ -1,3 +1,3 @@ { - "directory": "web/bower_components" + "directory": "web/static/bower_components" } diff --git a/.gitignore b/.gitignore index 7603995..d1026a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ .idea +*.iml + node_modules -web/bower_components +bower_components + +*.pg diff --git a/diller-web.js b/diller-web.js index 4cceaa1..f89755f 100644 --- a/diller-web.js +++ b/diller-web.js @@ -1,3 +1,4 @@ +var fs = require('fs'); var di = require('di'); var injector = new di.Injector(); @@ -6,5 +7,14 @@ config.configureLogging('web'); var dillerWeb = injector.get(require('./src/web/DillerWeb')); dillerWeb.init(); -dillerWeb.generateRpc(); + +if (config.updateDillerRpc) { + var DillerRpc = dillerWeb.generateRpc(); + var orig = fs.readFileSync('web/static/app/DillerRpc.js', {encoding: 'utf-8'}); + if (orig != DillerRpc) { + console.log('DillerRpc updated'); + fs.writeFileSync('web/static/app/DillerRpc.js', DillerRpc); + } +} + dillerWeb.listen(); diff --git a/package.json b/package.json index bfc0373..6f822ad 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "db-migrate": "^0.9.23", "di": "^2.0.0-pre-14", "express": "^4.13.3", + "jade": "^1.11.0", "lodash": "^3.10.1", "mqtt": "^1.4.3", "pg": "^4.4.2", diff --git a/src/Diller.js b/src/Diller.js index a057054..fa2e308 100644 --- a/src/Diller.js +++ b/src/Diller.js @@ -81,7 +81,7 @@ function Diller(config, db) { } if (!f) { - log.warn('Unknown message topic:', topic); + log.warn('Unknown topic:', topic); return; } @@ -107,6 +107,7 @@ function Diller(config, db) { }); }) .then(function (data) { + // log.info('data.device', data.device, 'data.property', data.property); return f(dao, data.device, data.property, message.toString()); }); }).then(function (res) { diff --git a/src/DillerConfig.js b/src/DillerConfig.js index 84afe42..652561a 100644 --- a/src/DillerConfig.js +++ b/src/DillerConfig.js @@ -55,6 +55,7 @@ function configureLogging(app) { function DillerConfig() { return { isProd: isProd, + updateDillerRpc: !isProd(), mqttUrl: mqttUrl, postgresqlConfig: postgresqlConfig, configureLogging: configureLogging, diff --git a/src/DillerDao.js b/src/DillerDao.js index c4d0e67..b46e734 100644 --- a/src/DillerDao.js +++ b/src/DillerDao.js @@ -33,7 +33,7 @@ function DillerDao(tx) { } function devicePropertyByDeviceIdAndKey(deviceId, key) { - return tx.oneOrNone('SELECT id FROM device_property WHERE device=$1 AND key=$2', [deviceId, key]); + return tx.oneOrNone('SELECT ' + propertyColumns + ' FROM device_property WHERE device=$1 AND key=$2', [deviceId, key]); } function devicePropertiesByDeviceId(deviceId) { @@ -41,11 +41,11 @@ function DillerDao(tx) { } function insertDeviceProperty(deviceId, key) { - return tx.oneOrNone('INSERT INTO device_property(id, device, key, created_timestamp) VALUES(DEFAULT, $1, $2, CURRENT_TIMESTAMP) RETURNING ' + propertyColumns, [deviceId, key]); + return tx.one('INSERT INTO device_property(id, device, key, created_timestamp) VALUES(DEFAULT, $1, $2, CURRENT_TIMESTAMP) RETURNING ' + propertyColumns, [deviceId, key]); } function updatePropertyName(id, name) { - return tx.none('UPDATE device_property SET name=$1 WHERE id=$2', name, id); + return tx.none('UPDATE device_property SET name=$1 WHERE id=$2', [name, id]); } function updatePropertyDescription(id, description) { @@ -58,7 +58,7 @@ function DillerDao(tx) { function valuesByPropertyId(propertyId, limit) { limit = limit || 10; - return tx.many('SELECT timestamp, value FROM value WHERE property=$1 LIMIT $2', [propertyId, limit]); + return tx.many('SELECT timestamp, value FROM value WHERE property=$1 ORDER BY timestamp DESC LIMIT $2', [propertyId, limit]); } function insertValue(propertyId, value) { diff --git a/src/web/DillerWeb.js b/src/web/DillerWeb.js index 40fbc3d..a5bdf6b 100644 --- a/src/web/DillerWeb.js +++ b/src/web/DillerWeb.js @@ -59,17 +59,22 @@ function DillerWeb(diller, db, config) { }); } + function getIndex(req, res) { + var baseUrl = (req.headers['trygvis-prefix'] || '').replace(/\/$/, ''); + res.render('index', {baseUrl: baseUrl + '/'}); + } + function init() { app = express(); app.use(bodyParser.urlencoded({extended: true})); app.use(bodyParser.json()); - var router = express.Router(); + var api = express.Router(); - function addRoute(name, method, path, callback) { - router[method](path, callback); - var layer = _.last(router.stack); + function addApi(name, method, path, callback) { + api[method](path, callback); + var layer = _.last(api.stack); calls.push({ name: name, @@ -82,12 +87,21 @@ function DillerWeb(diller, db, config) { }); } - addRoute('getDevices', 'get', '/device', getDevices); - addRoute('getDevice', 'get', '/device/:deviceId', getDevice); - addRoute('getValues', 'get', '/property/:propertyId/values', getValues); + addApi('getDevices', 'get', '/device', getDevices); + addApi('getDevice', 'get', '/device/:deviceId', getDevice); + addApi('getValues', 'get', '/property/:propertyId/values', getValues); + + var templates = express.Router(); - app.use('/api', router); - app.use(express.static('web')); + templates.get('/', getIndex); + + app.set('views', 'web/templates'); + app.set('view engine', 'jade'); + app.set('view cache', false); + + app.use('/api', api); + app.use('/', templates); + app.use(express.static('web/static')); } function listen() { @@ -96,54 +110,59 @@ function DillerWeb(diller, db, config) { } function generateRpc() { - console.log('function DillerRpc($http) {'); + var s = + 'function DillerRpc($http, DillerConfig) {\n' + + ' var baseUrl = DillerConfig.baseUrl;\n' + + '\n'; - var s = _.map(calls, function (call) { + s += _.map(calls, function (call) { //console.error(call); - console.error('call.layer', call.layer); + //console.error('call.layer', call.layer); var s = ' function ' + call.name + '(' + call.keys.join(', ') + ') {\n' + ' var req = {};\n' + ' req.method = \'' + call.method + '\';\n' + - ' req.url = \'/api' + call.path + '\';\n'; + ' req.url = baseUrl + \'/api' + call.path + '\';\n'; s += _.map(call.layer.keys, function (key) { return ' req.url = req.url.replace(/:' + key.name + '/, ' + key.name + ');\n' - }).join(''); + }).join('\n'); s += ' return $http(req);\n' + ' }\n'; return s; - }); - _.each(s, function (x) { - console.log(x); - }); - - console.log(' return {'); - console.log(_.map(calls, function (call) { + }).join('\n'); + s += '\n'; + s += ' return {\n'; + s += _.map(calls, function (call) { return ' ' + call.name + ': ' + call.name - }).join(',\n')); - console.log(' };'); - console.log('}'); - console.log(''); - - console.log('DillerRpcResolve = {};'); - _.each(calls, function (call) { + }).join(',\n'); + s += '\n'; + s += ' };\n'; + s += '}\n'; + s += '\n'; + + s += 'DillerRpcResolve = {};\n'; + s += _.map(calls, function (call) { + var s = ''; var args = ['DillerRpc']; if (call.keys.length > 0) { args.push('$route'); } - console.log('DillerRpcResolve.' + call.name + ' = function(' + args.join(', ') + ') {'); + s += 'DillerRpcResolve.' + call.name + ' = function(' + args.join(', ') + ') {\n'; args = _.map(call.keys, function (key) { return '$route.current.params.' + key; }); - console.log(' return DillerRpc.' + call.name + '(' + args.join(', ') + ');'); - console.log('};'); - }); + s += ' return DillerRpc.' + call.name + '(' + args.join(', ') + ');\n'; + s += '};\n'; + + return s; + }).join(''); + return s; } return { diff --git a/web/app/DillerRpc.js b/web/app/DillerRpc.js deleted file mode 100644 index a0c20fb..0000000 --- a/web/app/DillerRpc.js +++ /dev/null @@ -1,41 +0,0 @@ -function DillerRpc($http) { - function getDevices() { - var req = {}; - req.method = 'get'; - req.url = '/api/device'; - return $http(req); - } - - function getDevice(deviceId) { - var req = {}; - req.method = 'get'; - req.url = '/api/device/:deviceId'; - req.url = req.url.replace(/:deviceId/, deviceId); - return $http(req); - } - - function getValues(propertyId) { - var req = {}; - req.method = 'get'; - req.url = '/api/property/:propertyId/values'; - req.url = req.url.replace(/:propertyId/, propertyId); - return $http(req); - } - - return { - getDevices: getDevices, - getDevice: getDevice, - getValues: getValues - }; -} - -DillerRpcResolve = {}; -DillerRpcResolve.getDevices = function(DillerRpc) { - return DillerRpc.getDevices(); -}; -DillerRpcResolve.getDevice = function(DillerRpc, $route) { - return DillerRpc.getDevice($route.current.params.deviceId); -}; -DillerRpcResolve.getValues = function(DillerRpc, $route) { - return DillerRpc.getValues($route.current.params.propertyId); -}; diff --git a/web/app/app.js b/web/app/app.js deleted file mode 100644 index cd14ae5..0000000 --- a/web/app/app.js +++ /dev/null @@ -1,60 +0,0 @@ -(function () { - function FrontPageController(devices) { - var ctrl = this; - - ctrl.devices = devices.data.devices; - } - - function DeviceController(device) { - var ctrl = this; - - ctrl.device = device.data.device; - } - - function PropertyController($route, device, values) { - var ctrl = this; - - ctrl.device = device.data.device; - ctrl.property = _.find(ctrl.device.properties, {id: $route.current.params.propertyId}); - ctrl.values = values.data.values; - } - - function config($routeProvider, $locationProvider) { - $routeProvider - .when('/', { - controller: FrontPageController, - controllerAs: 'ctrl', - templateUrl: '/app/templates/front-page.html', - resolve: { - devices: DillerRpcResolve.getDevices - } - }) - .when('/device/:deviceId', { - controller: DeviceController, - controllerAs: 'ctrl', - templateUrl: '/app/templates/device.html', - resolve: { - device: DillerRpcResolve.getDevice - } - }) - .when('/device/:deviceId/property/:propertyId', { - controller: PropertyController, - controllerAs: 'ctrl', - templateUrl: '/app/templates/property.html', - resolve: { - device: DillerRpcResolve.getDevice, - values: DillerRpcResolve.getValues - } - }) - .otherwise({ - redirectTo: '/' - }); - - //$locationProvider.html5Mode(true); - } - - angular - .module('Diller', ['ngRoute']) - .config(config) - .service('DillerRpc', DillerRpc); -})(); diff --git a/web/app/templates/device.html b/web/app/templates/device.html deleted file mode 100644 index ae028b5..0000000 --- a/web/app/templates/device.html +++ /dev/null @@ -1,21 +0,0 @@ -
- -

- {{ctrl.device.key}} - device -

- - - -

Properties

- - -
diff --git a/web/app/templates/front-page.html b/web/app/templates/front-page.html deleted file mode 100644 index 1846dea..0000000 --- a/web/app/templates/front-page.html +++ /dev/null @@ -1,24 +0,0 @@ -
- -

- Diller - All your sensor data are belong to us -

- -

Devices

- - - - - - - - - - - - -
Key
- {{d.key}} -
-
diff --git a/web/app/templates/property.html b/web/app/templates/property.html deleted file mode 100644 index 65a66e8..0000000 --- a/web/app/templates/property.html +++ /dev/null @@ -1,36 +0,0 @@ -
- -

- {{ctrl.device.key}} - device -

- -

- {{ctrl.property.key}} - property -

- - - -

Latest Values

- - - - - - - - - - - - - - -
TimestampValue
{{v.timestamp | date:'medium'}}{{v.value}}
- -
diff --git a/web/index.html b/web/index.html deleted file mode 100644 index b591e55..0000000 --- a/web/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - -Loading Diller ... - - diff --git a/web/static/app/DillerRpc.js b/web/static/app/DillerRpc.js new file mode 100644 index 0000000..de90aee --- /dev/null +++ b/web/static/app/DillerRpc.js @@ -0,0 +1,43 @@ +function DillerRpc($http, DillerConfig) { + var baseUrl = DillerConfig.baseUrl; + + function getDevices() { + var req = {}; + req.method = 'get'; + req.url = baseUrl + '/api/device'; + return $http(req); + } + + function getDevice(deviceId) { + var req = {}; + req.method = 'get'; + req.url = baseUrl + '/api/device/:deviceId'; + req.url = req.url.replace(/:deviceId/, deviceId); + return $http(req); + } + + function getValues(propertyId) { + var req = {}; + req.method = 'get'; + req.url = baseUrl + '/api/property/:propertyId/values'; + req.url = req.url.replace(/:propertyId/, propertyId); + return $http(req); + } + + return { + getDevices: getDevices, + getDevice: getDevice, + getValues: getValues + }; +} + +DillerRpcResolve = {}; +DillerRpcResolve.getDevices = function(DillerRpc) { + return DillerRpc.getDevices(); +}; +DillerRpcResolve.getDevice = function(DillerRpc, $route) { + return DillerRpc.getDevice($route.current.params.deviceId); +}; +DillerRpcResolve.getValues = function(DillerRpc, $route) { + return DillerRpc.getValues($route.current.params.propertyId); +}; diff --git a/web/static/app/app.css b/web/static/app/app.css new file mode 100644 index 0000000..090ac5e --- /dev/null +++ b/web/static/app/app.css @@ -0,0 +1,3 @@ +nav.navbar { + margin-bottom: 2rem; +} diff --git a/web/static/app/app.js b/web/static/app/app.js new file mode 100644 index 0000000..5274362 --- /dev/null +++ b/web/static/app/app.js @@ -0,0 +1,72 @@ +(function () { + function FrontPageController(devices) { + var ctrl = this; + + ctrl.devices = devices.data.devices; + } + + function DeviceController(device) { + var ctrl = this; + + ctrl.device = device.data.device; + } + + function PropertyController($route, device, values) { + var ctrl = this; + + ctrl.device = device.data.device; + ctrl.property = _.find(ctrl.device.properties, {id: $route.current.params.propertyId}); + ctrl.values = values.data.values; + } + + function config($routeProvider, $locationProvider) { + $routeProvider + .when('/', { + controller: FrontPageController, + controllerAs: 'ctrl', + templateUrl: 'app/templates/front-page.html', + resolve: { + devices: DillerRpcResolve.getDevices + } + }) + .when('/device/:deviceId', { + controller: DeviceController, + controllerAs: 'ctrl', + templateUrl: 'app/templates/device.html', + resolve: { + device: DillerRpcResolve.getDevice + } + }) + .when('/device/:deviceId/property/:propertyId', { + controller: PropertyController, + controllerAs: 'ctrl', + templateUrl: 'app/templates/property.html', + resolve: { + device: DillerRpcResolve.getDevice, + values: DillerRpcResolve.getValues + } + }) + .otherwise({ + redirectTo: '/' + }); + + //$locationProvider.html5Mode(true); + } + + function DillerConfig() { + var head = document.getElementsByTagName('head')[0]; + var base = head.getElementsByTagName('base')[0]; + console.log('base =', base); + var baseUrl = base.href.replace(/\/$/, ''); + console.log('baseUrl =', baseUrl); + return { + baseUrl: baseUrl + }; + } + + angular + .module('Diller', ['ngRoute']) + .config(config) + .service('DillerConfig', DillerConfig) + .service('DillerRpc', DillerRpc); +})(); diff --git a/web/static/app/templates/device.html b/web/static/app/templates/device.html new file mode 100644 index 0000000..b466fdc --- /dev/null +++ b/web/static/app/templates/device.html @@ -0,0 +1,34 @@ +
+ +

+ {{ctrl.device.key}} + device +

+ + + +

Properties

+ + + + + + + + + + + + + + +
RegisteredKey
+ {{p.created_timestamp | date:'medium'}} + + {{p.key}} +
+
diff --git a/web/static/app/templates/front-page.html b/web/static/app/templates/front-page.html new file mode 100644 index 0000000..68026c3 --- /dev/null +++ b/web/static/app/templates/front-page.html @@ -0,0 +1,23 @@ +
+ +

Devices

+ + + + + + + + + + + + + + +
RegisteredKey
+ {{d.created_timestamp | date:'medium'}} + + {{d.key}} +
+
diff --git a/web/static/app/templates/property.html b/web/static/app/templates/property.html new file mode 100644 index 0000000..5f925e7 --- /dev/null +++ b/web/static/app/templates/property.html @@ -0,0 +1,42 @@ +
+ +

+ {{ctrl.device.key}} + device +

+ +

+ {{ctrl.property.key}} + property +

+ + + +

Latest Values

+ + + + + + + + + + + + + + + + + + + + +
TimestampValue
{{v.timestamp | date:'medium'}}{{v.value}}
{{v.timestamp | date:'medium'}}{{v.value}}
+ +
diff --git a/web/templates/index.jade b/web/templates/index.jade new file mode 100644 index 0000000..025354e --- /dev/null +++ b/web/templates/index.jade @@ -0,0 +1,52 @@ +doctype html + +html(lang='en') + head + meta(charset='utf-8') + meta(name="viewport", content="width=device-width, initial-scale=1") + meta(http-equiv="x-ua-compatible", content="ie=edge") + + base(href!=baseUrl) + + script(src="bower_components/jquery/dist/jquery.js", type="application/javascript") + script(src="bower_components/bootstrap/dist/js/bootstrap.js", type="application/javascript") + link(rel="stylesheet", href="bower_components/bootstrap/dist/css/bootstrap.css") + script(src="bower_components/angular/angular.js", type="application/javascript") + script(src="bower_components/angular-route/angular-route.js", type="application/javascript") + script(src="bower_components/lodash/lodash.js", type="application/javascript") + + script(src="app/DillerRpc.js", type="application/javascript") + script(src="app/app.js", type="application/javascript") + link(href="app/app.css", rel="stylesheet") + + body(ng-app="Diller") + .container + nav.navbar.navbar-dark.bg-inverse + a.navbar-brand(href='#/') Diller + ul.nav.navbar-nav + li.nav-item + a.nav-link(href='#/') Devices + + // + + span(ng-view) Loading Diller ... diff --git a/web/templates/wat.html b/web/templates/wat.html new file mode 100644 index 0000000..fd504a7 --- /dev/null +++ b/web/templates/wat.html @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + +Loading Diller ... + + -- cgit v1.2.3