| 1 | <% |
|---|
| 2 | |
|---|
| 3 | local sys = require "luci.sys" |
|---|
| 4 | local twa = require "luci.tools.webadmin" |
|---|
| 5 | |
|---|
| 6 | -- System |
|---|
| 7 | local system, model, memtotal, memcached, membuffers, memfree, bogomips = sys.sysinfo() |
|---|
| 8 | local uptime = twa.date_format(tonumber(sys.uptime())) |
|---|
| 9 | local_time = os.date("%a, %d %b %Y, %H:%M:%S") |
|---|
| 10 | local load1, load5, load15 = sys.loadavg() |
|---|
| 11 | local load = string.format("%.2f, %.2f, %.2f", load1, load5, load15) |
|---|
| 12 | |
|---|
| 13 | local mem = string.format( |
|---|
| 14 | "%.2f MB (%.2f %s, %.2f %s, %.2f %s, %.2f %s)", |
|---|
| 15 | tonumber(memtotal) / 1024, |
|---|
| 16 | tonumber(memtotal - memfree) / 1024, |
|---|
| 17 | tostring(i18n.translate("used")), |
|---|
| 18 | memfree / 1024, |
|---|
| 19 | tostring(i18n.translate("free")), |
|---|
| 20 | memcached / 1024, |
|---|
| 21 | tostring(i18n.translate("cached")), |
|---|
| 22 | membuffers / 1024, |
|---|
| 23 | tostring(i18n.translate("buffered")) |
|---|
| 24 | ) |
|---|
| 25 | |
|---|
| 26 | -- update interval |
|---|
| 27 | local bogomips = bogomips or 100 |
|---|
| 28 | local interval |
|---|
| 29 | if bogomips > 350 then |
|---|
| 30 | interval = "5000" |
|---|
| 31 | else |
|---|
| 32 | interval = "10000" |
|---|
| 33 | end |
|---|
| 34 | |
|---|
| 35 | -- wireless |
|---|
| 36 | local ntm = require "luci.model.network".init() |
|---|
| 37 | local devices = ntm:get_wifidevs() |
|---|
| 38 | local netlist = { } |
|---|
| 39 | local netdevs = { } |
|---|
| 40 | local dev |
|---|
| 41 | for _, dev in ipairs(devices) do |
|---|
| 42 | local net |
|---|
| 43 | for _, net in ipairs(dev:get_wifinets()) do |
|---|
| 44 | netlist[#netlist+1] = net:ifname() |
|---|
| 45 | netdevs[net:ifname()] = dev:name() |
|---|
| 46 | end |
|---|
| 47 | end |
|---|
| 48 | local has_iwinfo = pcall(require, "iwinfo") |
|---|
| 49 | |
|---|
| 50 | -- Routes |
|---|
| 51 | local defroutev4 = sys.net.defaultroute() |
|---|
| 52 | local defroutev6 = sys.net.defaultroute6() |
|---|
| 53 | |
|---|
| 54 | -%> |
|---|
| 55 | |
|---|
| 56 | <%+header%> |
|---|
| 57 | |
|---|
| 58 | |
|---|
| 59 | <script type="text/javascript" src="<%=resource%>/cbi.js"></script> |
|---|
| 60 | |
|---|
| 61 | <script type="text/javascript">//<![CDATA[ |
|---|
| 62 | var iwxhr = new XHR(); |
|---|
| 63 | |
|---|
| 64 | var update_wifi_status = function() { |
|---|
| 65 | iwxhr.get('<%=luci.dispatcher.build_url("freifunk", "status", "public_status_json", table.concat(netlist, ","))%>', null, |
|---|
| 66 | function(x, st) |
|---|
| 67 | { |
|---|
| 68 | if (st) |
|---|
| 69 | { |
|---|
| 70 | for( var i = 0; i < st.length; i++ ) |
|---|
| 71 | { |
|---|
| 72 | var iw = st[i]; |
|---|
| 73 | var is_assoc = (iw.bssid && iw.channel); |
|---|
| 74 | var p = (100 / iw.quality_max * iw.quality); |
|---|
| 75 | var q = is_assoc ? p : -1; |
|---|
| 76 | |
|---|
| 77 | var icon; |
|---|
| 78 | if (q < 0) |
|---|
| 79 | icon = "<%=resource%>/icons/signal-none.png"; |
|---|
| 80 | else if (q == 0) |
|---|
| 81 | icon = "<%=resource%>/icons/signal-0.png"; |
|---|
| 82 | else if (q < 25) |
|---|
| 83 | icon = "<%=resource%>/icons/signal-0-25.png"; |
|---|
| 84 | else if (q < 50) |
|---|
| 85 | icon = "<%=resource%>/icons/signal-25-50.png"; |
|---|
| 86 | else if (q < 75) |
|---|
| 87 | icon = "<%=resource%>/icons/signal-50-75.png"; |
|---|
| 88 | else |
|---|
| 89 | icon = "<%=resource%>/icons/signal-75-100.png"; |
|---|
| 90 | |
|---|
| 91 | var power = document.getElementById(iw.id + '-txpower'); |
|---|
| 92 | if (power) |
|---|
| 93 | power.innerHTML = String.format('%s dbm', iw.txpower); |
|---|
| 94 | |
|---|
| 95 | var signal = document.getElementById(iw.id + '-signal'); |
|---|
| 96 | if (signal) |
|---|
| 97 | signal.innerHTML = String.format( |
|---|
| 98 | '<img src="%s" title="Signal: %s db / Noise: %s db" alt="Signal Quality" />', |
|---|
| 99 | icon, iw.signal, iw.noise |
|---|
| 100 | ); |
|---|
| 101 | |
|---|
| 102 | var bitrate = document.getElementById(iw.id + '-bitrate'); |
|---|
| 103 | if (bitrate) |
|---|
| 104 | bitrate.innerHTML = String.format('%s Mb/s', iw.bitrate ? iw.bitrate / 1000 : '?'); |
|---|
| 105 | |
|---|
| 106 | var ssid = document.getElementById(iw.id + '-ssid'); |
|---|
| 107 | if (ssid) |
|---|
| 108 | ssid.innerHTML = iw.ssid; |
|---|
| 109 | |
|---|
| 110 | var bssid = document.getElementById(iw.id + '-bssid'); |
|---|
| 111 | if (bssid) |
|---|
| 112 | bssid.innerHTML = iw.bssid; |
|---|
| 113 | |
|---|
| 114 | var channel = document.getElementById(iw.id + '-channel'); |
|---|
| 115 | if (channel) |
|---|
| 116 | channel.innerHTML = iw.channel; |
|---|
| 117 | |
|---|
| 118 | var mode = document.getElementById(iw.id + '-mode'); |
|---|
| 119 | if (mode) |
|---|
| 120 | mode.innerHTML = iw.mode; |
|---|
| 121 | } |
|---|
| 122 | |
|---|
| 123 | i = st.length - 1 |
|---|
| 124 | var u |
|---|
| 125 | |
|---|
| 126 | if (u = document.getElementById('dynuptime')) |
|---|
| 127 | u.innerHTML = st[i].uptime; |
|---|
| 128 | |
|---|
| 129 | if (u = document.getElementById('dynload')) |
|---|
| 130 | u.innerHTML = st[i].load; |
|---|
| 131 | |
|---|
| 132 | if (u = document.getElementById('dynmem')) |
|---|
| 133 | u.innerHTML = st[i].mem; |
|---|
| 134 | |
|---|
| 135 | if (u = document.getElementById('dyntime')) |
|---|
| 136 | u.innerHTML = st[i].time; |
|---|
| 137 | |
|---|
| 138 | if (st[i].defroutev4) |
|---|
| 139 | { |
|---|
| 140 | if (u = document.getElementById('v4dst')) |
|---|
| 141 | u.innerHTML = st[i].defroutev4.dest; |
|---|
| 142 | |
|---|
| 143 | if (u = document.getElementById('v4gw')) |
|---|
| 144 | u.innerHTML = st[i].defroutev4.gateway; |
|---|
| 145 | |
|---|
| 146 | if (u = document.getElementById('v4dev')) |
|---|
| 147 | u.innerHTML = st[i].defroutev4.dev; |
|---|
| 148 | |
|---|
| 149 | if (u = document.getElementById('v4metr')) |
|---|
| 150 | u.innerHTML = st[i].defroutev4.metr; |
|---|
| 151 | } |
|---|
| 152 | |
|---|
| 153 | if (st[i].defroutev6) |
|---|
| 154 | { |
|---|
| 155 | if (u = document.getElementById('v6dst')) |
|---|
| 156 | u.innerHTML = st[i].defroutev6.dest; |
|---|
| 157 | |
|---|
| 158 | if (u = document.getElementById('v6gw')) |
|---|
| 159 | u.innerHTML = st[i].defroutev6.gateway; |
|---|
| 160 | |
|---|
| 161 | if (u = document.getElementById('v6dev')) |
|---|
| 162 | u.innerHTML = st[i].defroutev6.dev; |
|---|
| 163 | |
|---|
| 164 | if (u = document.getElementById('v6metr')) |
|---|
| 165 | u.innerHTML = st[i].defroutev6.metr; |
|---|
| 166 | } |
|---|
| 167 | } |
|---|
| 168 | |
|---|
| 169 | window.setTimeout(update_wifi_status, <%=interval%>); |
|---|
| 170 | } |
|---|
| 171 | ) |
|---|
| 172 | }; |
|---|
| 173 | |
|---|
| 174 | update_wifi_status(); |
|---|
| 175 | //]]></script> |
|---|
| 176 | |
|---|
| 177 | <div class="cbi-map"> |
|---|
| 178 | <h2><%:System%></h2> |
|---|
| 179 | <div class="cbi-section-node"> |
|---|
| 180 | <div class="cbi-value"><label class="cbi-value-title"><%:System%></label><div class="cbi-value-field"><%=system%></div></div> |
|---|
| 181 | <div class="cbi-value"><label class="cbi-value-title"><%:Processor%></label><div class="cbi-value-field"><%=model%></div></div> |
|---|
| 182 | <div class="cbi-value"><label class="cbi-value-title"><%:Load%></label><div class="cbi-value-field" id="dynload"><%=load%></div></div> |
|---|
| 183 | <div class="cbi-value"><label class="cbi-value-title"><%:Memory%></label><div class="cbi-value-field" id="dynmem"><%=mem%></div></div> |
|---|
| 184 | <div class="cbi-value"><label class="cbi-value-title"><%:Local Time%></label><div class="cbi-value-field" id="dyntime"><%=local_time%></div></div> |
|---|
| 185 | <div class="cbi-value"><label class="cbi-value-title"><%:Uptime%></label><div class="cbi-value-field" id="dynuptime"><%=uptime%></div></div> |
|---|
| 186 | </div> |
|---|
| 187 | </div> |
|---|
| 188 | |
|---|
| 189 | <% if devices[1] then %> |
|---|
| 190 | |
|---|
| 191 | <div class="cbi-map"> |
|---|
| 192 | <h2><%:Wireless Overview%></h2> |
|---|
| 193 | |
|---|
| 194 | <% if not has_iwinfo then %> |
|---|
| 195 | <div class="errorbox"> |
|---|
| 196 | <strong><%:Package libiwinfo required!%></strong><br /> |
|---|
| 197 | <%_The <em>libiwinfo</em> package is not installed. You must install this component for working wireless configuration!%> |
|---|
| 198 | </div> |
|---|
| 199 | <% end %> |
|---|
| 200 | |
|---|
| 201 | <div class="cbi-section"> |
|---|
| 202 | <div class="cbi-section-node"> |
|---|
| 203 | <table class="cbi-section-table"> |
|---|
| 204 | <tr class="cbi-section-table-titles"> |
|---|
| 205 | <th class="cbi-section-table-cell"><%:Signal%></th> |
|---|
| 206 | <th class="cbi-section-table-cell"><%:Bitrate%></th> |
|---|
| 207 | <th class="cbi-section-table-cell"><%:SSID%></th> |
|---|
| 208 | <th class="cbi-section-table-cell"><%:BSSID%></th> |
|---|
| 209 | <th class="cbi-section-table-cell"><%:Channel%></th> |
|---|
| 210 | <th class="cbi-section-table-cell"><%:Mode%></th> |
|---|
| 211 | <th class="cbi-section-table-cell"><%:TX%>-<%:Power%></th> |
|---|
| 212 | <th class="cbi-section-table-cell"><%:Interface%></th> |
|---|
| 213 | </tr> |
|---|
| 214 | <% |
|---|
| 215 | for _, dev in ipairs(devices) do |
|---|
| 216 | local net |
|---|
| 217 | for _, net in ipairs(dev:get_wifinets()) do |
|---|
| 218 | netlist[#netlist+1] = net:ifname() |
|---|
| 219 | netdevs[net:ifname()] = dev:name() |
|---|
| 220 | |
|---|
| 221 | if net.iwdata.ifname then |
|---|
| 222 | local signal = net.iwinfo.signal or "N/A" |
|---|
| 223 | local noise = net.iwinfo.noise or "N/A" |
|---|
| 224 | local q = net.iwinfo.quality or "0" |
|---|
| 225 | local qmax = net.iwinfo.quality_max or "100" |
|---|
| 226 | local qperc = q / qmax * 100 |
|---|
| 227 | |
|---|
| 228 | if qperc == 0 then |
|---|
| 229 | icon = "signal-none.png" |
|---|
| 230 | elseif qperc < 26 then |
|---|
| 231 | icon = "signal-0-25.png" |
|---|
| 232 | elseif qperc < 51 then |
|---|
| 233 | icon = "signal-25-50.png" |
|---|
| 234 | elseif qperc < 76 then |
|---|
| 235 | icon = "signal-50-75.png" |
|---|
| 236 | elseif qperc < 100 then |
|---|
| 237 | icon = "signal-75-100.png" |
|---|
| 238 | else |
|---|
| 239 | icon = "signal-0.png" |
|---|
| 240 | end |
|---|
| 241 | |
|---|
| 242 | signal_string = "<img src='"..resource.."/icons/"..icon.."' title='Signal: "..signal.." db / Noise: "..noise.." db' alt='Signal Quality'></img>" |
|---|
| 243 | |
|---|
| 244 | local ssid = net.iwinfo.ssid or "N/A" |
|---|
| 245 | local bssid = net.iwinfo.bssid or "N/A" |
|---|
| 246 | local chan = net.iwinfo.channel or "N/A" |
|---|
| 247 | local mode = net.iwinfo.mode or "N/A" |
|---|
| 248 | local txpwr = net.iwinfo.txpower or "N/A" |
|---|
| 249 | if txpwr ~= "N/A" then |
|---|
| 250 | txpwr = txpwr.." dbm" |
|---|
| 251 | end |
|---|
| 252 | local bitrate = net.iwinfo.bitrate or "N/A" |
|---|
| 253 | if bitrate ~= "N/A" then |
|---|
| 254 | bitrate = ( bitrate / 1000 ).."Mb/s" |
|---|
| 255 | end |
|---|
| 256 | local interface = net.iwdata.ifname or "N/A" |
|---|
| 257 | %> |
|---|
| 258 | <tr class="cbi-section-table-row cbi-rowstyle-1"> |
|---|
| 259 | <td class="cbi-value-field" id="<%=net:ifname()%>-signal"><%=signal_string%></td> |
|---|
| 260 | <td class="cbi-value-field" id="<%=net:ifname()%>-bitrate"><%=bitrate%></td> |
|---|
| 261 | <td class="cbi-value-field" id="<%=net:ifname()%>-ssid"><%=ssid%></td> |
|---|
| 262 | <td class="cbi-value-field" id="<%=net:ifname()%>-bssid"><%=bssid%></td> |
|---|
| 263 | <td class="cbi-value-field" id="<%=net:ifname()%>-channel"><%=chan%></td> |
|---|
| 264 | <td class="cbi-value-field" id="<%=net:ifname()%>-mode"><%=mode%></td> |
|---|
| 265 | <td class="cbi-value-field" id="<%=net:ifname()%>-txpower"><%=txpwr%></td> |
|---|
| 266 | <td class="cbi-value-field"><%=interface%></td> |
|---|
| 267 | </tr> |
|---|
| 268 | <% end |
|---|
| 269 | end |
|---|
| 270 | end %> |
|---|
| 271 | </table> |
|---|
| 272 | </div> |
|---|
| 273 | </div> |
|---|
| 274 | </div> |
|---|
| 275 | <% end %> |
|---|
| 276 | |
|---|
| 277 | <div class="cbi-map"> |
|---|
| 278 | <h2><%:Default routes%></h2> |
|---|
| 279 | <div class="cbi-section"> |
|---|
| 280 | <div class="cbi-section-node"> |
|---|
| 281 | |
|---|
| 282 | <% if not defroutev4 and not defroutev6 then %> |
|---|
| 283 | <%:No default routes known.%> |
|---|
| 284 | <%else%> |
|---|
| 285 | <table class="cbi-section-table"> |
|---|
| 286 | <tr class="cbi-section-table-titles"> |
|---|
| 287 | <th class="cbi-section-table-cell"><%:Network%></th> |
|---|
| 288 | <th class="cbi-section-table-cell"><%:Interface%></th> |
|---|
| 289 | <th class="cbi-section-table-cell"><%:Gateway%></th> |
|---|
| 290 | <th class="cbi-section-table-cell"><%:Metric%></th> |
|---|
| 291 | </tr> |
|---|
| 292 | |
|---|
| 293 | <% if defroutev4 then %> |
|---|
| 294 | |
|---|
| 295 | <tr class="cbi-section-table-row cbi-rowstyle-1"> |
|---|
| 296 | <td class="cbi-value-field" id="v4dst"><%=defroutev4.dest:string()%></td> |
|---|
| 297 | <td class="cbi-value-field" id="v4dev"><%=defroutev4.device%></td> |
|---|
| 298 | <td class="cbi-value-field" id="v4gw"><%=defroutev4.gateway:string()%></td> |
|---|
| 299 | <td class="cbi-value-field" id="v4metr"><%=defroutev4.metric%></td> |
|---|
| 300 | </tr> |
|---|
| 301 | |
|---|
| 302 | <% end |
|---|
| 303 | if defroutev6 then %> |
|---|
| 304 | |
|---|
| 305 | <tr class="cbi-section-table-row cbi-rowstyle-2"> |
|---|
| 306 | <td class="cbi-value-field" id="v6dst"><%=defroutev6.dest:string()%></td> |
|---|
| 307 | <td class="cbi-value-field" id="v6dev"><%=defroutev6.device%></td> |
|---|
| 308 | <td class="cbi-value-field" id="v6gw"><%=defroutev6.nexthop:string()%></td> |
|---|
| 309 | <td class="cbi-value-field" id="v6metr"><%=defroutev6.metric%></td> |
|---|
| 310 | </tr> |
|---|
| 311 | |
|---|
| 312 | <% end %> |
|---|
| 313 | |
|---|
| 314 | </table> |
|---|
| 315 | <% end %> |
|---|
| 316 | </div> |
|---|
| 317 | </div> |
|---|
| 318 | </div> |
|---|
| 319 | <%+footer%> |
|---|