diff options
author | Jo-Philipp Wich <jo@mein.io> | 2019-11-02 22:55:59 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2019-11-03 17:56:58 +0100 |
commit | cfb5af89e108960c33d12cbd6dd76e9aa4e19bee (patch) | |
tree | eff25a43f550318944e8c018b4129f36bc7da8bd /modules/luci-mod-status/luasrc | |
parent | a2f43983b63b2e65aba7dd7f7f2fa22306c12e21 (diff) |
luci-base, luci-mod-status: convert realtime stats to client side views
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'modules/luci-mod-status/luasrc')
5 files changed, 4 insertions, 1476 deletions
diff --git a/modules/luci-mod-status/luasrc/controller/admin/status.lua b/modules/luci-mod-status/luasrc/controller/admin/status.lua index d09cb6e2f7..e888ccf097 100644 --- a/modules/luci-mod-status/luasrc/controller/admin/status.lua +++ b/modules/luci-mod-status/luasrc/controller/admin/status.lua @@ -20,22 +20,10 @@ function index() entry({"admin", "status", "realtime"}, alias("admin", "status", "realtime", "load"), _("Realtime Graphs"), 7) - entry({"admin", "status", "realtime", "load"}, template("admin_status/load"), _("Load"), 1).leaf = true - entry({"admin", "status", "realtime", "load_status"}, call("action_load")).leaf = true - - entry({"admin", "status", "realtime", "bandwidth"}, template("admin_status/bandwidth"), _("Traffic"), 2).leaf = true - entry({"admin", "status", "realtime", "bandwidth_status"}, call("action_bandwidth")).leaf = true - - page = entry({"admin", "status", "realtime", "wireless"}, template("admin_status/wireless"), _("Wireless"), 3) - page.uci_depends = { wireless = true } - page.leaf = true - - page = entry({"admin", "status", "realtime", "wireless_status"}, call("action_wireless")) - page.uci_depends = { wireless = true } - page.leaf = true - - entry({"admin", "status", "realtime", "connections"}, template("admin_status/connections"), _("Connections"), 4).leaf = true - entry({"admin", "status", "realtime", "connections_status"}, call("action_connections")).leaf = true + entry({"admin", "status", "realtime", "load"}, view("status/load"), _("Load"), 1) + entry({"admin", "status", "realtime", "bandwidth"}, view("status/bandwidth"), _("Traffic"), 2) + entry({"admin", "status", "realtime", "wireless"}, view("status/wireless"), _("Wireless"), 3).uci_depends = { wireless = true } + entry({"admin", "status", "realtime", "connections"}, view("status/connections"), _("Connections"), 4) entry({"admin", "status", "nameinfo"}, call("action_nameinfo")).leaf = true end @@ -84,97 +72,3 @@ function action_iptables() luci.http.redirect(luci.dispatcher.build_url("admin/status/iptables")) end - -function action_bandwidth(iface) - luci.http.prepare_content("application/json") - - local bwc = io.popen("luci-bwc -i %s 2>/dev/null" - % luci.util.shellquote(iface)) - - if bwc then - luci.http.write("[") - - while true do - local ln = bwc:read("*l") - if not ln then break end - luci.http.write(ln) - end - - luci.http.write("]") - bwc:close() - end -end - -function action_wireless(iface) - luci.http.prepare_content("application/json") - - local bwc = io.popen("luci-bwc -r %s 2>/dev/null" - % luci.util.shellquote(iface)) - - if bwc then - luci.http.write("[") - - while true do - local ln = bwc:read("*l") - if not ln then break end - luci.http.write(ln) - end - - luci.http.write("]") - bwc:close() - end -end - -function action_load() - luci.http.prepare_content("application/json") - - local bwc = io.popen("luci-bwc -l 2>/dev/null") - if bwc then - luci.http.write("[") - - while true do - local ln = bwc:read("*l") - if not ln then break end - luci.http.write(ln) - end - - luci.http.write("]") - bwc:close() - end -end - -function action_connections() - local sys = require "luci.sys" - - luci.http.prepare_content("application/json") - - luci.http.write('{ "connections": ') - luci.http.write_json(sys.net.conntrack()) - - local bwc = io.popen("luci-bwc -c 2>/dev/null") - if bwc then - luci.http.write(', "statistics": [') - - while true do - local ln = bwc:read("*l") - if not ln then break end - luci.http.write(ln) - end - - luci.http.write("]") - bwc:close() - end - - luci.http.write(" }") -end - -function action_nameinfo(...) - local util = require "luci.util" - - luci.http.prepare_content("application/json") - luci.http.write_json(util.ubus("network.rrdns", "lookup", { - addrs = { ... }, - timeout = 5000, - limit = 1000 - }) or { }) -end diff --git a/modules/luci-mod-status/luasrc/view/admin_status/bandwidth.htm b/modules/luci-mod-status/luasrc/view/admin_status/bandwidth.htm deleted file mode 100644 index 5cc661ad17..0000000000 --- a/modules/luci-mod-status/luasrc/view/admin_status/bandwidth.htm +++ /dev/null @@ -1,308 +0,0 @@ -<%# - Copyright 2010-2018 Jo-Philipp Wich <jo@mein.io> - Licensed to the public under the Apache License 2.0. --%> - -<%- - local ntm = require "luci.model.network".init() - - local dev - local devices = { } - for _, dev in luci.util.vspairs(luci.sys.net.devices()) do - if dev ~= "lo" and not ntm:ignore_interface(dev) then - devices[#devices+1] = dev - end - end - - local curdev = luci.http.formvalue("dev") or devices[1] --%> - -<%+header%> - -<script type="text/javascript">//<![CDATA[ - var bwxhr = new XHR(); - - var G; - var TIME = 0; - var RXB = 1; - var RXP = 2; - var TXB = 3; - var TXP = 4; - - var width = 760; - var height = 300; - var step = 5; - - var data_wanted = Math.floor(width / step); - var data_fill = 1; - var data_stamp = 0; - - var data_rx = [ ]; - var data_tx = [ ]; - - var line_rx; - var line_tx; - - var label_25; - var label_50; - var label_75; - - var label_rx_cur; - var label_rx_avg; - var label_rx_peak; - - var label_tx_cur; - var label_tx_avg; - var label_tx_peak; - - var label_scale; - - - Math.log2 = Math.log2 || function(x) { return Math.log(x) * Math.LOG2E; }; - - function bandwidth_label(bytes, br) - { - var uby = '<%:kB/s%>'; - var kby = (bytes / 1024); - - if (kby >= 1024) - { - uby = '<%:MB/s%>'; - kby = kby / 1024; - } - - var ubi = '<%:kbit/s%>'; - var kbi = (bytes * 8 / 1024); - - if (kbi >= 1024) - { - ubi = '<%:Mbit/s%>'; - kbi = kbi / 1024; - } - - return String.format("%f %s%s(%f %s)", - kbi.toFixed(2), ubi, - br ? '<br />' : ' ', - kby.toFixed(2), uby - ); - } - - /* wait for SVG */ - window.setTimeout( - function() { - var svg = document.getElementById('bwsvg'); - - try { - G = svg.getSVGDocument - ? svg.getSVGDocument() : svg.contentDocument; - } - catch(e) { - G = document.embeds['bwsvg'].getSVGDocument(); - } - - if (!G) - { - window.setTimeout(arguments.callee, 1000); - } - else - { - /* find sizes */ - width = svg.offsetWidth - 2; - height = svg.offsetHeight - 2; - data_wanted = Math.ceil(width / step); - - /* prefill datasets */ - for (var i = 0; i < data_wanted; i++) - { - data_rx[i] = 0; - data_tx[i] = 0; - } - - /* find svg elements */ - line_rx = G.getElementById('rx'); - line_tx = G.getElementById('tx'); - - label_25 = G.getElementById('label_25'); - label_50 = G.getElementById('label_50'); - label_75 = G.getElementById('label_75'); - - label_rx_cur = document.getElementById('rx_bw_cur'); - label_rx_avg = document.getElementById('rx_bw_avg'); - label_rx_peak = document.getElementById('rx_bw_peak'); - - label_tx_cur = document.getElementById('tx_bw_cur'); - label_tx_avg = document.getElementById('tx_bw_avg'); - label_tx_peak = document.getElementById('tx_bw_peak'); - - label_scale = document.getElementById('scale'); - - - /* plot horizontal time interval lines */ - for (var i = width % (step * 60); i < width; i += step * 60) - { - var line = G.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 = G.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(G.createTextNode(Math.round((width - i) / step / 60) + 'm')); - - label_25.parentNode.appendChild(line); - label_25.parentNode.appendChild(text); - } - - label_scale.innerHTML = String.format('<%:(%d minute window, %d second interval)%>', data_wanted / 60, 3); - - /* render datasets, start update interval */ - XHR.poll(3, '<%=build_url("admin/status/realtime/bandwidth_status", curdev)%>', null, - function(x, data) - { - var data_max = 0; - var data_scale = 0; - - var data_rx_avg = 0; - var data_tx_avg = 0; - - var data_rx_peak = 0; - var data_tx_peak = 0; - - for (var i = data_stamp ? 0 : 1; i < data.length; i++) - { - /* skip overlapping entries */ - if (data[i][TIME] <= data_stamp) - continue; - - data_fill++; - - /* normalize difference against time interval */ - if (i > 0) - { - var time_delta = data[i][TIME] - data[i-1][TIME]; - if (time_delta) - { - data_rx.push((data[i][RXB] - data[i-1][RXB]) / time_delta); - data_tx.push((data[i][TXB] - data[i-1][TXB]) / time_delta); - } - } - } - - /* cut off outdated entries */ - data_rx = data_rx.slice(data_rx.length - data_wanted, data_rx.length); - data_tx = data_tx.slice(data_tx.length - data_wanted, data_tx.length); - data_fill = Math.min(data_fill, data_wanted); - - /* find peak */ - for (var i = 0; i < data_rx.length; i++) - { - data_max = Math.max(data_max, data_rx[i]); - data_max = Math.max(data_max, data_tx[i]); - - data_rx_peak = Math.max(data_rx_peak, data_rx[i]); - data_tx_peak = Math.max(data_tx_peak, data_tx[i]); - - data_rx_avg += data_rx[i]; - data_tx_avg += data_tx[i]; - } - - data_rx_avg = (data_rx_avg / data_fill); - data_tx_avg = (data_tx_avg / data_fill); - - var size = Math.floor(Math.log2(data_max)), - div = Math.pow(2, size - (size % 10)), - mult = data_max / div, - mult = (mult < 5) ? 2 : ((mult < 50) ? 10 : ((mult < 500) ? 100 : 1000)); - - data_max = data_max + (mult * div) - (data_max % (mult * div)); - - /* remember current timestamp, calculate horizontal scale */ - data_stamp = data[data.length-1][TIME]; - data_scale = height / data_max; - - /* plot data */ - var pt_rx = '0,' + height; - var pt_tx = '0,' + height; - - var y_rx = 0; - var y_tx = 0; - - for (var i = 0; i < data_rx.length; i++) - { - var x = i * step; - - y_rx = height - Math.floor(data_rx[i] * data_scale); - y_tx = height - Math.floor(data_tx[i] * data_scale); - - pt_rx += ' ' + x + ',' + y_rx; - pt_tx += ' ' + x + ',' + y_tx; - } - - pt_rx += ' ' + width + ',' + y_rx + ' ' + width + ',' + height; - pt_tx += ' ' + width + ',' + y_tx + ' ' + width + ',' + height; - - - line_rx.setAttribute('points', pt_rx); - line_tx.setAttribute('points', pt_tx); - - label_25.firstChild.data = bandwidth_label(0.25 * data_max); - label_50.firstChild.data = bandwidth_label(0.50 * data_max); - label_75.firstChild.data = bandwidth_label(0.75 * data_max); - - label_rx_cur.innerHTML = bandwidth_label(data_rx[data_rx.length-1], true); - label_tx_cur.innerHTML = bandwidth_label(data_tx[data_tx.length-1], true); - - label_rx_avg.innerHTML = bandwidth_label(data_rx_avg, true); - label_tx_avg.innerHTML = bandwidth_label(data_tx_avg, true); - - label_rx_peak.innerHTML = bandwidth_label(data_rx_peak, true); - label_tx_peak.innerHTML = bandwidth_label(data_tx_peak, true); - } - ); - - XHR.run(); - } - }, 1000 - ); -//]]></script> - -<h2 name="content"><%:Realtime Traffic%></h2> - -<ul class="cbi-tabmenu"> - <% for _, dev in ipairs(devices) do %> - <li class="cbi-tab<%= dev == curdev and "" or "-disabled" %>"><a href="?dev=<%=pcdata(dev)%>"><%=pcdata(dev)%></a></li> - <% end %> -</ul> - -<embed id="bwsvg" style="width:100%; height:300px; border:1px solid #000000; background-color:#FFFFFF" src="<%=resource%>/bandwidth.svg" /> -<div style="text-align:right"><small id="scale">-</small></div> -<br /> - -<div class="table" style="width:100%; table-layout:fixed" cellspacing="5"> - <div class="tr"> - <div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid blue"><%:Inbound:%></strong></div> - <div class="td" id="rx_bw_cur">0 <%:kbit/s%><br />(0 <%:kB/s%>)</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div> - <div class="td" id="rx_bw_avg">0 <%:kbit/s%><br />(0 <%:kB/s%>)</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div> - <div class="td" id="rx_bw_peak">0 <%:kbit/s%><br />(0 <%:kB/s%>)</div> - </div> - <div class="tr"> - <div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid green"><%:Outbound:%></strong></div> - <div class="td" id="tx_bw_cur">0 <%:kbit/s%><br />(0 <%:kB/s%>)</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div> - <div class="td" id="tx_bw_avg">0 <%:kbit/s%><br />(0 <%:kB/s%>)</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div> - <div class="td" id="tx_bw_peak">0 <%:kbit/s%><br />(0 <%:kB/s%>)</div> - </div> -</div> - -<%+footer%> diff --git a/modules/luci-mod-status/luasrc/view/admin_status/connections.htm b/modules/luci-mod-status/luasrc/view/admin_status/connections.htm deleted file mode 100644 index 37debcde66..0000000000 --- a/modules/luci-mod-status/luasrc/view/admin_status/connections.htm +++ /dev/null @@ -1,405 +0,0 @@ -<%# - Copyright 2010-2018 Jo-Philipp Wich <jo@mein.io> - Licensed to the public under the Apache License 2.0. --%> - -<%+header%> - -<script type="text/javascript">//<![CDATA[ - var bwxhr = new XHR(); - - var G; - var TIME = 0; - var UDP = 1; - var TCP = 2; - var OTHER = 3; - - var width = 760; - var height = 300; - var step = 5; - - var data_wanted = Math.floor(width / step); - var data_fill = 1; - var data_stamp = 0; - - var data_udp = [ ]; - var data_tcp = [ ]; - var data_otr = [ ]; - - var line_udp; - var line_tcp; - - var label_25; - var label_50; - var label_75; - - var label_udp_cur; - var label_udp_avg; - var label_udp_peak; - - var label_tcp_cur; - var label_tcp_avg; - var label_tcp_peak; - - var label_otr_cur; - var label_otr_avg; - var label_otr_peak; - - var label_scale; - - var conn_table; - - var dns_cache = { }; - - - /* wait for SVG */ - window.setTimeout( - function() { - var svg = document.getElementById('bwsvg'); - - try { - G = svg.getSVGDocument - ? svg.getSVGDocument() : svg.contentDocument; - } - catch(e) { - G = document.embeds['bwsvg'].getSVGDocument(); - } - - if (!G) - { - window.setTimeout(arguments.callee, 1000); - } - else - { - /* find sizes */ - width = svg.offsetWidth - 2; - height = svg.offsetHeight - 2; - data_wanted = Math.ceil(width / step); - - /* prefill datasets */ - for (var i = 0; i < data_wanted; i++) - { - data_udp[i] = 0; - data_tcp[i] = 0; - data_otr[i] = 0; - } - - /* find svg elements */ - line_udp = G.getElementById('udp'); - line_tcp = G.getElementById('tcp'); - line_otr = G.getElementById('other'); - - label_25 = G.getElementById('label_25'); - label_50 = G.getElementById('label_50'); - label_75 = G.getElementById('label_75'); - - label_udp_cur = document.getElementById('lb_udp_cur'); - label_udp_avg = document.getElementById('lb_udp_avg'); - label_udp_peak = document.getElementById('lb_udp_peak'); - - label_tcp_cur = document.getElementById('lb_tcp_cur'); - label_tcp_avg = document.getElementById('lb_tcp_avg'); - label_tcp_peak = document.getElementById('lb_tcp_peak'); - - label_otr_cur = document.getElementById('lb_otr_cur'); - label_otr_avg = document.getElementById('lb_otr_avg'); - label_otr_peak = document.getElementById('lb_otr_peak'); - - label_scale = document.getElementById('scale'); - - conn_table = document.getElementById('connections'); - - - /* plot horizontal time interval lines */ - for (var i = width % (step * 60); i < width; i += step * 60) - { - var line = G.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 = G.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(G.createTextNode(Math.round((width - i) / step / 60) + 'm')); - - label_25.parentNode.appendChild(line); - label_25.parentNode.appendChild(text); - } - - label_scale.innerHTML = String.format('<%:(%d minute window, %d second interval)%>', data_wanted / 60, 3); - - var recheck_lookup_queue = {}; - - /* render datasets, start update interval */ - XHR.poll(3, '<%=build_url("admin/status/realtime/connections_status")%>', null, - function(x, json) - { - - if (!json.connections) - return; - - var conn = json.connections; - - var lookup_queue = [ ]; - var rows = []; - - conn.sort(function(a, b) { - return b.bytes - a.bytes; - }); - - for (var i = 0; i < conn.length; i++) - { - var c = conn[i]; - - if ((c.src == '127.0.0.1' && c.dst == '127.0.0.1') || - (c.src == '::1' && c.dst == '::1')) - continue; - - if (!dns_cache[c.src] && lookup_queue.indexOf(c.src) == -1) - lookup_queue.push(c.src); - - if (!dns_cache[c.dst] && lookup_queue.indexOf(c.dst) == -1) - lookup_queue.push(c.dst); - - var src = dns_cache[c.src] || (c.layer3 == 'ipv6' ? '[' + c.src + ']' : c.src); - var dst = dns_cache[c.dst] || (c.layer3 == 'ipv6' ? '[' + c.dst + ']' : c.dst); - - rows.push([ - c.layer3.toUpperCase(), - c.layer4.toUpperCase(), - c.hasOwnProperty('sport') ? (src + ':' + c.sport) : src, - c.hasOwnProperty('dport') ? (dst + ':' + c.dport) : dst, - '%1024.2mB (%d <%:Pkts.%>)'.format(c.bytes, c.packets) - ]); - } - - cbi_update_table(conn_table, rows, '<em><%:No information available%></em>'); - - if (lookup_queue.length > 0) { - var reduced_lookup_queue = lookup_queue; - - if (lookup_queue.length > 100) - reduced_lookup_queue = lookup_queue.slice(0, 100); - - XHR.get('<%=build_url("admin/status/nameinfo")%>/' + reduced_lookup_queue.join('/'), null, - function(x, json) { - if (!json) - return; - - for (var index in reduced_lookup_queue) { - var address = reduced_lookup_queue[index]; - - if (!address) - continue; - - if (json[address]) { - dns_cache[address] = json[address]; - lookup_queue.splice(reduced_lookup_queue.indexOf(address),1); - continue; - } - - if(recheck_lookup_queue[address] > 2) { - dns_cache[address] = (address.match(/:/)) ? '[' + address + ']' : address; - lookup_queue.splice(index,1); - } else { - recheck_lookup_queue[address] != null ? recheck_lookup_queue[address]++ : recheck_lookup_queue[address] = 0; - } - } - } - ); - } - - - var data = json.statistics; - - var data_max = 0; - var data_scale = 0; - - var data_udp_avg = 0; - var data_tcp_avg = 0; - var data_otr_avg = 0; - - var data_udp_peak = 0; - var data_tcp_peak = 0; - var data_otr_peak = 0; - - for (var i = data_stamp ? 0 : 1; i < data.length; i++) - { - /* skip overlapping entries */ - if (data[i][TIME] <= data_stamp) - continue; - - data_fill++; - - data_udp.push(data[i][UDP]); - data_tcp.push(data[i][TCP]); - data_otr.push(data[i][OTHER]); - } - - /* cut off outdated entries */ - data_fill = Math.min(data_fill, data_wanted); - data_udp = data_udp.slice(data_udp.length - data_wanted, data_udp.length); - data_tcp = data_tcp.slice(data_tcp.length - data_wanted, data_tcp.length); - data_otr = data_otr.slice(data_otr.length - data_wanted, data_otr.length); - - /* find peak */ - for (var i = 0; i < data_udp.length; i++) - { - data_max = Math.max(data_max, data_udp[i]); - data_max = Math.max(data_max, data_tcp[i]); - data_max = Math.max(data_max, data_otr[i]); - - data_udp_peak = Math.max(data_udp_peak, data_udp[i]); - data_tcp_peak = Math.max(data_tcp_peak, data_tcp[i]); - data_otr_peak = Math.max(data_otr_peak, data_otr[i]); - - data_udp_avg += data_udp[i]; - data_tcp_avg += data_tcp[i]; - data_otr_avg += data_otr[i]; - } - - data_udp_avg = data_udp_avg / data_fill; - data_tcp_avg = data_tcp_avg / data_fill; - data_otr_avg = data_otr_avg / data_fill; - - /* remember current timestamp, calculate horizontal scale */ - data_stamp = data[data.length-1][TIME]; - data_scale = height / (data_max * 1.1); - - - /* plot data */ - var pt_udp = '0,' + height; - var pt_tcp = '0,' + height; - var pt_otr = '0,' + height; - - var y_udp = 0; - var y_tcp = 0; - var y_otr = 0; - - for (var i = 0; i < data_udp.length; i++) - { - var x = i * step; - - y_udp = height - Math.floor(data_udp[i] * data_scale); - y_tcp = height - Math.floor(data_tcp[i] * data_scale); - y_otr = height - Math.floor(data_otr[i] * data_scale); - - pt_udp += ' ' + x + ',' + y_udp; - pt_tcp += ' ' + x + ',' + y_tcp; - pt_otr += ' ' + x + ',' + y_otr; - } - - pt_udp += ' ' + width + ',' + y_udp + ' ' + width + ',' + height; - pt_tcp += ' ' + width + ',' + y_tcp + ' ' + width + ',' + height; - pt_otr += ' ' + width + ',' + y_otr + ' ' + width + ',' + height; - - - var order = [ - [ line_udp, data_udp[data_udp.length-1] ], - [ line_tcp, data_tcp[data_tcp.length-1] ], - [ line_otr, data_otr[data_otr.length-1] ] - ]; - - order.sort(function(a, b) { return b[1] - a[1] }); - - for (var i = 0; i < order.length; i++) - order[i][0].parentNode.appendChild(order[i][0]); - - - line_udp.setAttribute('points', pt_udp); - line_tcp.setAttribute('points', pt_tcp); - line_otr.setAttribute('points', pt_otr); - - label_25.firstChild.data = Math.floor(1.1 * 0.25 * data_max); - label_50.firstChild.data = Math.floor(1.1 * 0.50 * data_max); - label_75.firstChild.data = Math.floor(1.1 * 0.75 * data_max); - - label_udp_cur.innerHTML = Math.floor(data_udp[data_udp.length-1]); - label_tcp_cur.innerHTML = Math.floor(data_tcp[data_tcp.length-1]); - label_otr_cur.innerHTML = Math.floor(data_otr[data_otr.length-1]); - - label_udp_avg.innerHTML = Math.floor(data_udp_avg); - label_tcp_avg.innerHTML = Math.floor(data_tcp_avg); - label_otr_avg.innerHTML = Math.floor(data_otr_avg); - - label_udp_peak.innerHTML = Math.floor(data_udp_peak); - label_tcp_peak.innerHTML = Math.floor(data_tcp_peak); - label_otr_peak.innerHTML = Math.floor(data_otr_peak); - } - ); - - XHR.run(); - } - }, 1000 - ); -//]]></script> - -<h2 name="content"><%:Realtime Connections%></h2> - -<div class="cbi-map-descr"><%:This page gives an overview over currently active network connections.%></div> - -<fieldset class="cbi-section" id="cbi-table-table"> - <legend><%:Active Connections%></legend> - - <embed id="bwsvg" style="width:100%; height:300px; border:1px solid #000000; background-color:#FFFFFF" src="<%=resource%>/connections.svg" /> - <div style="text-align:right"><small id="scale">-</small></div> - <br /> - - <div class="table"> - <div class="tr"> - <div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid blue"><%:UDP:%></strong></div> - <div class="td" id="lb_udp_cur">0</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div> - <div class="td" id="lb_udp_avg">0</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div> - <div class="td" id="lb_udp_peak">0</div> - </div> - <div class="tr"> - <div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid green"><%:TCP:%></strong></div> - <div class="td" id="lb_tcp_cur">0</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div> - <div class="td" id="lb_tcp_avg">0</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div> - <div class="td" id="lb_tcp_peak">0</div> - </div> - <div class="tr"> - <div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid red"><%:Other:%></strong></div> - <div class="td" id="lb_otr_cur">0</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div> - <div class="td" id="lb_otr_avg">0</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div> - <div class="td" id="lb_otr_peak">0</div> - </div> - </div> - <br /> - - <div class="cbi-section-node"> - <div class="table" id="connections"> - <div class="tr table-titles"> - <div class="th col-2 hide-xs"><%:Network%></div> - <div class="th col-2"><%:Protocol%></div> - <div class="th col-7"><%:Source%></div> - <div class="th col-7"><%:Destination%></div> - <div class="th col-4"><%:Transfer%></div> - </div> - - <div class="tr placeholder"> - <div class="td"> - <em><%:Collecting data...%></em> - </div> - </div> - </div> - </div> -</fieldset> - -<%+footer%> diff --git a/modules/luci-mod-status/luasrc/view/admin_status/load.htm b/modules/luci-mod-status/luasrc/view/admin_status/load.htm deleted file mode 100644 index d31d340621..0000000000 --- a/modules/luci-mod-status/luasrc/view/admin_status/load.htm +++ /dev/null @@ -1,283 +0,0 @@ -<%# - Copyright 2010-2018 Jo-Philipp Wich <jo@mein.io> - Licensed to the public under the Apache License 2.0. --%> - -<%+header%> - -<script type="text/javascript">//<![CDATA[ - var bwxhr = new XHR(); - - var G; - var TIME = 0; - var L01 = 1; - var L05 = 2; - var L15 = 3; - - var width = 760; - var height = 300; - var step = 5; - - var data_wanted = Math.floor(width / step); - var data_fill = 1; - var data_stamp = 0; - - var data_01 = [ ]; - var data_05 = [ ]; - var data_15 = [ ]; - - var line_01; - var line_05; - var line_15; - - var label_25; - var label_050; - var label_75; - - var label_01_cur; - var label_01_avg; - var label_01_peak; - - var label_05_cur; - var label_05_avg; - var label_05_peak; - - var label_15_cur; - var label_15_avg; - var label_15_peak; - - var label_scale; - - - /* wait for SVG */ - window.setTimeout( - function() { - var svg = document.getElementById('bwsvg'); - - try { - G = svg.getSVGDocument - ? svg.getSVGDocument() : svg.contentDocument; - } - catch(e) { - G = document.embeds['bwsvg'].getSVGDocument(); - } - - if (!G) - { - window.setTimeout(arguments.callee, 1000); - } - else - { - /* find sizes */ - width = svg.offsetWidth - 2; - height = svg.offsetHeight - 2; - data_wanted = Math.ceil(width / step); - - /* prefill datasets */ - for (var i = 0; i < data_wanted; i++) - { - data_01[i] = 0; - data_05[i] = 0; - data_15[i] = 0; - } - - /* find svg elements */ - line_01 = G.getElementById('load01'); - line_05 = G.getElementById('load05'); - line_15 = G.getElementById('load15'); - - label_25 = G.getElementById('label_25'); - label_50 = G.getElementById('label_50'); - label_75 = G.getElementById('label_75'); - - label_01_cur = document.getElementById('lb_load01_cur'); - label_01_avg = document.getElementById('lb_load01_avg'); - label_01_peak = document.getElementById('lb_load01_peak'); - - label_05_cur = document.getElementById('lb_load05_cur'); - label_05_avg = document.getElementById('lb_load05_avg'); - label_05_peak = document.getElementById('lb_load05_peak'); - - label_15_cur = document.getElementById('lb_load15_cur'); - label_15_avg = document.getElementById('lb_load15_avg'); - label_15_peak = document.getElementById('lb_load15_peak'); - - label_scale = document.getElementById('scale'); - - - /* plot horizontal time interval lines */ - for (var i = width % (step * 60); i < width; i += step * 60) - { - var line = G.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 = G.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(G.createTextNode(Math.round((width - i) / step / 60) + 'm')); - - label_25.parentNode.appendChild(line); - label_25.parentNode.appendChild(text); - } - - label_scale.innerHTML = String.format('<%:(%d minute window, %d second interval)%>', data_wanted / 60, 3); - - /* render datasets, start update interval */ - XHR.poll(3, '<%=build_url("admin/status/realtime/load_status")%>', null, - function(x, data) - { - var data_max = 0; - var data_scale = 0; - - var data_01_avg = 0; - var data_05_avg = 0; - var data_15_avg = 0; - - var data_01_peak = 0; - var data_05_peak = 0; - var data_15_peak = 0; - - for (var i = data_stamp ? 0 : 1; i < data.length; i++) - { - /* skip overlapping entries */ - if (data[i][TIME] <= data_stamp) - continue; - - data_fill++; - - data_01.push(data[i][L01]); - data_05.push(data[i][L05]); - data_15.push(data[i][L15]); - } - - /* cut off outdated entries */ - data_fill = Math.min(data_fill, data_wanted); - data_01 = data_01.slice(data_01.length - data_wanted, data_01.length); - data_05 = data_05.slice(data_05.length - data_wanted, data_05.length); - data_15 = data_15.slice(data_15.length - data_wanted, data_15.length); - - /* find peak */ - for (var i = 0; i < data_01.length; i++) - { - data_max = Math.max(data_max, data_01[i]); - data_max = Math.max(data_max, data_05[i]); - data_max = Math.max(data_max, data_15[i]); - - data_01_peak = Math.max(data_01_peak, data_01[i]); - data_05_peak = Math.max(data_05_peak, data_05[i]); - data_15_peak = Math.max(data_15_peak, data_15[i]); - - data_01_avg += data_01[i]; - data_05_avg += data_05[i]; - data_15_avg += data_15[i]; - } - - data_01_avg = data_01_avg / data_fill; - data_05_avg = data_05_avg / data_fill; - data_15_avg = data_15_avg / data_fill; - - /* remember current timestamp, calculate horizontal scale */ - data_stamp = data[data.length-1][TIME]; - data_scale = height / (data_max * 1.1); - - - /* plot data */ - var pt_01 = '0,' + height; - var pt_05 = '0,' + height; - var pt_15 = '0,' + height; - - var y_01 = 0; - var y_05 = 0; - var y_15 = 0; - - for (var i = 0; i < data_01.length; i++) - { - var x = i * step; - - y_01 = height - Math.floor(data_01[i] * data_scale); - y_05 = height - Math.floor(data_05[i] * data_scale); - y_15 = height - Math.floor(data_15[i] * data_scale); - - pt_01 += ' ' + x + ',' + y_01; - pt_05 += ' ' + x + ',' + y_05; - pt_15 += ' ' + x + ',' + y_15; - } - - pt_01 += ' ' + width + ',' + y_01 + ' ' + width + ',' + height; - pt_05 += ' ' + width + ',' + y_05 + ' ' + width + ',' + height; - pt_15 += ' ' + width + ',' + y_15 + ' ' + width + ',' + height; - - - line_01.setAttribute('points', pt_01); - line_05.setAttribute('points', pt_05); - line_15.setAttribute('points', pt_15); - - label_25.firstChild.data = (1.1 * 0.25 * data_max / 100).toFixed(2); - label_50.firstChild.data = (1.1 * 0.50 * data_max / 100).toFixed(2); - label_75.firstChild.data = (1.1 * 0.75 * data_max / 100).toFixed(2); - - label_01_cur.innerHTML = (data_01[data_01.length-1] / 100).toFixed(2); - label_05_cur.innerHTML = (data_05[data_05.length-1] / 100).toFixed(2); - label_15_cur.innerHTML = (data_15[data_15.length-1] / 100).toFixed(2); - - label_01_avg.innerHTML = (data_01_avg / 100).toFixed(2); - label_05_avg.innerHTML = (data_05_avg / 100).toFixed(2); - label_15_avg.innerHTML = (data_15_avg / 100).toFixed(2); - - label_01_peak.innerHTML = (data_01_peak / 100).toFixed(2); - label_05_peak.innerHTML = (data_05_peak / 100).toFixed(2); - label_15_peak.innerHTML = (data_15_peak / 100).toFixed(2); - } - ); - - XHR.run(); - } - }, 1000 - ); -//]]></script> - -<h2 name="content"><%:Realtime Load%></h2> - -<embed id="bwsvg" style="width:100%; height:300px; border:1px solid #000000; background-color:#FFFFFF" src="<%=resource%>/load.svg" /> -<div style="text-align:right"><small id="scale">-</small></div> -<br /> - -<div class="table" style="width:100%; table-layout:fixed" cellspacing="5"> - <div class="tr"> - <div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid #ff0000; white-space:nowrap"><%:1 Minute Load:%></strong></div> - <div class="td" id="lb_load01_cur">0</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div> - <div class="td" id="lb_load01_avg">0</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div> - <div class="td" id="lb_load01_peak">0</div> - </div> - <div class="tr"> - <div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid #ff6600; white-space:nowrap"><%:5 Minute Load:%></strong></div> - <div class="td" id="lb_load05_cur">0</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div> - <div class="td" id="lb_load05_avg">0</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div> - <div class="td" id="lb_load05_peak">0</div> - </div> - <div class="tr"> - <div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid #ffaa00; white-space:nowrap"><%:15 Minute Load:%></strong></div> - <div class="td" id="lb_load15_cur">0</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div> - <div class="td" id="lb_load15_avg">0</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div> - <div class="td" id="lb_load15_peak">0</div> - </div> -</div> - -<%+footer%> diff --git a/modules/luci-mod-status/luasrc/view/admin_status/wireless.htm b/modules/luci-mod-status/luasrc/view/admin_status/wireless.htm deleted file mode 100644 index 5ac2eb462d..0000000000 --- a/modules/luci-mod-status/luasrc/view/admin_status/wireless.htm +++ /dev/null @@ -1,370 +0,0 @@ -<%# - Copyright 2011-2018 Jo-Philipp Wich <jo@mein.io> - Licensed to the public under the Apache License 2.0. --%> - -<%- - local ntm = require "luci.model.network".init() - - local dev - local devices = { } - for _, dev in luci.util.vspairs(luci.sys.net.devices()) do - if dev:match("^wlan%d") or dev:match("^ath%d") or dev:match("^wl%d") then - devices[#devices+1] = dev - end - end - - local curdev = luci.http.formvalue("dev") or devices[1] --%> - -<%+header%> - -<script type="text/javascript">//<![CDATA[ - var bwxhr = new XHR(); - - var G, G2; - var TIME = 0; - var RATE = 1; - var RSSI = 2; - var NOISE = 3; - - var width = 760; - var height = 300; - var step = 5; - - var data_wanted = Math.floor(width / step); - var data_fill = 1; - var data_stamp = 0; - - var data_rssi = [ ]; - var data_noise = [ ]; - var data_rate = [ ]; - - var line_rssi; - var line_noise; - var line_rate; - - var label_25, label_25_2; - var label_50, label_50_2; - var label_75, label_75_2; - - var label_rssi_cur; - var label_rssi_avg; - var label_rssi_peak; - - var label_noise_cur; - var label_noise_avg; - var label_noise_peak; - - var label_rate_cur; - var label_rate_avg; - var label_rate_peak; - - var label_scale; - var label_scale_2; - - - /* wait for SVG */ - window.setTimeout( - function() { - var svg = document.getElementById('iwsvg'); - var svg2 = document.getElementById('iwsvg2'); - - try { - G = svg.getSVGDocument - ? svg.getSVGDocument() : svg.contentDocument; - G2 = svg2.getSVGDocument - ? svg2.getSVGDocument() : svg2.contentDocument; - } - catch(e) { - G = document.embeds['iwsvg'].getSVGDocument(); - G2 = document.embeds['iwsvg2'].getSVGDocument(); - } - - if (!G || !G2) - { - window.setTimeout(arguments.callee, 1000); - } - else - { - /* find sizes */ - width = svg.offsetWidth - 2; - height = svg.offsetHeight - 2; - data_wanted = Math.ceil(width / step); - - /* prefill datasets */ - for (var i = 0; i < data_wanted; i++) - { - data_rssi[i] = 0; - data_noise[i] = 0; - data_rate[i] = 0; - } - - /* find svg elements */ - line_rssi = G.getElementById('rssi'); - line_noise = G.getElementById('noise'); - line_rate = G2.getElementById('rate'); - - label_25 = G.getElementById('label_25'); - label_50 = G.getElementById('label_50'); - label_75 = G.getElementById('label_75'); - label_25_2 = G2.getElementById('label_25'); - label_50_2 = G2.getElementById('label_50'); - label_75_2 = G2.getElementById('label_75'); - - label_rssi_cur = document.getElementById('rssi_bw_cur'); - label_rssi_avg = document.getElementById('rssi_bw_avg'); - label_rssi_peak = document.getElementById('rssi_bw_peak'); - - label_noise_cur = document.getElementById('noise_bw_cur'); - label_noise_avg = document.getElementById('noise_bw_avg'); - label_noise_peak = document.getElementById('noise_bw_peak'); - - label_rate_cur = document.getElementById('rate_bw_cur'); - label_rate_avg = document.getElementById('rate_bw_avg'); - label_rate_peak = document.getElementById('rate_bw_peak'); - - label_scale = document.getElementById('scale'); - label_scale_2 = document.getElementById('scale2'); - - - /* plot horizontal time interval lines */ - for (var i = width % (step * 60); i < width; i += step * 60) - { - var line = G.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 = G.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(G.createTextNode(Math.round((width - i) / step / 60) + 'm')); - - label_25.parentNode.appendChild(line); - label_25.parentNode.appendChild(text); - - - var line2 = G2.createElementNS('http://www.w3.org/2000/svg', 'line'); - line2.setAttribute('x1', i); - line2.setAttribute('y1', 0); - line2.setAttribute('x2', i); - line2.setAttribute('y2', '100%'); - line2.setAttribute('style', 'stroke:black;stroke-width:0.1'); - - var text2 = G2.createElementNS('http://www.w3.org/2000/svg', 'text'); - text2.setAttribute('x', i + 5); - text2.setAttribute('y', 15); - text2.setAttribute('style', 'fill:#eee; font-size:9pt; font-family:sans-serif; text-shadow:1px 1px 1px #000'); - text2.appendChild(G.createTextNode(Math.round((width - i) / step / 60) + 'm')); - - label_25_2.parentNode.appendChild(line2); - label_25_2.parentNode.appendChild(text2); - } - - label_scale.innerHTML = String.format('<%:(%d minute window, %d second interval)%>', data_wanted / 60, 3); - label_scale_2.innerHTML = String.format('<%:(%d minute window, %d second interval)%>', data_wanted / 60, 3); - - /* render datasets, start update interval */ - XHR.poll(3, '<%=build_url("admin/status/realtime/wireless_status", curdev)%>', null, - function(x, data) - { - var noise_floor = 255; - var rate_floor = 60000; - - for (var i = 0; i < data.length; i++) { - noise_floor = Math.min(noise_floor, data[i][NOISE]); - rate_floor = Math.min(rate_floor, data[i][RATE]); - } - - noise_floor -= 5; - - var data_max = 0; - var data_scale = 0; - var data_max_2 = 0; - var data_scale_2 = 0; - - var data_rssi_avg = 0; - var data_noise_avg = 0; - var data_rate_avg = 0; - - var data_rssi_peak = 0; - var data_noise_peak = 0; - var data_rate_peak = 0; - - for (var i = data_stamp ? 0 : 1; i < data.length; i++) - { - /* skip overlapping entries */ - if (data[i][TIME] <= data_stamp) - continue; - - data_fill++; - - data_rssi.push(data[i][RSSI] - noise_floor); - data_noise.push(data[i][NOISE] - noise_floor); - data_rate.push(Math.floor(data[i][RATE] / 1000)); - } - - /* cut off outdated entries */ - data_fill = Math.min(data_fill, data_wanted); - data_rssi = data_rssi.slice(data_rssi.length - data_wanted, data_rssi.length); - data_noise = data_noise.slice(data_noise.length - data_wanted, data_noise.length); - data_rate = data_rate.slice(data_rate.length - data_wanted, data_rate.length); - - /* find peak */ - for (var i = 0; i < data_rssi.length; i++) - { - data_max = Math.max(data_max, data_rssi[i]); - data_max_2 = Math.max(data_max_2, data_rate[i]); - - data_rssi_peak = Math.max(data_rssi_peak, data_rssi[i]); - data_noise_peak = Math.max(data_noise_peak, data_noise[i]); - data_rate_peak = Math.max(data_rate_peak, data_rate[i]); - - data_rssi_avg += data_rssi[i]; - data_noise_avg += data_noise[i]; - data_rate_avg += data_rate[i]; - } - - data_rssi_avg = data_rssi_avg / data_fill; - data_noise_avg = data_noise_avg / data_fill; - data_rate_avg = data_rate_avg / data_fill; - - /* remember current timestamp, calculate horizontal scale */ - data_stamp = data[data.length-1][TIME]; - data_scale = (height / (data_max * 1.1)).toFixed(1); - data_scale_2 = (height / (data_max_2 * 1.1)).toFixed(1); - - /* plot data */ - var pt_rssi = '0,' + height; - var pt_noise = '0,' + height; - var pt_rate = '0,' + height; - - var y_rssi = 0; - var y_noise = 0; - var y_rate = 0; - - for (var i = 0; i < data_rssi.length; i++) - { - var x = i * step; - - y_rssi = height - Math.floor(data_rssi[i] * data_scale); - y_noise = height - Math.floor(data_noise[i] * data_scale); - y_rate = height - Math.floor(data_rate[i] * data_scale_2); - - y_rssi -= Math.floor(y_rssi % (1/data_scale)); - y_noise -= Math.floor(y_noise % (1/data_scale)); - - pt_rssi += ' ' + x + ',' + y_rssi; - pt_noise += ' ' + x + ',' + y_noise; - pt_rate += ' ' + x + ',' + y_rate; - } - - pt_rssi += ' ' + width + ',' + y_rssi + ' ' + width + ',' + height; - pt_noise += ' ' + width + ',' + y_noise + ' ' + width + ',' + height; - pt_rate += ' ' + width + ',' + y_rate + ' ' + width + ',' + height; - - line_rssi.setAttribute('points', pt_rssi); - line_noise.setAttribute('points', pt_noise); - line_rate.setAttribute('points', pt_rate); - - function wireless_label(dbm, noise) - { - if (noise) - return String.format("%d <%:dBm%> (SNR %d <%:dB%>)", noise_floor + dbm - 255, dbm - noise); - else - return String.format("%d <%:dBm%>", noise_floor + dbm - 255); - } - - function rate_label(mbit) - { - return String.format("%d <%:Mbit/s%>", mbit); - } - - label_25.firstChild.data = wireless_label(1.1 * 0.25 * data_max); - label_50.firstChild.data = wireless_label(1.1 * 0.50 * data_max); - label_75.firstChild.data = wireless_label(1.1 * 0.75 * data_max); - - label_25_2.firstChild.data = rate_label(1.1 * 0.25 * data_max_2); - label_50_2.firstChild.data = rate_label(1.1 * 0.50 * data_max_2); - label_75_2.firstChild.data = rate_label(1.1 * 0.75 * data_max_2); - - label_rssi_cur.innerHTML = wireless_label(data_rssi[data_rssi.length-1], data_noise[data_noise.length-1]).nobr(); - label_noise_cur.innerHTML = wireless_label(data_noise[data_noise.length-1]).nobr(); - - label_rssi_avg.innerHTML = wireless_label(data_rssi_avg, data_noise_avg).nobr(); - label_noise_avg.innerHTML = wireless_label(data_noise_avg).nobr(); - - label_rssi_peak.innerHTML = wireless_label(data_rssi_peak, data_noise_peak).nobr(); - label_noise_peak.innerHTML = wireless_label(data_noise_peak).nobr(); - - label_rate_cur.innerHTML = rate_label(data_rate[data_rate.length-1]); - label_rate_avg.innerHTML = rate_label(data_rate_avg); - label_rate_peak.innerHTML = rate_label(data_rate_peak); - } - ); - - XHR.run(); - } - }, 1000 - ); -//]]></script> - -<h2 name="content"><%:Realtime Wireless%></h2> - -<ul class="cbi-tabmenu"> - <% for _, dev in ipairs(devices) do %> - <li class="cbi-tab<%= dev == curdev and "" or "-disabled" %>"><a href="?dev=<%=pcdata(dev)%>"><%=pcdata(dev)%></a></li> - <% end %> -</ul> - -<embed id="iwsvg" style="width:100%; height:300px; border:1px solid #000000; background-color:#FFFFFF" src="<%=resource%>/wireless.svg" /> -<div style="text-align:right"><small id="scale">-</small></div> -<br /> - -<div class="table" style="width:100%; table-layout:fixed" cellspacing="5"> - <div class="tr"> - <div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid blue"><%:Signal:%></strong></div> - <div class="td" id="rssi_bw_cur">0 <%:dBm%></div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div> - <div class="td" id="rssi_bw_avg">0 <%:dBm%></div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div> - <div class="td" id="rssi_bw_peak">0 <%:dBm%></div> - </div> - <div class="tr"> - <div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid red"><%:Noise:%></strong></div> - <div class="td" id="noise_bw_cur">0 <%:dBm%></div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div> - <div class="td" id="noise_bw_avg">0 <%:dBm%></div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div> - <div class="td" id="noise_bw_peak">0 <%:dBm%></div> - </div> -</div> - -<br /> - -<embed id="iwsvg2" style="width:100%; height:300px; border:1px solid #000000; background-color:#FFFFFF" src="<%=resource%>/wifirate.svg" /> -<div style="text-align:right"><small id="scale2">-</small></div> -<br /> - -<div class="table" style="width:100%; table-layout:fixed" cellspacing="5"> - <div class="tr"> - <div class="td" style="text-align:right; vertical-align:top"><strong style="border-bottom:2px solid green"><%:Phy Rate:%></strong></div> - <div class="td" id="rate_bw_cur">0 MBit/s</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Average:%></strong></div> - <div class="td" id="rate_bw_avg">0 MBit/s</div> - - <div class="td" style="text-align:right; vertical-align:top"><strong><%:Peak:%></strong></div> - <div class="td" id="rate_bw_peak">0 MBit/s</div> - </div> -</div> - -<%+footer%> |