mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-08 13:24:56 +00:00
577 lines
19 KiB
JavaScript
577 lines
19 KiB
JavaScript
/**
|
|
* The Main Controller handling Main Application Logic
|
|
*/
|
|
Ext.define('FHEM.controller.MainController', {
|
|
extend: 'Ext.app.Controller',
|
|
requires: [
|
|
'FHEM.view.DevicePanel'
|
|
],
|
|
|
|
refs: [
|
|
{
|
|
selector: 'viewport[name=mainviewport]',
|
|
ref: 'mainviewport' //this.getMainviewport()
|
|
},
|
|
{
|
|
selector: 'text[name=statustextfield]',
|
|
ref: 'statustextfield' //this.getStatustextfield()
|
|
},
|
|
{
|
|
selector: 'panel[name=westaccordionpanel]',
|
|
ref: 'westaccordionpanel' //this.getWestaccordionpanel()
|
|
},
|
|
{
|
|
selector: 'panel[name=maintreepanel]',
|
|
ref: 'maintreepanel' //this.getMaintreepanel()
|
|
},
|
|
{
|
|
selector: 'textfield[name=commandfield]',
|
|
ref: 'commandfield' //this.getCommandfield()
|
|
}
|
|
],
|
|
|
|
/**
|
|
* init function to register listeners
|
|
*/
|
|
init: function() {
|
|
this.control({
|
|
'viewport[name=mainviewport]': {
|
|
afterrender: this.viewportRendered
|
|
},
|
|
'panel[name=fhemaccordion]': {
|
|
expand: this.showFHEMPanel
|
|
},
|
|
'panel[name=tabledataaccordionpanel]': {
|
|
expand: this.showDatabaseTablePanel
|
|
},
|
|
'treepanel[name=maintreepanel]': {
|
|
itemclick: this.showDeviceOrChartPanel,
|
|
treeupdated: this.setupTree
|
|
},
|
|
'textfield[name=commandfield]': {
|
|
specialkey: this.checkCommand
|
|
},
|
|
'button[name=saveconfig]': {
|
|
click: this.saveConfig
|
|
},
|
|
'button[name=executecommand]': {
|
|
click: this.submitCommand
|
|
},
|
|
'button[name=shutdownfhem]': {
|
|
click: this.shutdownFhem
|
|
},
|
|
'button[name=restartfhem]': {
|
|
click: this.restartFhem
|
|
},
|
|
'button[name=unsortedtree]': {
|
|
click: this.setupTree
|
|
},
|
|
'button[name=sortedtree]': {
|
|
click: this.setupTree
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* fade-in viewport, load the FHEM devices and state on viewport render completion
|
|
*/
|
|
viewportRendered: function() {
|
|
|
|
var me = this;
|
|
|
|
me.createFHEMPanel();
|
|
me.createDevicePanel();
|
|
me.createLineChartPanel();
|
|
me.createDatabaseTablePanel();
|
|
|
|
me.getMainviewport().show();
|
|
me.getMainviewport().getEl().setOpacity(0);
|
|
me.getMainviewport().getEl().animate({
|
|
opacity: 1,
|
|
easing: 'easeIn',
|
|
duration: 500,
|
|
remove: false
|
|
});
|
|
|
|
if (Ext.isDefined(FHEM.version)) {
|
|
var sp = this.getStatustextfield();
|
|
sp.setText(FHEM.version + "; Frontend Version: 1.0.4 - 2013-12-27");
|
|
}
|
|
|
|
this.setupTree(false);
|
|
},
|
|
|
|
/**
|
|
* setup west accordion / treepanel
|
|
*/
|
|
setupTree: function(unsorted) {
|
|
var me = this,
|
|
rootNode = { text:"root", expanded: true, children: []},
|
|
oldRootNode = me.getMaintreepanel().getRootNode();
|
|
|
|
//first cleanup
|
|
if (oldRootNode) {
|
|
oldRootNode.removeAll();
|
|
}
|
|
if (unsorted && unsorted.name === 'unsortedtree') {
|
|
//setup the tree "unsorted"
|
|
Ext.each(FHEM.info.Results, function(result) {
|
|
if (result.list && !Ext.isEmpty(result.list)) {
|
|
if (result.devices && result.devices.length > 0) {
|
|
var blacklist = ['dummy', 'notify', 'Global', 'telnet', 'DbLog', 'FileLog', 'FHEMWEB', 'weblink'];
|
|
if (Ext.Array.contains(blacklist, result.list)) {
|
|
node = {text: result.list, expanded: false, children: []};
|
|
} else {
|
|
node = {text: result.list, expanded: true, children: []};
|
|
}
|
|
Ext.each(result.devices, function(device) {
|
|
var subnode = {text: device.NAME, leaf: true, data: device};
|
|
node.children.push(subnode);
|
|
}, this);
|
|
} else {
|
|
node = {text: result.list, leaf: true};
|
|
}
|
|
rootNode.children.push(node);
|
|
}
|
|
});
|
|
this.getMaintreepanel().setRootNode(rootNode);
|
|
this.addChartsToTree();
|
|
} else {
|
|
//sort / create items by room
|
|
me.getMaintreepanel().setRootNode(rootNode);
|
|
var root = me.getMaintreepanel().getRootNode();
|
|
Ext.each(FHEM.info.Results, function(result) {
|
|
if (result.list && !Ext.isEmpty(result.list)) {
|
|
if (result.devices && result.devices.length > 0) {
|
|
Ext.each(result.devices, function(device) {
|
|
if (device.ATTR && device.ATTR.room) {
|
|
//first we check if we have comma separated multiple rooms
|
|
var roomArray = device.ATTR.room.split(",");
|
|
Ext.each(roomArray, function(room) {
|
|
//check if room exists
|
|
var resultnode = root.findChild("text", room, true),
|
|
subnode = {text: device.NAME, leaf: true, data: device};
|
|
if (!resultnode) {
|
|
//create roomfolder
|
|
var roomfolder;
|
|
if (room !== "hidden") {
|
|
if (room === "Unsorted") {
|
|
roomfolder = {text: room, leaf: false, expanded: false, children: []};
|
|
} else {
|
|
roomfolder = {text: room, leaf: false, expanded: true, children: []};
|
|
}
|
|
roomfolder.children.push(subnode);
|
|
root.appendChild(roomfolder);
|
|
}
|
|
} else {
|
|
resultnode.appendChild(subnode);
|
|
root.appendChild(resultnode);
|
|
}
|
|
});
|
|
}
|
|
}, this);
|
|
} else {
|
|
node = {text: result.list, leaf: true};
|
|
root.appendChild(node);
|
|
}
|
|
}
|
|
});
|
|
this.addChartsToTree();
|
|
}
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
addChartsToTree: function() {
|
|
//load the saved charts store with configured dblog name
|
|
var me = this,
|
|
store = Ext.create('FHEM.store.SavedChartsStore', {});
|
|
store.getProxy().url = '../../../fhem?cmd=get+' + FHEM.dblogname + '+-+webchart+""+""+""+getcharts&XHR=1';
|
|
store.load();
|
|
//add the charts to the tree
|
|
store.on("load", function() {
|
|
var rootNode = me.getMaintreepanel().getRootNode(),
|
|
chartfolder = {text: "Charts", expanded: true, children: []};
|
|
rootNode.appendChild(chartfolder);
|
|
var chartfoldernode = rootNode.findChild("text", "Charts", true);
|
|
|
|
//add the filelogcharts to the store
|
|
if (FHEM.filelogcharts) {
|
|
store.add(FHEM.filelogcharts);
|
|
}
|
|
|
|
store.each(function(rec) {
|
|
var chartchild,
|
|
unsortedMode = Ext.ComponentQuery.query('button[name=unsortedtree]')[0].pressed;
|
|
|
|
if (!unsortedMode && rec.raw && rec.raw.VALUE && rec.raw.VALUE.parentFolder) {
|
|
var ownerFolder = rec.raw.VALUE.parentFolder,
|
|
index = rec.raw.VALUE.treeIndex,
|
|
parentNode = rootNode.findChild("text", ownerFolder, true);
|
|
|
|
chartchild = {text: rec.raw.NAME, leaf: true, data: rec.raw, iconCls:'x-tree-icon-leaf-chart'};
|
|
if (parentNode === null) {
|
|
rootNode.insertChild(index, chartchild);
|
|
} else {
|
|
parentNode.insertChild(index, chartchild);
|
|
}
|
|
} else {
|
|
chartchild = {text: rec.raw.NAME, leaf: true, data: rec.raw, iconCls:'x-tree-icon-leaf-chart'};
|
|
chartfoldernode.appendChild(chartchild);
|
|
}
|
|
});
|
|
|
|
// at last we add a chart template to the folder which wont be saved to db and cannot be deleted
|
|
chartchild = {text: 'Create new Chart', leaf: true, data: {template: true}, iconCls:'x-tree-icon-leaf-chart'};
|
|
chartfoldernode.appendChild(chartchild);
|
|
|
|
});
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
saveConfig: function() {
|
|
|
|
var command = this.getCommandfield().getValue();
|
|
if (command && !Ext.isEmpty(command)) {
|
|
this.submitCommand();
|
|
}
|
|
|
|
Ext.Ajax.request({
|
|
method: 'GET',
|
|
disableCaching: false,
|
|
url: '../../../fhem?cmd=save',
|
|
success: function(response){
|
|
|
|
var win = Ext.create('Ext.window.Window', {
|
|
width: 110,
|
|
height: 60,
|
|
html: 'Save successful!',
|
|
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();
|
|
}
|
|
}
|
|
});
|
|
},
|
|
failure: function() {
|
|
Ext.Msg.alert("Error", "Could not save the current configuration!");
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
checkCommand: function(field, e) {
|
|
if (e.getKey() == e.ENTER && !Ext.isEmpty(field.getValue())) {
|
|
this.submitCommand();
|
|
}
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
submitCommand: function() {
|
|
|
|
var command = this.getCommandfield().getValue();
|
|
|
|
if (command && !Ext.isEmpty(command)) {
|
|
Ext.Ajax.request({
|
|
method: 'GET',
|
|
disableCaching: false,
|
|
url: '../../../fhem?cmd=' + command + '&XHR=1',
|
|
success: function(response){
|
|
|
|
if(response.responseText && !Ext.isEmpty(response.responseText)) {
|
|
Ext.create('Ext.window.Window', {
|
|
maxWidth: 600,
|
|
maxHeight: 500,
|
|
autoScroll: true,
|
|
layout: 'fit',
|
|
title: "Response",
|
|
items: [
|
|
{
|
|
xtype: 'panel',
|
|
autoScroll: true,
|
|
items:[
|
|
{
|
|
xtype: 'displayfield',
|
|
htmlEncode: true,
|
|
value: response.responseText
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}).show();
|
|
} else {
|
|
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();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
},
|
|
failure: function() {
|
|
Ext.Msg.alert("Error", "Could not submit the command!");
|
|
}
|
|
});
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
shutdownFhem: function() {
|
|
Ext.Ajax.request({
|
|
method: 'GET',
|
|
disableCaching: false,
|
|
url: '../../../fhem?cmd=shutdown&XHR=1'
|
|
});
|
|
var win = Ext.create('Ext.window.Window', {
|
|
width: 130,
|
|
height: 60,
|
|
html: 'Shutdown 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();
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
restartFhem: function() {
|
|
Ext.Ajax.request({
|
|
method: 'GET',
|
|
disableCaching: false,
|
|
url: '../../../fhem?cmd=shutdown restart&XHR=1'
|
|
});
|
|
Ext.getBody().mask("Please wait while FHEM is restarting...");
|
|
this.retryConnect();
|
|
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
retryConnect: function() {
|
|
var me = this;
|
|
|
|
var task = new Ext.util.DelayedTask(function(){
|
|
Ext.Ajax.request({
|
|
method: 'GET',
|
|
disableCaching: false,
|
|
url: '../../../fhem?cmd=jsonlist&XHR=1',
|
|
|
|
success: function(response){
|
|
if (response.responseText !== "Unknown command JsonList, try help↵") {
|
|
//restarting the frontend
|
|
window.location.reload();
|
|
} else {
|
|
me.retryConnect();
|
|
}
|
|
|
|
},
|
|
failure: function() {
|
|
me.retryConnect();
|
|
}
|
|
});
|
|
});
|
|
|
|
task.delay(1000);
|
|
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
hideCenterPanels: function() {
|
|
var panels = Ext.ComponentQuery.query('panel[region=center]');
|
|
Ext.each(panels, function(panel) {
|
|
panel.hide();
|
|
});
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
showDeviceOrChartPanel: function(treeview, rec) {
|
|
var me = this;
|
|
if (rec.raw.data.template === true || rec.get('leaf') === true &&
|
|
rec.raw.data &&
|
|
rec.raw.data.TYPE &&
|
|
(rec.raw.data.TYPE === "savedchart" || rec.raw.data.TYPE === "savedfilelogchart")) {
|
|
this.showLineChartPanel();
|
|
} else {
|
|
this.showDevicePanel(treeview, rec);
|
|
}
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
showFHEMPanel: function() {
|
|
var panel = Ext.ComponentQuery.query('panel[name=fhempanel]')[0];
|
|
this.hideCenterPanels();
|
|
panel.show();
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
createFHEMPanel: function() {
|
|
var panel = {
|
|
xtype: 'panel',
|
|
name: 'fhempanel',
|
|
title: 'FHEM',
|
|
region: 'center',
|
|
layout: 'fit',
|
|
hidden: true,
|
|
items : [
|
|
{
|
|
xtype : 'component',
|
|
autoEl : {
|
|
tag : 'iframe',
|
|
src : '../../fhem?'
|
|
}
|
|
}
|
|
]
|
|
};
|
|
this.getMainviewport().add(panel);
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
showDevicePanel: function(view, record) {
|
|
|
|
if (record.raw.leaf === true) {
|
|
var panel = Ext.ComponentQuery.query('devicepanel')[0];
|
|
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;
|
|
}
|
|
panel.setTitle(title);
|
|
panel.record = record;
|
|
|
|
this.hideCenterPanels();
|
|
panel.show();
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
createDevicePanel: function() {
|
|
var panel = {
|
|
xtype: 'devicepanel',
|
|
title: null,
|
|
region: 'center',
|
|
layout: 'fit',
|
|
record: null,
|
|
hidden: true
|
|
};
|
|
this.getMainviewport().add(panel);
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
showLineChartPanel: function() {
|
|
var panel = Ext.ComponentQuery.query('linechartpanel')[0];
|
|
this.hideCenterPanels();
|
|
panel.show();
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
createLineChartPanel: function() {
|
|
var panel = {
|
|
xtype: 'linechartpanel',
|
|
name: 'linechartpanel',
|
|
region: 'center',
|
|
layout: 'fit',
|
|
hidden: true
|
|
};
|
|
this.getMainviewport().add(panel);
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
createDatabaseTablePanel: function() {
|
|
var panel = {
|
|
xtype: 'tabledatagridpanel',
|
|
name: 'tabledatagridpanel',
|
|
region: 'center',
|
|
layout: 'fit',
|
|
hidden: true
|
|
};
|
|
this.getMainviewport().add(panel);
|
|
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
showDatabaseTablePanel: function() {
|
|
var panel = Ext.ComponentQuery.query('tabledatagridpanel')[0];
|
|
this.hideCenterPanels();
|
|
panel.show();
|
|
}
|
|
|
|
}); |