luci-mod-status: ES6 treatment, hide disabled radios and SSIDs
authorPaul Donald <[email protected]>
Sun, 9 Nov 2025 14:04:14 +0000 (15:04 +0100)
committerPaul Donald <[email protected]>
Sun, 9 Nov 2025 14:41:51 +0000 (15:41 +0100)
This reduces the amount of data polled for inactive entities.

Signed-off-by: Paul Donald <[email protected]>
modules/luci-mod-status/htdocs/luci-static/resources/view/status/wireless.js

index f5b3404382f44882a5bdbff6ed53747e64b78580..401ae104e2d1ecef0bc6c66fb25f8b1f0320d8f7 100644 (file)
@@ -6,81 +6,85 @@
 'require rpc';
 'require network';
 
-var callLuciRealtimeStats = rpc.declare({
+const callLuciRealtimeStats = rpc.declare({
        object: 'luci',
        method: 'getRealtimeStats',
        params: [ 'mode', 'device' ],
        expect: { result: [] }
 });
 
-var graphPolls = [],
-    pollInterval = 3;
+const graphPolls = [], pollInterval = 3;
 
 Math.log2 = Math.log2 || function(x) { return Math.log(x) * Math.LOG2E; };
 
 return view.extend({
-       load: function() {
+       load() {
                return Promise.all([
                        this.loadSVG(L.resource('svg/wireless.svg')),
                        this.loadSVG(L.resource('svg/wifirate.svg')),
-                       network.getWifiDevices().then(function(radios) {
-                               var tasks = [], all_networks = [];
-
-                               for (var i = 0; i < radios.length; i++)
-                                       tasks.push(radios[i].getWifiNetworks().then(function(networks) {
-                                               all_networks.push.apply(all_networks, networks);
+                       network.getWifiDevices().then((radios) => {
+                               const tasks = [], all_networks = [];
+
+                               for (const radio of radios) {
+                                       if (radio.isDisabled()) continue;
+                                       tasks.push(radio.getWifiNetworks().then((networks) => {
+                                               for (const net of networks) {
+                                                       if (net.isDisabled()) continue;
+                                                       all_networks.push(net);
+                                               }
                                        }));
+                               }
 
-                               return Promise.all(tasks).then(function() {
+                               return Promise.all(tasks).then(() => {
                                        return all_networks;
                                });
                        })
                ]);
        },
 
-       updateGraph: function(ifname, svg, lines, cb) {
-               var G = svg.firstElementChild;
+       updateGraph(ifname, svg, lines, cb) {
+               const G = svg.firstElementChild;
 
-               var view = document.querySelector('#view');
+               const view = document.querySelector('#view');
 
-               var width  = view.offsetWidth - 2;
-               var height = 300 - 2;
-               var step   = 5;
+               const width  = view.offsetWidth - 2;
+               const height = 300 - 2;
+               const step   = 5;
 
-               var data_wanted = Math.floor(width / step);
+               const data_wanted = Math.floor(width / step);
 
-               var data_values = [],
+               const data_values = [],
                    line_elements = [];
 
-               for (var i = 0; i < lines.length; i++)
-                       if (lines[i] != null)
+               for (const line of lines)
+                       if (line)
                                data_values.push([]);
 
-               var info = {
+               const info = {
                        line_current: [],
                        line_average: [],
                        line_peak:    []
                };
 
                /* prefill datasets */
-               for (var i = 0; i < data_values.length; i++)
-                       for (var j = 0; j < data_wanted; j++)
+               for (let i = 0; i < data_values.length; i++)
+                       for (let j = 0; j < data_wanted; j++)
                                        data_values[i][j] = 0;
 
                /* plot horizontal time interval lines */
-               for (var i = width % (step * 60); i < width; i += step * 60) {
-                       var line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
-                               line.setAttribute('x1', i);
-                               line.setAttribute('y1', 0);
-                               line.setAttribute('x2', i);
-                               line.setAttribute('y2', '100%');
-                               line.setAttribute('style', 'stroke:black;stroke-width:0.1');
-
-                       var text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
-                               text.setAttribute('x', i + 5);
-                               text.setAttribute('y', 15);
-                               text.setAttribute('style', 'fill:#eee; font-size:9pt; font-family:sans-serif; text-shadow:1px 1px 1px #000');
-                               text.appendChild(document.createTextNode(Math.round((width - i) / step / 60) + 'm'));
+               for (let i = width % (step * 60); i < width; i += step * 60) {
+                       const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
+                       line.setAttribute('x1', i);
+                       line.setAttribute('y1', 0);
+                       line.setAttribute('x2', i);
+                       line.setAttribute('y2', '100%');
+                       line.setAttribute('style', 'stroke:black;stroke-width:0.1');
+
+                       const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
+                       text.setAttribute('x', i + 5);
+                       text.setAttribute('y', 15);
+                       text.setAttribute('style', 'fill:#eee; font-size:9pt; font-family:sans-serif; text-shadow:1px 1px 1px #000');
+                       text.appendChild(document.createTextNode(Math.round((width - i) / step / 60) + 'm'));
 
                        G.appendChild(line);
                        G.appendChild(text);
@@ -104,35 +108,34 @@ return view.extend({
                });
        },
 
-       pollData: function() {
+       pollData() {
                poll.add(L.bind(function() {
-                       var tasks = [];
+                       const tasks = [];
 
-                       for (var i = 0; i < graphPolls.length; i++) {
-                               var ctx = graphPolls[i];
+                       for (const ctx of graphPolls) {
                                tasks.push(L.resolveDefault(callLuciRealtimeStats('wireless', ctx.ifname), []));
                        }
 
                        return Promise.all(tasks).then(L.bind(function(datasets) {
-                               for (var gi = 0; gi < graphPolls.length; gi++) {
-                                       var ctx = graphPolls[gi],
-                                           data = datasets[gi],
-                                           values = ctx.values,
-                                           lines = ctx.lines,
-                                           info = ctx.info;
-
-                                       var data_scale = 0;
-                                       var data_wanted = Math.floor(ctx.width / ctx.step);
-                                       var last_timestamp = NaN;
-
-                                       for (var i = 0, di = 0; di < lines.length; di++) {
+                               for (let gi = 0; gi < graphPolls.length; gi++) {
+                                       const ctx = graphPolls[gi];
+                                       const data = datasets[gi];
+                                       const values = ctx.values;
+                                       const lines = ctx.lines;
+                                       const info = ctx.info;
+
+                                       let data_scale = 0;
+                                       const data_wanted = Math.floor(ctx.width / ctx.step);
+                                       let last_timestamp = NaN;
+
+                                       for (let i = 0, di = 0; di < lines.length; di++) {
                                                if (lines[di] == null)
                                                        continue;
 
-                                               var multiply = (lines[di].multiply != null) ? lines[di].multiply : 1,
-                                                   offset = (lines[di].offset != null) ? lines[di].offset : 0;
+                                               const multiply = (lines[di].multiply != null) ? lines[di].multiply : 1;
+                                               const offset = (lines[di].offset != null) ? lines[di].offset : 0;
 
-                                               for (var j = ctx.timestamp ? 0 : 1; j < data.length; j++) {
+                                               for (let j = ctx.timestamp ? 0 : 1; j < data.length; j++) {
                                                        /* skip overlapping entries */
                                                        if (data[j][0] <= ctx.timestamp)
                                                                continue;
@@ -153,15 +156,15 @@ return view.extend({
                                        /* cut off outdated entries */
                                        ctx.fill = Math.min(ctx.fill, data_wanted);
 
-                                       for (var i = 0; i < values.length; i++) {
-                                               var len = values[i].length;
+                                       for (let i = 0; i < values.length; i++) {
+                                               const len = values[i].length;
                                                values[i] = values[i].slice(len - data_wanted, len);
 
                                                /* find peaks, averages */
                                                info.line_peak[i] = NaN;
                                                info.line_average[i] = 0;
 
-                                               for (var j = 0; j < values[i].length; j++) {
+                                               for (let j = 0; j < values[i].length; j++) {
                                                        info.line_peak[i] = isNaN(info.line_peak[i]) ? values[i][j] : Math.max(info.line_peak[i], values[i][j]);
                                                        info.line_average[i] += values[i][j];
                                                }
@@ -175,39 +178,39 @@ return view.extend({
                                        if (!isNaN(last_timestamp))
                                                ctx.timestamp = last_timestamp;
 
-                                       var size = Math.floor(Math.log2(info.peak)),
-                                           div = Math.pow(2, size - (size % 10)),
-                                           mult = info.peak / div,
-                                           mult = (mult < 5) ? 2 : ((mult < 50) ? 10 : ((mult < 500) ? 100 : 1000));
+                                       const size = Math.floor(Math.log2(info.peak));
+                                       const div = Math.pow(2, size - (size % 10));
+                                       const p_o_d = info.peak / div;
+                                       const mult = (p_o_d < 5) ? 2 : ((p_o_d < 50) ? 10 : ((p_o_d < 500) ? 100 : 1000));
 
                                        info.peak = info.peak + (mult * div) - (info.peak % (mult * div));
 
                                        data_scale = ctx.height / info.peak;
 
                                        /* plot data */
-                                       for (var i = 0, di = 0; di < lines.length; di++) {
+                                       for (let i = 0, di = 0; di < lines.length; di++) {
                                                if (lines[di] == null)
                                                        continue;
 
-                                               var el = ctx.svg.firstElementChild.getElementById(lines[di].line),
-                                                   pt = '0,' + ctx.height,
-                                                   y = 0;
+                                               const el = ctx.svg.firstElementChild.getElementById(lines[di].line);
+                                               let pt = `0,${ctx.height}`;
+                                               let y = 0;
 
                                                if (!el)
                                                        continue;
 
-                                               for (var j = 0; j < values[i].length; j++) {
-                                                       var x = j * ctx.step;
+                                               for (let j = 0; j < values[i].length; j++) {
+                                                       const x = j * ctx.step;
 
                                                        y = ctx.height - Math.floor(values[i][j] * data_scale);
                                                        //y -= Math.floor(y % (1 / data_scale));
 
                                                        y = isNaN(y) ? ctx.height : y;
 
-                                                       pt += ' ' + x + ',' + y;
+                                                       pt += ` ${x},${y}`;
                                                }
 
-                                               pt += ' ' + ctx.width + ',' + y + ' ' + ctx.width + ',' + ctx.height;
+                                               pt += ` ${ctx.width},${y} ${ctx.width},${ctx.height}`;
 
                                                el.setAttribute('points', pt);
 
@@ -225,7 +228,7 @@ return view.extend({
                }, this), pollInterval);
        },
 
-       loadSVG: function(src) {
+       loadSVG(src) {
                return request.get(src).then(function(response) {
                        if (!response.ok)
                                throw new Error(response.statusText);
@@ -236,23 +239,21 @@ return view.extend({
                });
        },
 
-       render: function(data) {
-               var svg1 = data[0],
-                   svg2 = data[1],
-                   wifidevs = data[2];
+       render([svg1, svg2, wifidevs]) {
 
-               var v = E('div', { 'class': 'cbi-map', 'id': 'map' }, E('div'));
+               const v = E('div', { 'class': 'cbi-map', 'id': 'map' }, E('div'));
 
-               for (var i = 0; i < wifidevs.length; i++) {
-                       var ifname = wifidevs[i].getIfname();
+               for (const wifidev of wifidevs) {
+                       const ifname = wifidev.getIfname();
+                       const ssid = wifidev.getSSID();
 
                        if (!ifname)
                                continue;
 
-                       var csvg1 = svg1.cloneNode(true),
-                           csvg2 = svg2.cloneNode(true);
+                       const csvg1 = svg1.cloneNode(true);
+                       const csvg2 = svg2.cloneNode(true);
 
-                       v.firstElementChild.appendChild(E('div', { 'class': 'cbi-section', 'data-tab': ifname, 'data-tab-title': ifname }, [
+                       v.firstElementChild.appendChild(E('div', { 'class': 'cbi-section', 'data-tab': ifname, 'data-tab-title': `${ifname} ${ssid}` }, [
                                csvg1,
                                E('div', { 'class': 'right' }, E('small', { 'id': 'scale' }, '-')),
                                E('br'),