Merge pull request #3639 from TDT-AG/pr/20200217-leds
authorFlorian Eckert <fe@dev.tdt.de>
Thu, 27 Feb 2020 13:08:57 +0000 (14:08 +0100)
committerGitHub <noreply@github.com>
Thu, 27 Feb 2020 13:08:57 +0000 (14:08 +0100)
luci-mod-system: add led plugin infrastructure

14 files changed:
applications/luci-app-ledtrig-rssi/Makefile [new file with mode: 0644]
applications/luci-app-ledtrig-rssi/htdocs/luci-static/resources/view/system/led-trigger/rssi.js [new file with mode: 0644]
applications/luci-app-ledtrig-switch/Makefile [new file with mode: 0644]
applications/luci-app-ledtrig-switch/htdocs/luci-static/resources/view/system/led-trigger/switch0.js [new file with mode: 0644]
applications/luci-app-ledtrig-switch/htdocs/luci-static/resources/view/system/led-trigger/switch1.js [new file with mode: 0644]
applications/luci-app-ledtrig-usbport/Makefile [new file with mode: 0644]
applications/luci-app-ledtrig-usbport/htdocs/luci-static/resources/view/system/led-trigger/usbport.js [new file with mode: 0644]
modules/luci-mod-system/Makefile
modules/luci-mod-system/htdocs/luci-static/resources/view/system/led-trigger/default-on.js [new file with mode: 0644]
modules/luci-mod-system/htdocs/luci-static/resources/view/system/led-trigger/heartbeat.js [new file with mode: 0644]
modules/luci-mod-system/htdocs/luci-static/resources/view/system/led-trigger/netdev.js [new file with mode: 0644]
modules/luci-mod-system/htdocs/luci-static/resources/view/system/led-trigger/none.js [new file with mode: 0644]
modules/luci-mod-system/htdocs/luci-static/resources/view/system/led-trigger/timer.js [new file with mode: 0644]
modules/luci-mod-system/htdocs/luci-static/resources/view/system/leds.js

diff --git a/applications/luci-app-ledtrig-rssi/Makefile b/applications/luci-app-ledtrig-rssi/Makefile
new file mode 100644 (file)
index 0000000..b3be206
--- /dev/null
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2020 TDT AG <development@tdt.de>
+#
+# This is free software, licensed under the Apache License Version 2.0.
+# See https://www.apache.org/licenses/LICENSE-2.0 for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+LUCI_TITLE:= LuCI Support for ledtrigger rssi
+LUCI_DEPENDS:=+rssileds
+LUCI_PKGARCH:=all
+
+include ../../luci.mk
+
+# call BuildPackage - OpenWrt buildroot signature
diff --git a/applications/luci-app-ledtrig-rssi/htdocs/luci-static/resources/view/system/led-trigger/rssi.js b/applications/luci-app-ledtrig-rssi/htdocs/luci-static/resources/view/system/led-trigger/rssi.js
new file mode 100644 (file)
index 0000000..611adc8
--- /dev/null
@@ -0,0 +1,38 @@
+'use strict';
+'require form';
+'require tools.widgets as widgets';
+
+return L.Class.extend({
+       trigger: _('rssi (service)'),
+       kernel: false,
+       addFormOptions(s){
+               var o;
+
+               o = s.option(widgets.DeviceSelect, '_rssi_iface', _('Device'));
+               o.rmempty = true;
+               o.ucioption = 'iface';
+               o.modalonly = true;
+               o.noaliases = true;
+               o.depends('trigger', 'rssi');
+
+               o = s.option(form.Value, 'minq', _('Minimal quality'));
+               o.rmempty = true;
+               o.modalonly = true;
+               o.depends('trigger', 'rssi');
+
+               o = s.option(form.Value, 'maxq', _('Maximal quality'));
+               o.rmempty = true;
+               o.modalonly = true;
+               o.depends('trigger', 'rssi');
+
+               o = s.option(form.Value, 'offset', _('Value offset'));
+               o.rmempty = true;
+               o.modalonly = true;
+               o.depends('trigger', 'rssi');
+
+               o = s.option(form.Value, 'factor', _('Multiplication factor'));
+               o.rmempty = true;
+               o.modalonly = true;
+               o.depends('trigger', 'rssi');
+       }
+});
diff --git a/applications/luci-app-ledtrig-switch/Makefile b/applications/luci-app-ledtrig-switch/Makefile
new file mode 100644 (file)
index 0000000..7cefc50
--- /dev/null
@@ -0,0 +1,15 @@
+#
+# Copyright (C) 2020 TDT AG <development@tdt.de>
+#
+# This is free software, licensed under the Apache License Version 2.0.
+# See https://www.apache.org/licenses/LICENSE-2.0 for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+LUCI_TITLE:= LuCI Support for ledtrigger switch
+LUCI_PKGARCH:=all
+
+include ../../luci.mk
+
+# call BuildPackage - OpenWrt buildroot signature
diff --git a/applications/luci-app-ledtrig-switch/htdocs/luci-static/resources/view/system/led-trigger/switch0.js b/applications/luci-app-ledtrig-switch/htdocs/luci-static/resources/view/system/led-trigger/switch0.js
new file mode 100644 (file)
index 0000000..2f59866
--- /dev/null
@@ -0,0 +1,18 @@
+'use strict';
+'require form';
+
+return L.Class.extend({
+       trigger: _('switch0 (kernel)'),
+       kernel: true,
+       addFormOptions(s){
+               var o;
+
+               o = s.option(form.Value, 'port_mask', _('Switch Port Mask'));
+               o.modalonly = true;
+               o.depends('trigger', 'switch0');
+
+               o = s.option(form.Value, 'speed_mask', _('Switch Speed Mask'));
+               o.modalonly = true;
+               o.depends('trigger', 'switch0');
+       }
+});
diff --git a/applications/luci-app-ledtrig-switch/htdocs/luci-static/resources/view/system/led-trigger/switch1.js b/applications/luci-app-ledtrig-switch/htdocs/luci-static/resources/view/system/led-trigger/switch1.js
new file mode 100644 (file)
index 0000000..7800cba
--- /dev/null
@@ -0,0 +1,18 @@
+'use strict';
+'require form';
+
+return L.Class.extend({
+       trigger: _('switch1 (kernel)'),
+       kernel: true,
+       addFormOptions(s){
+               var o;
+
+               o = s.option(form.Value, 'port_mask', _('Switch Port Mask'));
+               o.modalonly = true;
+               o.depends('trigger', 'switch1');
+
+               o = s.option(form.Value, 'speed_mask', _('Switch Speed Mask'));
+               o.modalonly = true;
+               o.depends('trigger', 'switch1');
+       }
+});
diff --git a/applications/luci-app-ledtrig-usbport/Makefile b/applications/luci-app-ledtrig-usbport/Makefile
new file mode 100644 (file)
index 0000000..1a17667
--- /dev/null
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2020 TDT AG <development@tdt.de>
+#
+# This is free software, licensed under the Apache License Version 2.0.
+# See https://www.apache.org/licenses/LICENSE-2.0 for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+LUCI_TITLE:= LuCI Support for ledtrigger usbport
+LUCI_DEPENDS:=+kmod-usb-ledtrig-usbport
+LUCI_PKGARCH:=all
+
+include ../../luci.mk
+
+# call BuildPackage - OpenWrt buildroot signature
diff --git a/applications/luci-app-ledtrig-usbport/htdocs/luci-static/resources/view/system/led-trigger/usbport.js b/applications/luci-app-ledtrig-usbport/htdocs/luci-static/resources/view/system/led-trigger/usbport.js
new file mode 100644 (file)
index 0000000..970016c
--- /dev/null
@@ -0,0 +1,46 @@
+'use strict';
+'require rpc';
+'require uci';
+'require form';
+
+var callUSB = rpc.declare({
+       object: 'luci',
+       method: 'getUSBDevices',
+       expect: { 'ports': [] }
+});
+
+return L.Class.extend({
+       trigger: _('usbport (kernel)'),
+       kernel: true,
+       addFormOptions(s){
+               var o;
+
+               o = s.option(form.Value, 'port', _('USB Ports'));
+               o.depends('trigger', 'usbport');
+               o.rmempty = true;
+               o.modalonly = true;
+               o.load = function(s) {
+                       return Promise.all([
+                               callUSB()
+                       ]).then(L.bind(function(usbport){
+                               for (var i = 0; i < usbport[0].length; i++)
+                                       o.value(usbport[0][i].port, _('Port %s').format(usbport[0][i].port));
+                       },this));
+               };
+               o.cfgvalue = function(section_id) {
+                       var ports = [],
+                               value = uci.get('system', section_id, 'port');
+
+                       if (!Array.isArray(value))
+                               value = String(value || '').split(/\s+/);
+
+                       for (var i = 0; i < value.length; i++)
+                               if (value[i].match(/^(\d+)-(\d+)$/))
+                                       ports.push('usb%d-port%d'.format(Regexp.$1, Regexp.$2));
+                               else
+                                       ports.push(value[i]);
+
+                       return ports;
+               };
+       }
+});
index a6d5a7a456628e8535924358c9584f1fd5e3a318..f0ca7987ed40d437142313f44bbdbd4a519a30c3 100644 (file)
@@ -7,7 +7,11 @@
 include $(TOPDIR)/rules.mk
 
 LUCI_TITLE:=LuCI Administration - Global System Settings
-LUCI_DEPENDS:=+luci-base
+LUCI_DEPENDS:=+luci-base \
+       +kmod-ledtrig-default-on \
+       +kmod-ledtrig-heartbeat \
+       +kmod-ledtrig-netdev \
+       +kmod-ledtrig-timer
 
 PKG_LICENSE:=Apache-2.0
 
diff --git a/modules/luci-mod-system/htdocs/luci-static/resources/view/system/led-trigger/default-on.js b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/led-trigger/default-on.js
new file mode 100644 (file)
index 0000000..6ccc70a
--- /dev/null
@@ -0,0 +1,20 @@
+'use strict';
+'require form';
+
+return L.Class.extend({
+       trigger: _('default-on (kernel)'),
+       kernel: true,
+       addFormOptions(s){
+               var o;
+
+               o = s.option(form.Flag, 'default', _('Default state'));
+               o.rmempty = false;
+               o.depends('trigger', 'default-on');
+               o.textvalue = function(section_id) {
+                       var cval = this.cfgvalue(section_id);
+                       if (cval == null)
+                               cval = this.default;
+                       return (cval == this.enabled) ? _('On') : _('Off');
+               };
+       }
+});
diff --git a/modules/luci-mod-system/htdocs/luci-static/resources/view/system/led-trigger/heartbeat.js b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/led-trigger/heartbeat.js
new file mode 100644 (file)
index 0000000..7495843
--- /dev/null
@@ -0,0 +1,9 @@
+'use strict';
+
+return L.Class.extend({
+       trigger: _('heartbeat (kernel)'),
+       kernel: true,
+       addFormOptions(s){
+               var o;
+       }
+});
diff --git a/modules/luci-mod-system/htdocs/luci-static/resources/view/system/led-trigger/netdev.js b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/led-trigger/netdev.js
new file mode 100644 (file)
index 0000000..dad631b
--- /dev/null
@@ -0,0 +1,26 @@
+'use strict';
+'require form';
+'require tools.widgets as widgets';
+
+return L.Class.extend({
+       trigger: _("netdev (kernel)"),
+       kernel: true,
+       addFormOptions(s){
+               var o;
+
+               o = s.option(widgets.DeviceSelect, '_net_dev', _('Device'));
+               o.rmempty = true;
+               o.ucioption = 'dev';
+               o.modalonly = true;
+               o.noaliases = true;
+               o.depends('trigger', 'netdev');
+
+               o = s.option(form.MultiValue, 'mode', _('Trigger Mode'));
+               o.rmempty = true;
+               o.modalonly = true;
+               o.depends('trigger', 'netdev');
+               o.value('link', _('Link On'));
+               o.value('tx', _('Transmit'));
+               o.value('rx', _('Receive'));
+       }
+});
diff --git a/modules/luci-mod-system/htdocs/luci-static/resources/view/system/led-trigger/none.js b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/led-trigger/none.js
new file mode 100644 (file)
index 0000000..31fed55
--- /dev/null
@@ -0,0 +1,9 @@
+'use strict';
+
+return L.Class.extend({
+       trigger: _('none (kernel)'),
+       kernel: true,
+       addFormOptions(s){
+               var o;
+       }
+});
diff --git a/modules/luci-mod-system/htdocs/luci-static/resources/view/system/led-trigger/timer.js b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/led-trigger/timer.js
new file mode 100644 (file)
index 0000000..23ddd6d
--- /dev/null
@@ -0,0 +1,18 @@
+'use strict';
+'require form';
+
+return L.Class.extend({
+       trigger: _('timer (kernel)'),
+       kernel: true,
+       addFormOptions(s){
+               var o;
+
+               o = s.option(form.Value, 'delayon', _('On-State Delay'));
+               o.modalonly = true;
+               o.depends('trigger', 'timer');
+
+               o = s.option(form.Value, 'delayoff', _('Off-State Delay'));
+               o.modalonly = true;
+               o.depends('trigger', 'timer');
+       }
+});
index edd4a24e0673656f2318cb52b6182208f9676aa4..849ead9528c12f0d0b3c4f1947423f927fac5cfb 100644 (file)
@@ -2,39 +2,56 @@
 'require uci';
 'require rpc';
 'require form';
-'require tools.widgets as widgets';
+'require fs';
 
-var callLeds, callUSB;
-
-callLeds = rpc.declare({
+var callLeds = rpc.declare({
        object: 'luci',
        method: 'getLEDs',
        expect: { '': {} }
 });
 
-callUSB = rpc.declare({
-       object: 'luci',
-       method: 'getUSBDevices',
-       expect: { '': {} }
-});
-
 return L.view.extend({
        load: function() {
                return Promise.all([
                        callLeds(),
-                       callUSB()
-               ]);
+                       L.resolveDefault(fs.list('/www' + L.resource('view/system/led-trigger')), [])
+               ]).then(function(data) {
+                       var plugins = data[1];
+                       var tasks = [];
+
+                       for (var i = 0; i < plugins.length; i++) {
+                               var m = plugins[i].name.match(/^(.+)\.js$/);
+
+                               if (plugins[i].type != 'file' || m == null)
+                                       continue;
+
+                               tasks.push(L.require('view.system.led-trigger.' + m[1]).then(L.bind(function(name){
+                                       return L.resolveDefault(L.require('view.system.led-trigger.' + name)).then(function(form) {
+                                               return {
+                                                       name: name,
+                                                       form: form,
+                                               };
+                                       });
+                               }, this, m[1])));
+                       }
+
+                       return Promise.all(tasks).then(function(plugins) {
+                               var value = {};
+                               value[0] = data[0];
+                               value[1] = plugins;
+                               return value;
+                       });
+               });
        },
 
-       render: function(results) {
-               var leds = results[0],
-                   usb = results[1],
-                   triggers = {},
-                   m, s, o;
+       render: function(data) {
+               var m, s, o, triggers = [];
+               var leds = data[0];
+               var plugins = data[1];
 
                for (var k in leds)
                        for (var i = 0; i < leds[k].triggers.length; i++)
-                               triggers[leds[k].triggers[i]] = true;
+                               triggers[i] = leds[k].triggers[i];
 
                m = new form.Map('system',
                        _('<abbr title="Light Emitting Diode">LED</abbr> Configuration'),
@@ -49,117 +66,28 @@ return L.view.extend({
                s.option(form.Value, 'name', _('Name'));
 
                o = s.option(form.ListValue, 'sysfs', _('<abbr title="Light Emitting Diode">LED</abbr> Name'));
-               Object.keys(leds).sort().forEach(function(name) { o.value(name) });
-
-               o = s.option(form.Flag, 'default', _('Default state'));
-               o.rmempty = false;
-               o.textvalue = function(section_id) {
-                       var cval = this.cfgvalue(section_id);
-
-                       if (cval == null)
-                               cval = this.default;
-
-                       return (cval == this.enabled) ? _('On') : _('Off');
-               };
+               Object.keys(leds).sort().forEach(function(name) {
+                       o.value(name)
+               });
 
                o = s.option(form.ListValue, 'trigger', _('Trigger'));
-               if (usb.devices && usb.devices.length)
-                       triggers['usbdev'] = true;
-               if (usb.ports && usb.ports.length)
-                       triggers['usbport'] = true;
-               Object.keys(triggers).sort().forEach(function(t) { o.value(t, t.replace(/-/g, '')) });
-
-               o = s.option(form.Value, 'delayon', _('On-State Delay'));
-               o.modalonly = true;
-               o.depends('trigger', 'timer');
-
-               o = s.option(form.Value, 'delayoff', _('Off-State Delay'));
-               o.modalonly = true;
-               o.depends('trigger', 'timer');
-
-               o = s.option(widgets.DeviceSelect, '_net_dev', _('Device'));
-               o.rmempty = true;
-               o.ucioption = 'dev';
-               o.modalonly = true;
-               o.noaliases = true;
-               o.depends('trigger', 'netdev');
-               o.remove = function(section_id) {
-                       var topt = this.map.lookupOption('trigger', section_id),
-                           tval = topt ? topt[0].formvalue(section_id) : null;
-
-                       if (tval != 'netdev' && tval != 'usbdev')
-                               uci.unset('system', section_id, 'dev');
-               };
-
-               o = s.option(form.MultiValue, 'mode', _('Trigger Mode'));
-               o.rmempty = true;
-               o.modalonly = true;
-               o.depends('trigger', 'netdev');
-               o.value('link', _('Link On'));
-               o.value('tx', _('Transmit'));
-               o.value('rx', _('Receive'));
-
-               if (usb.devices && usb.devices.length) {
-                       o = s.option(form.ListValue, '_usb_dev', _('USB Device'));
-                       o.depends('trigger', 'usbdev');
-                       o.rmempty = true;
-                       o.ucioption = 'dev';
-                       o.modalonly = true;
-                       o.remove = function(section_id) {
-                               var topt = this.map.lookupOption('trigger', section_id),
-                                   tval = topt ? topt[0].formvalue(section_id) : null;
-
-                               if (tval != 'netdev' && tval != 'usbdev')
-                                       uci.unset('system', section_id, 'dev');
-                       }
-                       o.value('');
-                       usb.devices.forEach(function(usbdev) {
-                               o.value(usbdev.id, '%s (%s - %s)'.format(usbdev.id, usbdev.vendor || '?', usbdev.product || '?'));
-                       });
-               }
-
-               if (usb.ports && usb.ports.length) {
-                       o = s.option(form.MultiValue, 'port', _('USB Ports'));
-                       o.depends('trigger', 'usbport');
-                       o.rmempty = true;
-                       o.modalonly = true;
-                       o.cfgvalue = function(section_id) {
-                               var ports = [],
-                                   value = uci.get('system', section_id, 'port');
-
-                               if (!Array.isArray(value))
-                                       value = String(value || '').split(/\s+/);
-
-                               for (var i = 0; i < value.length; i++)
-                                       if (value[i].match(/^(\d+)-(\d+)$/))
-                                               ports.push('usb%d-port%d'.format(Regexp.$1, Regexp.$2));
-                                       else
-                                               ports.push(value[i]);
-
-                               return ports;
-                       };
-                       usb.ports.forEach(function(usbport) {
-                               var dev = (usbport.device && Array.isArray(usb.devices))
-                                       ? usb.devices.filter(function(d) { return d.id == usbport.device })[0] : null;
-
-                               var label = _('Port %s').format(usbport.port);
-
-                               if (dev)
-                                       label += ' (%s - %s)'.format(dev.vendor || '?', dev.product || '?');
-
-                               o.value(usbport.port, label);
-                       });
+               for (var i = 0; i < plugins.length; i++) {
+                       var plugin = plugins[i];
+
+                       if ( plugin.form.kernel == false )
+                               o.value(plugin.name, plugin.form.trigger);
+                       else
+                               for (var k = 0; k < triggers.length; k++)
+                                       if ( plugin.name == triggers[k] )
+                                               o.value(plugin.name, plugin.form.trigger);
                }
 
-               o = s.option(form.Value, 'port_mask', _('Switch Port Mask'));
-               o.modalonly = true;
-               o.depends('trigger', 'switch0');
-               o.depends('trigger', 'switch1');
-
-               o = s.option(form.Value, 'speed_mask', _('Switch Speed Mask'));
-               o.modalonly = true;
-               o.depends('trigger', 'switch0');
-               o.depends('trigger', 'switch1');
+               s.addModalOptions = function(s) {
+                       for (var i = 0; i < plugins.length; i++) {
+                               var plugin = plugins[i];
+                               plugin.form.addFormOptions(s);
+                       }
+               };
 
                return m.render();
        }