From 20b697c42c4cc5e0fdf4bbf8d59a97216562ca78 Mon Sep 17 00:00:00 2001 From: johannnes <> Date: Sat, 23 Mar 2013 15:32:16 +0000 Subject: [PATCH] added support for controling devices; fixed dblogs statistics by casting to floats git-svn-id: https://svn.fhem.de/fhem/trunk@2969 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/www/frontend/CHANGED | 6 + fhem/www/frontend/FHEM/93_DbLog.pm | 76 ++- fhem/www/frontend/controls_frontend.txt | 10 +- .../app/controller/ChartController.js | 18 + .../frontend/app/controller/MainController.js | 93 +++- .../www/frontend/app/view/DevicePanel.js | 490 ++++++++++++++---- .../www/frontend/app/view/Viewport.js | 29 +- 7 files changed, 572 insertions(+), 150 deletions(-) diff --git a/fhem/www/frontend/CHANGED b/fhem/www/frontend/CHANGED index 9e873730d..bb719a645 100644 --- a/fhem/www/frontend/CHANGED +++ b/fhem/www/frontend/CHANGED @@ -1,3 +1,9 @@ +Update vom 23.3.2013 + * Integration von Buttons und Dropdownlisten, um einzelene Geräte steuern zu können + * Aktualisierung aller Geräteinformationen über kontinuierliche AJAX Requests + * Korrektur der Statistikfunktion im DbLog Modul, Cast auf Floats hinzugefügt + * viele Bugfixes + Update vom 18.3.2013 * Implementation einer Statistikfunktion für Charts, die für ein beliebiges Reading * Summen diff --git a/fhem/www/frontend/FHEM/93_DbLog.pm b/fhem/www/frontend/FHEM/93_DbLog.pm index 1b4de6b8a..69c8e3a76 100644 --- a/fhem/www/frontend/FHEM/93_DbLog.pm +++ b/fhem/www/frontend/FHEM/93_DbLog.pm @@ -780,53 +780,99 @@ sub prepareSql(@_) { if ($dbmodel eq "POSTGRESQL") { ### POSTGRESQL Queries for Statistics ### ### hour: - $hourstats = "SELECT to_char(timestamp, 'YYYY-MM-DD HH24:00:00') AS TIMESTAMP, SUM(VALUE::float) AS SUM, AVG(VALUE::float) AS AVG, MIN(VALUE::float) AS MIN, MAX(VALUE::float) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; + $hourstats = "SELECT to_char(timestamp, 'YYYY-MM-DD HH24:00:00') AS TIMESTAMP, SUM(VALUE::float) AS SUM, "; + $hourstats .= "AVG(VALUE::float) AS AVG, MIN(VALUE::float) AS MIN, MAX(VALUE::float) AS MAX, "; + $hourstats .= "COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' "; + $hourstats .= "AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; ### day: - $daystats = "SELECT to_char(timestamp, 'YYYY-MM-DD 00:00:00') AS TIMESTAMP, SUM(VALUE::float) AS SUM, AVG(VALUE::float) AS AVG, MIN(VALUE::float) AS MIN, MAX(VALUE::float) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; + $daystats = "SELECT to_char(timestamp, 'YYYY-MM-DD 00:00:00') AS TIMESTAMP, SUM(VALUE::float) AS SUM, "; + $daystats .= "AVG(VALUE::float) AS AVG, MIN(VALUE::float) AS MIN, MAX(VALUE::float) AS MAX, "; + $daystats .= "COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' "; + $daystats .= "AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; ### week: - $weekstats = "SELECT date_trunc('week',timestamp) AS TIMESTAMP, SUM(VALUE::float) AS SUM, AVG(VALUE::float) AS AVG, MIN(VALUE::float) AS MIN, MAX(VALUE::float) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; + $weekstats = "SELECT date_trunc('week',timestamp) AS TIMESTAMP, SUM(VALUE::float) AS SUM, "; + $weekstats .= "AVG(VALUE::float) AS AVG, MIN(VALUE::float) AS MIN, MAX(VALUE::float) AS MAX, "; + $weekstats .= "COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' "; + $weekstats .= "AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; ### month: - $monthstats = "SELECT to_char(timestamp, 'YYYY-MM-01 00:00:00') AS TIMESTAMP, SUM(VALUE::float) AS SUM, AVG(VALUE::float) AS AVG, MIN(VALUE::float) AS MIN, MAX(VALUE::float) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; + $monthstats = "SELECT to_char(timestamp, 'YYYY-MM-01 00:00:00') AS TIMESTAMP, SUM(VALUE::float) AS SUM, "; + $monthstats .= "AVG(VALUE::float) AS AVG, MIN(VALUE::float) AS MIN, MAX(VALUE::float) AS MAX, "; + $monthstats .= "COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' "; + $monthstats .= "AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; ### year: - $yearstats = "SELECT to_char(timestamp, 'YYYY-01-01 00:00:00') AS TIMESTAMP, SUM(VALUE::float) AS SUM, AVG(VALUE::float) AS AVG, MIN(VALUE::float) AS MIN, MAX(VALUE::float) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; + $yearstats = "SELECT to_char(timestamp, 'YYYY-01-01 00:00:00') AS TIMESTAMP, SUM(VALUE::float) AS SUM, "; + $yearstats .= "AVG(VALUE::float) AS AVG, MIN(VALUE::float) AS MIN, MAX(VALUE::float) AS MAX, "; + $yearstats .= "COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' "; + $yearstats .= "AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; } elsif ($dbmodel eq "MYSQL") { ### MYSQL Queries for Statistics ### ### hour: - $hourstats = "SELECT date_format(timestamp, '%Y-%m-%d %H:00:00') AS TIMESTAMP, SUM(VALUE) AS SUM, AVG(VALUE) AS AVG, MIN(VALUE) AS MIN, MAX(VALUE) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; + $hourstats = "SELECT date_format(timestamp, '%Y-%m-%d %H:00:00') AS TIMESTAMP, SUM(CAST(VALUE AS DECIMAL(12,4))) AS SUM, "; + $hourstats .= "AVG(CAST(VALUE AS DECIMAL(12,4))) AS AVG, MIN(CAST(VALUE AS DECIMAL(12,4))) AS MIN, "; + $hourstats .= "MAX(CAST(VALUE AS DECIMAL(12,4))) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' "; + $hourstats .= "AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; ### day: - $daystats = "SELECT date_format(timestamp, '%Y-%m-%d 00:00:00') AS TIMESTAMP, SUM(VALUE) AS SUM, AVG(VALUE) AS AVG, MIN(VALUE) AS MIN, MAX(VALUE) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; + $daystats = "SELECT date_format(timestamp, '%Y-%m-%d 00:00:00') AS TIMESTAMP, SUM(CAST(VALUE AS DECIMAL(12,4))) AS SUM, "; + $daystats .= "AVG(CAST(VALUE AS DECIMAL(12,4))) AS AVG, MIN(CAST(VALUE AS DECIMAL(12,4))) AS MIN, "; + $daystats .= "MAX(CAST(VALUE AS DECIMAL(12,4))) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' "; + $daystats .= "AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; ### week: - $weekstats = "SELECT date_format(timestamp, '%Y-%m-%d 00:00:00') AS TIMESTAMP, SUM(VALUE) AS SUM, AVG(VALUE) AS AVG, MIN(VALUE) AS MIN, MAX(VALUE) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY date_format(timestamp, '%Y-%u 00:00:00') ORDER BY 1;"; + $weekstats = "SELECT date_format(timestamp, '%Y-%m-%d 00:00:00') AS TIMESTAMP, SUM(CAST(VALUE AS DECIMAL(12,4))) AS SUM, "; + $weekstats .= "AVG(CAST(VALUE AS DECIMAL(12,4))) AS AVG, MIN(CAST(VALUE AS DECIMAL(12,4))) AS MIN, "; + $weekstats .= "MAX(CAST(VALUE AS DECIMAL(12,4))) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' "; + $weekstats .= "AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' "; + $weekstats .= "GROUP BY date_format(timestamp, '%Y-%u 00:00:00') ORDER BY 1;"; ### month: - $monthstats = "SELECT date_format(timestamp, '%Y-%m-01 00:00:00') AS TIMESTAMP, SUM(VALUE) AS SUM, AVG(VALUE) AS AVG, MIN(VALUE) AS MIN, MAX(VALUE) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; + $monthstats = "SELECT date_format(timestamp, '%Y-%m-01 00:00:00') AS TIMESTAMP, SUM(CAST(VALUE AS DECIMAL(12,4))) AS SUM, "; + $monthstats .= "AVG(CAST(VALUE AS DECIMAL(12,4))) AS AVG, MIN(CAST(VALUE AS DECIMAL(12,4))) AS MIN, "; + $monthstats .= "MAX(CAST(VALUE AS DECIMAL(12,4))) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' "; + $monthstats .= "AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; ### year: - $yearstats = "SELECT date_format(timestamp, '%Y-01-01 00:00:00') AS TIMESTAMP, SUM(VALUE) AS SUM, AVG(VALUE) AS AVG, MIN(VALUE) AS MIN, MAX(VALUE) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; + $yearstats = "SELECT date_format(timestamp, '%Y-01-01 00:00:00') AS TIMESTAMP, SUM(CAST(VALUE AS DECIMAL(12,4))) AS SUM, "; + $yearstats .= "AVG(CAST(VALUE AS DECIMAL(12,4))) AS AVG, MIN(CAST(VALUE AS DECIMAL(12,4))) AS MIN, "; + $yearstats .= "MAX(CAST(VALUE AS DECIMAL(12,4))) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' "; + $yearstats .= "AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY 1 ORDER BY 1;"; } elsif ($hash->{DBMODEL} eq "SQLITE") { ### SQLITE Queries for Statistics ### ### hour: - $hourstats = "SELECT TIMESTAMP, SUM(VALUE) AS SUM, AVG(VALUE) AS AVG, MIN(VALUE) AS MIN, MAX(VALUE) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY strftime('%Y-%m-%d %H:00:00', TIMESTAMP);"; + $hourstats = "SELECT TIMESTAMP, SUM(CAST(VALUE AS FLOAT)) AS SUM, AVG(CAST(VALUE AS FLOAT)) AS AVG, "; + $hourstats .= "MIN(CAST(VALUE AS FLOAT)) AS MIN, MAX(CAST(VALUE AS FLOAT)) AS MAX, COUNT(VALUE) AS COUNT "; + $hourstats .= "FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' "; + $hourstats .= "AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY strftime('%Y-%m-%d %H:00:00', TIMESTAMP);"; ### day: - $daystats = "SELECT TIMESTAMP, SUM(VALUE) AS SUM, AVG(VALUE) AS AVG, MIN(VALUE) AS MIN, MAX(VALUE) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY strftime('%Y-%m-%d 00:00:00', TIMESTAMP);"; + $daystats = "SELECT TIMESTAMP, SUM(CAST(VALUE AS FLOAT)) AS SUM, AVG(CAST(VALUE AS FLOAT)) AS AVG, "; + $daystats .= "MIN(CAST(VALUE AS FLOAT)) AS MIN, MAX(CAST(VALUE AS FLOAT)) AS MAX, COUNT(VALUE) AS COUNT "; + $daystats .= "FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' "; + $daystats .= "AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY strftime('%Y-%m-%d 00:00:00', TIMESTAMP);"; ### week: - $weekstats = "SELECT TIMESTAMP, SUM(VALUE) AS SUM, AVG(VALUE) AS AVG, MIN(VALUE) AS MIN, MAX(VALUE) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY strftime('%Y-%W 00:00:00', TIMESTAMP);"; + $weekstats = "SELECT TIMESTAMP, SUM(CAST(VALUE AS FLOAT)) AS SUM, AVG(CAST(VALUE AS FLOAT)) AS AVG, "; + $weekstats .= "MIN(CAST(VALUE AS FLOAT)) AS MIN, MAX(CAST(VALUE AS FLOAT)) AS MAX, COUNT(VALUE) AS COUNT "; + $weekstats .= "FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' "; + $weekstats .= "AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY strftime('%Y-%W 00:00:00', TIMESTAMP);"; ### month: - $monthstats = "SELECT TIMESTAMP, SUM(VALUE) AS SUM, AVG(VALUE) AS AVG, MIN(VALUE) AS MIN, MAX(VALUE) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY strftime('%Y-%m 00:00:00', TIMESTAMP);"; + $monthstats = "SELECT TIMESTAMP, SUM(CAST(VALUE AS FLOAT)) AS SUM, AVG(CAST(VALUE AS FLOAT)) AS AVG, "; + $monthstats .= "MIN(CAST(VALUE AS FLOAT)) AS MIN, MAX(CAST(VALUE AS FLOAT)) AS MAX, COUNT(VALUE) AS COUNT "; + $monthstats .= "FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' "; + $monthstats .= "AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY strftime('%Y-%m 00:00:00', TIMESTAMP);"; ### year: - $yearstats = "SELECT TIMESTAMP, SUM(VALUE) AS SUM, AVG(VALUE) AS AVG, MIN(VALUE) AS MIN, MAX(VALUE) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY strftime('%Y 00:00:00', TIMESTAMP);"; + $yearstats = "SELECT TIMESTAMP, SUM(CAST(VALUE AS FLOAT)) AS SUM, AVG(CAST(VALUE AS FLOAT)) AS AVG, "; + $yearstats .= "MIN(CAST(VALUE AS FLOAT)) AS MIN, MAX(CAST(VALUE AS FLOAT)) AS MAX, COUNT(VALUE) AS COUNT "; + $yearstats .= "FROM history WHERE READING = '$yaxis' AND DEVICE = '$device' "; + $yearstats .= "AND TIMESTAMP Between '$starttime' AND '$endtime' GROUP BY strftime('%Y 00:00:00', TIMESTAMP);"; } else { $sql = "errordb"; diff --git a/fhem/www/frontend/controls_frontend.txt b/fhem/www/frontend/controls_frontend.txt index ba89d4d3f..80c2f2f59 100644 --- a/fhem/www/frontend/controls_frontend.txt +++ b/fhem/www/frontend/controls_frontend.txt @@ -37,18 +37,18 @@ DIR www/frontend/lib/ext-4.1.1a/images/gray/grid DIR www/frontend/lib/ext-4.1.1a/images/gray/util DIR www/frontend/lib/ext-4.1.1a/images/gray/panel-header DIR www/frontend/lib/ext-4.1.1a/images/gray/tip -UPD 2013-03-16_05:44:48 49791 FHEM/93_DbLog.pm +UPD 2013-03-23_05:44:48 57766 FHEM/93_DbLog.pm UPD 2013-03-08_07:13:10 563 www/frontend/index.html UPD 2013-03-06_11:11:22 236 www/frontend/README.txt UPD 2013-03-08_01:44:54 613 www/frontend/app/userconfig.js UPD 2013-03-06_11:11:22 1856 www/frontend/app/app.js UPD 2013-03-18_06:58:48 27330 www/frontend/app/view/LineChartPanel.js -UPD 2013-03-16_06:15:53 7586 www/frontend/app/view/Viewport.js -UPD 2013-03-16_06:15:46 4279 www/frontend/app/view/DevicePanel.js +UPD 2013-03-23_06:15:53 8137 www/frontend/app/view/Viewport.js +UPD 2013-03-23_06:15:46 15563 www/frontend/app/view/DevicePanel.js UPD 2013-03-06_11:11:22 2503 www/frontend/app/view/TableDataGridPanel.js UPD 2013-03-06_11:11:22 1310 www/frontend/app/view/LineChartView.js -UPD 2013-03-18_06:58:22 54163 www/frontend/app/controller/ChartController.js -UPD 2013-03-16_11:15:36 10115 www/frontend/app/controller/MainController.js +UPD 2013-03-23_06:58:22 54921 www/frontend/app/controller/ChartController.js +UPD 2013-03-23_06:15:36 11211 www/frontend/app/controller/MainController.js UPD 2013-03-06_11:11:22 202 www/frontend/app/model/ReadingsModel.js UPD 2013-03-06_11:11:22 338 www/frontend/app/model/SavedChartsModel.js UPD 2013-03-18_05:43:31 2173 www/frontend/app/model/ChartModel.js diff --git a/fhem/www/frontend/www/frontend/app/controller/ChartController.js b/fhem/www/frontend/www/frontend/app/controller/ChartController.js index 0d430779e..666a1bf45 100644 --- a/fhem/www/frontend/www/frontend/app/controller/ChartController.js +++ b/fhem/www/frontend/www/frontend/app/controller/ChartController.js @@ -697,22 +697,27 @@ Ext.define('FHEM.controller.ChartController', { view.axes.get(0).maximum = store.max('VALUE'); } else if (yaxisstatistics.indexOf("sum") > 0) { y1series.yField = 'SUM'; + y1series.tips.renderer = me.setSeriesRenderer('SUM'); view.axes.get(0).maximum = store.max('SUM'); view.axes.get(0).setTitle("SUM " + yaxis); } else if (yaxisstatistics.indexOf("average") > 0) { y1series.yField = 'AVG'; + y1series.tips.renderer = me.setSeriesRenderer('AVG'); view.axes.get(0).maximum = store.max('AVG'); view.axes.get(0).setTitle("AVG " + yaxis); } else if (yaxisstatistics.indexOf("min") > 0) { y1series.yField = 'MIN'; + y1series.tips.renderer = me.setSeriesRenderer('MIN'); view.axes.get(0).maximum = store.max('MIN'); view.axes.get(0).setTitle("MIN " + yaxis); } else if (yaxisstatistics.indexOf("max") > 0) { y1series.yField = 'MAX'; + y1series.tips.renderer = me.setSeriesRenderer('MAX'); view.axes.get(0).maximum = store.max('MAX'); view.axes.get(0).setTitle("MAX " + yaxis); } else if (yaxisstatistics.indexOf("count") > 0) { y1series.yField = 'COUNT'; + y1series.tips.renderer = me.setSeriesRenderer('COUNT'); view.axes.get(0).maximum = store.max('COUNT'); view.axes.get(0).setTitle("COUNT " + yaxis); } @@ -727,6 +732,19 @@ Ext.define('FHEM.controller.ChartController', { }, + /** + * Setup the renderer for displaying values in chart with mouse hover + */ + setSeriesRenderer: function(value) { + + var renderer = function (storeItem, item) { + this.setTitle(' ' + value + ' : ' + storeItem.get(value) + + '
Time: ' + storeItem.get('TIMESTAMP')); + }; + + return renderer; + }, + /** * */ diff --git a/fhem/www/frontend/www/frontend/app/controller/MainController.js b/fhem/www/frontend/www/frontend/app/controller/MainController.js index b5c4287bb..f50037e8e 100644 --- a/fhem/www/frontend/www/frontend/app/controller/MainController.js +++ b/fhem/www/frontend/www/frontend/app/controller/MainController.js @@ -76,7 +76,7 @@ Ext.define('FHEM.controller.MainController', { if (Ext.isDefined(FHEM.version)) { var sp = this.getStatustextfield(); - sp.setText(FHEM.version + "; Frontend Version: 0.3 - 2013-03-16"); + sp.setText(FHEM.version + "; Frontend Version: 0.4 - 2013-03-23"); } //setup west accordion / treepanel @@ -108,21 +108,6 @@ Ext.define('FHEM.controller.MainController', { this.getMaintreepanel().setRootNode(rootNode); }, - /** - * - */ - showDevicePanel: function(view, record) { - var panel = { - xtype: 'devicepanel', - title: record.raw.NAME, - region: 'center', - layout: 'fit', - record: record - }; - this.hideCenterPanels(); - this.getMainviewport().add(panel); - }, - /** * */ @@ -147,13 +132,19 @@ Ext.define('FHEM.controller.MainController', { border: false, closable: false, plain: true - });win.showAt(Ext.getBody().getWidth() / 2 -100, 30); + }); + win.showAt(Ext.getBody().getWidth() / 2 -100, 30); win.getEl().animate({ opacity: 0, easing: 'easeOut', duration: 3000, delay: 2000, - remove: true + remove: false, + listeners: { + afteranimate: function() { + win.destroy(); + } + } }); }, failure: function() { @@ -215,13 +206,19 @@ Ext.define('FHEM.controller.MainController', { border: false, closable: false, plain: true - });win.showAt(Ext.getBody().getWidth() / 2 -100, 30); + }); + win.showAt(Ext.getBody().getWidth() / 2 -100, 30); win.getEl().animate({ opacity: 0, easing: 'easeOut', duration: 3000, delay: 2000, - remove: true + remove: false, + listeners: { + afteranimate: function() { + win.destroy(); + } + } }); } @@ -251,13 +248,19 @@ Ext.define('FHEM.controller.MainController', { border: false, closable: false, plain: true - });win.showAt(Ext.getBody().getWidth() / 2 -100, 30); + }); + win.showAt(Ext.getBody().getWidth() / 2 -100, 30); win.getEl().animate({ opacity: 0, easing: 'easeOut', duration: 3000, delay: 2000, - remove: true + remove: false, + listeners: { + afteranimate: function() { + win.destroy(); + } + } }); }, @@ -309,27 +312,61 @@ Ext.define('FHEM.controller.MainController', { /** * */ - hideCenterPanels: function() { + destroyCenterPanels: function() { var panels = Ext.ComponentQuery.query('panel[region=center]'); Ext.each(panels, function(panel) { - panel.hide(); + panel.destroy(); }); }, + /** + * + */ + showDevicePanel: function(view, record) { + + var title; + if (record.raw.ATTR && record.raw.ATTR.alias && !Ext.isEmpty(record.raw.ATTR.alias)) { + title = record.raw.data.ATTR.alias; + } else { + title = record.raw.data.NAME; + } + var panel = { + xtype: 'devicepanel', + title: title, + region: 'center', + layout: 'fit', + record: record + }; + this.destroyCenterPanels(); + this.getMainviewport().add(panel); + }, + /** * */ showLineChartPanel: function() { - this.hideCenterPanels(); - Ext.ComponentQuery.query('panel[name=linechartpanel]')[0].show(); + var panel = { + xtype: 'linechartpanel', + name: 'linechartpanel', + region: 'center', + layout: 'fit' + }; + this.destroyCenterPanels(); + this.getMainviewport().add(panel); }, /** * */ showDatabaseTablePanel: function() { - this.hideCenterPanels(); - Ext.ComponentQuery.query('panel[name=tabledatagridpanel]')[0].show(); + var panel = { + xtype: 'tabledatagridpanel', + name: 'tabledatagridpanel', + region: 'center', + layout: 'fit' + }; + this.destroyCenterPanels(); + this.getMainviewport().add(panel); } }); \ No newline at end of file diff --git a/fhem/www/frontend/www/frontend/app/view/DevicePanel.js b/fhem/www/frontend/www/frontend/app/view/DevicePanel.js index 81baccdbf..ad3106a51 100644 --- a/fhem/www/frontend/www/frontend/app/view/DevicePanel.js +++ b/fhem/www/frontend/www/frontend/app/view/DevicePanel.js @@ -35,110 +35,416 @@ Ext.define('FHEM.view.DevicePanel', { me.callParent(arguments); - var devicedata = []; + var controlFieldset = Ext.create('Ext.form.FieldSet', { + title: 'Controls', + name: 'controlfieldset', + layout: 'column', + hidden: true, + bodyStyle: 'padding:5px 5px 0', + defaults: { + margin: '0 10 10 10', + height: 65 + } + }); + me.down('panel[name=container]').add(controlFieldset); - Ext.iterate(me.record.raw.data, function(key, value) { - if (key !== 'ATTR' && key !== 'attrs' && key !== 'sets' && key !== 'READINGS') { - var obj = { - key: key, - value: value - }; + var devicedatastore = Ext.create('Ext.data.Store', { + fields: ['key', 'value'], + data: [], + proxy: { + type: 'memory', + reader: { + type: 'json' + } + } + }); + var devicedatagrid = { + xtype: 'grid', + title: 'Device Data', + name: 'devicedata', + columns: [ + { + header: 'KEY', + dataIndex: 'key', + width: '49%' + }, + { + header: 'VALUE', + dataIndex: 'value', + width: '49%' + } + ], + store: devicedatastore + }; + me.down('panel[name=container]').add(devicedatagrid); + + var devicereadingsstore = Ext.create('Ext.data.Store', { + fields: ['key', 'value', 'measured'], + data: [], + proxy: { + type: 'memory', + reader: { + type: 'json' + } + } + }); + var devicereadingsgrid = { + xtype: 'grid', + title: 'Device Readings', + name: 'readingsgrid', + columns: [ + { + header: 'KEY', + dataIndex: 'key', + width: '33%' + }, + { + header: 'VALUE', + dataIndex: 'value', + width: '33%' + }, + { + header: 'MEASURED', + dataIndex: 'measured', + width: '33%' + } + ], + store: devicereadingsstore + }; + me.down('panel[name=container]').add(devicereadingsgrid); + + // Stop all old tasks + Ext.TaskManager.stopAll(); + + // Starting a task to update the device readings + var task = { + run: function(){ + me.getDeviceData(me.record.raw.data.NAME); + }, + interval: 5000 //5 seconds + }; + Ext.TaskManager.start(task); + + me.on("afterrender", function() { + me.setLoading(true); + }); + + me.on("destroy", function() { + Ext.TaskManager.stopAll(); + }); + + }, + + /** + * + */ + sendCommand: function(command, value) { + var me = this, + url = '../../../fhem?cmd=set ' + me.record.raw.data.NAME + ' '+ command; + + if (value && !Ext.isEmpty(value)) { + url += ' ' + value; + } + url += '&XHR=1'; + + Ext.Ajax.request({ + method: 'GET', + disableCaching: false, + url: url, + success: function(response){ + if (response.status === 200) { + //all ok + var win = Ext.create('Ext.window.Window', { + width: 130, + height: 60, + html: 'Command submitted!', + preventHeader: true, + border: false, + closable: false, + plain: true + }); + win.showAt(Ext.getBody().getWidth() / 2 -100, 30); + win.getEl().animate({ + opacity: 0, + easing: 'easeOut', + duration: 3000, + delay: 2000, + remove: false, + listeners: { + afteranimate: function() { + win.destroy(); + } + } + }); + + // trigger an update nearly immediately to set new values + var task = new Ext.util.DelayedTask(function(){ + me.getDeviceData(me.record.raw.data.NAME); + }); + task.delay(1000); + + } - devicedata.push(obj); + }, + failure: function() { + Ext.Msg.alert("Error", "Could not send command!"); } }); - if (devicedata.length > 0) { - var devicedatastore = Ext.create('Ext.data.Store', { - fields: ['key', 'value'], - data: devicedata, - proxy: { - type: 'memory', - reader: { - type: 'json' + }, + + /** + * + */ + updateControls: function(results) { + + var me = this, + allSets = results.sets, + controlfieldset = me.down('panel[name=container] fieldset[name=controlfieldset]'); + + if (controlfieldset.items.length <= 0) { + + if (results.ATTR.webCmd) { + Ext.each(results.sets, function(set) { + var split = set.split(":"); + if (split[0] === results.ATTR.webCmd) { + // overriding all sets as we only need the user defined webcmd now + allSets = set; } + }); + } + + Ext.each(allSets, function(set) { + //check for button / slider + if (set.indexOf(":") > 0) { + var split = set.split(":"); + var text = split[0]; + + if (split[1].indexOf(",") > 0) { // we currently only use sets that have more than just a text + var splitvals = split[1].split(","); + + var subfieldset = Ext.create('Ext.form.FieldSet', { + title: text, + name: 'subcontrolfieldset' + }); + controlfieldset.add(subfieldset); + controlfieldset.setVisible(true); + + if (splitvals.length > 3) { //make a dropdown + + var dataset = []; + Ext.each(splitvals, function(val) { + var entry = { + 'name':val + }; + dataset.push(entry); + }); + + var comboStore = Ext.create('Ext.data.Store', { + fields: ['name'], + data : dataset + }); + + var current; + Ext.each(results.READINGS, function(reading) { + Ext.iterate(reading, function(k,v) { + if (k === text) { + current = v; + } + }); + }); + + var combo = Ext.create('Ext.form.ComboBox', { + store: comboStore, + queryMode: 'local', + displayField: 'name', + valueField: 'name', + value: current, + listeners: { + select: function(combo, records) { + var value = records[0].data.name; + me.sendCommand(text, value); + } + } + }); + subfieldset.add(combo); + + } else { // give some buttons + + Ext.each(splitvals, function(val) { + + var pressed = false; + Ext.each(results.READINGS, function(reading) { + Ext.iterate(reading, function(k,v) { + if (k === text && v === val || k === text && val === "0" && v === "null") { + pressed = true; + } + }); + }); + + var control = Ext.create('Ext.button.Button', { + text: val, + width: 120, + enableToggle: true, + pressed: pressed, + listeners: { + click: function(btn) { + var command = text, + value = btn.text; + me.sendCommand(command, value); + } + } + }); + subfieldset.add(control); + }); + } + } + } }); - var devicedatagrid = { - xtype: 'grid', - title: 'Device Data', - //hideHeaders: true, - columns: [ - { - header: 'KEY', - dataIndex: 'key', - width: '49%' - }, - { - header: 'VALUE', - dataIndex: 'value', - width: '49%' - } - ], - store: devicedatastore - }; - me.down('panel[name=container]').add(devicedatagrid); - } - - var readingcollection = me.record.raw.data.READINGS; - if (readingcollection && !Ext.isEmpty(readingcollection) && readingcollection.length > 0) { - - var readingsdata = []; - Ext.each(readingcollection, function(readings) { - Ext.each(readings, function(reading) { - Ext.iterate(reading, function(key, value) { - - if (key !== "measured") { - var obj = { - key: key, - value: value, - measured: '' - }; - readingsdata.push(obj); - } else { - // as the measured time belongs to the last dataset, we merge it.. - readingsdata[readingsdata.length - 1].measured = value; - } - + } else { // we already have controls added, just checkin the state if everything is up2date + Ext.each(controlfieldset.items.items, function(subfieldset) { + + Ext.each(subfieldset.items.items, function(item) { + + var xtype = item.getXType(), + current; + + Ext.each(results.READINGS, function(reading) { + Ext.iterate(reading, function(k,v) { + if (k === subfieldset.title) { + current = v; + } + }); }); + + if (xtype === "combobox") { + item.setValue(current); + } else if (xtype === "button") { + if (item.text === current || item.text === "0" && current === "null") { + item.toggle(true); + } else { + item.toggle(false); + } + } }); }); - - var devicereadingsstore = Ext.create('Ext.data.Store', { - fields: ['key', 'value', 'measured'], - data: readingsdata, - proxy: { - type: 'memory', - reader: { - type: 'json' - } - } - }); - var devicereadingsgrid = { - xtype: 'grid', - title: 'Device Readings', - columns: [ - { - header: 'KEY', - dataIndex: 'key', - width: '33%' - }, - { - header: 'VALUE', - dataIndex: 'value', - width: '33%' - }, - { - header: 'MEASURED', - dataIndex: 'measured', - width: '33%' - } - ], - store: devicereadingsstore - }; - me.down('panel[name=container]').add(devicereadingsgrid); } + }, + + /** + * + */ + processReadings: function(readings) { + + var me = this, + devicedata = [], + devicegrid = me.down('panel[name=container] grid[name=devicedata]'), + devicestore = devicegrid.getStore(), + readingsgrid = me.down('panel[name=container] grid[name=readingsgrid]'), + readingsstore = readingsgrid.getStore(); + + Ext.iterate(readings, function(key, value) { + if (key !== 'ATTR' && key !== 'attrs' && + key !== 'ATTRIBUTES' && key !== 'sets' && + key !== 'READINGS' && key !== 'CHANGETIME') { + + if (typeof value === "object") { + Ext.iterate(value, function(k, v) { + var obj = { + key: k, + value: v + }; + devicedata.push(obj); + }); + + } else { + var obj = { + key: key, + value: value + }; + devicedata.push(obj); + } + } + }); + + devicestore.loadData(devicedata); + + var readingcollection = readings.READINGS, + readingsdata = []; + + Ext.each(readingcollection, function(readings) { + Ext.each(readings, function(reading) { + Ext.iterate(reading, function(key, value) { + + var obj; + if (typeof value === "object") { + obj = { + key: key, + value: value.VAL, + measured: value.TIME + }; + readingsdata.push(obj); + + } else if (key !== "measured") { + obj = { + key: key, + value: value, + measured: '' + }; + readingsdata.push(obj); + } else { + // as the measured time belongs to the last dataset, we merge it.. + readingsdata[readingsdata.length - 1].measured = value; + } + + }); + }); + }); + + readingsstore.loadData(readingsdata); + }, + + /** + * + */ + getDeviceData: function(name) { + var me = this; + + Ext.Ajax.request({ + method: 'GET', + disableCaching: false, + url: '../../../fhem?cmd=jsonlist&XHR=1', + scope: me, + success: function(response){ + me.setLoading(false); + + var json = Ext.decode(response.responseText); + + var devicejson; + Ext.each(json.Results, function(result) { + Ext.each(result.devices, function(device) { + if (device.NAME === name) { + devicejson = device; + } + }); + }); + if (devicejson && devicejson !== "") { + me.updateControls(devicejson); + me.processReadings(devicejson); + } else { + Ext.Msg.alert("Error", "Could not get any devicedata!"); + Ext.TaskManager.stopAll(); + } + + + }, + failure: function() { + me.setLoading(false); + Ext.Msg.alert("Error", "Could not get any devicedata!"); + Ext.TaskManager.stopAll(); + } + }); } - }); diff --git a/fhem/www/frontend/www/frontend/app/view/Viewport.js b/fhem/www/frontend/www/frontend/app/view/Viewport.js index a429093d1..4c72d50db 100644 --- a/fhem/www/frontend/www/frontend/app/view/Viewport.js +++ b/fhem/www/frontend/www/frontend/app/view/Viewport.js @@ -165,19 +165,28 @@ Ext.define('FHEM.view.Viewport', { split: true, height: 50, minHeight: 30 - }, - { - xtype: 'linechartpanel', - name: 'linechartpanel', - region: 'center', - layout: 'fit' }, { - xtype: 'tabledatagridpanel', - name: 'tabledatagridpanel', - hidden: true, + xtype: 'panel', region: 'center', - layout: 'fit' + title: 'Welcome', + layout: 'hbox', + bodyStyle: 'padding:5px 5px 0', + items: [ + { + xtype: 'image', + src: '../../fhem/images/default/fhemicon.png', + height: 132, + width: 120 + }, + { + xtype: 'text', + name: 'statustextfield', + padding: '50 0 0 20', + html: '
Welcome to the new FHEM Frontend.
For Informations, Problems and discussion, visit the FHEM Forums' + } + ], + height: '100%' } ] });