932fe2912374331c8920ed4a4bdc17b0400199b9
[project/luci2/ui.git] / luci2 / htdocs / luci2 / view / status.overview.js
1 L.ui.view.extend({
2 title: L.tr('Status'),
3
4 getConntrackCount: L.rpc.declare({
5 object: 'luci2.network',
6 method: 'conntrack_count',
7 expect: { '': { count: 0, limit: 0 } }
8 }),
9
10 getDHCPLeases: L.rpc.declare({
11 object: 'luci2.network',
12 method: 'dhcp_leases',
13 expect: { leases: [ ] }
14 }),
15
16 getDHCPv6Leases: L.rpc.declare({
17 object: 'luci2.network',
18 method: 'dhcp6_leases',
19 expect: { leases: [ ] }
20 }),
21
22 renderContents: function() {
23 var self = this;
24 return $.when(
25 L.network.refreshStatus().then(function() {
26 var wan = L.network.findWAN();
27 var wan6 = L.network.findWAN6();
28
29 if (!wan && !wan6)
30 {
31 $('#network_status_table').empty();
32 return;
33 }
34
35 var networkTable = new L.ui.table({
36 caption: L.tr('Network'),
37 columns: [ {
38 width: '146px',
39 format: '%s'
40 }, {
41 width: '146px',
42 align: 'right',
43 format: function(v) {
44 var dev = L.network.resolveAlias(v.getDevice());
45 if (dev)
46 return $('<span />')
47 .addClass('badge')
48 .attr('title', dev.description())
49 .append($('<img />').attr('src', dev.icon()))
50 .append(' %s'.format(dev.name()));
51
52 return '';
53 }
54 }, {
55 format: function(v, n) {
56 var s = '<strong>' + L.tr('Type') + ':</strong> %s | ' +
57 '<strong>' + L.tr('Connected') + ':</strong> %t<br />';
58
59 s = s.format(v.getProtocol().description, v.getUptime(),
60 n ? v.getIPv6Addrs(true).join(', ')
61 : v.getIPv4Addrs(true).join(', '));
62
63 var addr = n ? v.getIPv6Addrs() : v.getIPv4Addrs();
64 if (addr.length)
65 s += '<strong>' + L.tr('Address') + ':</strong> %s<br />'.format(addr.join(', '));
66
67 var gw = v.getIPv4Gateway();
68 if (gw)
69 s += '<strong>' + L.tr('Gateway') + ':</strong> %s<br />'.format(gw);
70
71 var dns = n ? v.getIPv6DNS() : v.getIPv4DNS();
72 if (dns.length)
73 s += '<strong>' + L.tr('DNS') + ':</strong> %s<br />'.format(dns.join(', '));
74
75 return s;
76 }
77 } ]
78 });
79
80 if (wan)
81 networkTable.row([ L.tr('IPv4 WAN Status'), wan, wan ]);
82
83 if (wan6)
84 networkTable.row([ L.tr('IPv6 WAN Status'), wan6, wan6 ]);
85
86 networkTable.insertInto('#network_status_table');
87 }),
88 self.getConntrackCount().then(function(count) {
89 var conntrackTable = new L.ui.table({
90 caption: L.tr('Connection Tracking'),
91 columns: [ {
92 width: '300px'
93 }, {
94 format: function(v) {
95 return new L.ui.progress({
96 value: v.count,
97 max: v.limit,
98 format: '%d / %d (%d%%)'
99 }).render();
100 }
101 } ]
102 });
103
104 conntrackTable.row([ L.tr('Active Connections'), count ]);
105 conntrackTable.insertInto('#conntrack_status_table');
106 }),
107 L.system.getInfo().then(function(info) {
108 var sysinfoTable = new L.ui.table({
109 caption: L.tr('System'),
110 columns: [ { width: '300px' }, { } ]
111 });
112
113 sysinfoTable.rows([
114 [ L.tr('Hostname'), info.hostname ],
115 [ L.tr('Model'), info.model ],
116 [ L.tr('Firmware Version'), info.release.description ],
117 [ L.tr('Kernel Version'), info.kernel ],
118 [ L.tr('Local Time'), (new Date(info.localtime * 1000)).toString() ],
119 [ L.tr('Uptime'), '%t'.format(info.uptime) ],
120 [ L.tr('Load Average'),
121 '%.2f %.2f %.2f'.format(
122 info.load[0] / 65535.0,
123 info.load[1] / 65535.0,
124 info.load[2] / 65535.0
125 ) ]
126 ]);
127
128 sysinfoTable.insertInto('#system_status_table');
129
130 var memoryTable = new L.ui.table({
131 caption: L.tr('Memory'),
132 columns: [ {
133 format: '%s',
134 width: '300px'
135 }, {
136 format: function(v) {
137 return new L.ui.progress({
138 value: v,
139 max: info.memory.total,
140 format: function(pc) {
141 return ('%d ' + L.tr('kB') + ' / %d ' + L.tr('kB') + ' (%d%%)').format(
142 v / 1024, info.memory.total / 1024, pc
143 );
144 }
145 }).toString();
146 }
147 } ]
148 });
149
150 memoryTable.rows([
151 [ L.tr('Total Available'), info.memory.free + info.memory.buffered ],
152 [ L.tr('Free'), info.memory.free ],
153 [ L.tr('Cached'), info.memory.shared ],
154 [ L.tr('Buffered'), info.memory.buffered ],
155 ]);
156
157 memoryTable.insertInto('#memory_status_table');
158
159 if (info.swap.total > 0)
160 {
161 var swapTable = new L.ui.table({
162 caption: L.tr('Swap'),
163 columns: [ {
164 format: '%s',
165 width: '300px'
166 }, {
167 format: function(v) {
168 return new L.ui.progress({
169 value: v,
170 max: info.swap.total,
171 format: function(pc) {
172 return ('%d ' + L.tr('kB') + ' / %d ' + L.tr('kB') + ' (%d%%)').format(
173 v / 1024, info.swap.total / 1024, pc
174 );
175 }
176 }).toString();
177 }
178 } ]
179 });
180
181 swapTable.row([ L.tr('Free'), info.swap.free ]);
182 swapTable.insertInto('#swap_status_table');
183 }
184
185 var diskTable = new L.ui.table({
186 caption: L.tr('Storage'),
187 columns: [ {
188 format: '%s',
189 width: '300px'
190 }, {
191 format: function(v) {
192 return new L.ui.progress({
193 value: v[0],
194 max: v[1],
195 format: function(pc) {
196 return ('%d ' + L.tr('kB') + ' / %d ' + L.tr('kB') + ' (%d%%)').format(
197 v[0] / 1024, v[1] / 1024, pc
198 );
199 }
200 }).toString();
201 }
202 } ]
203 });
204
205 diskTable.row([ '' + L.tr('Root Usage') + ' (/)', [ info.root.used, info.root.total ] ]);
206 diskTable.row([ '' + L.tr('Temporary Usage') + ' (/tmp)', [ info.tmp.used, info.tmp.total ] ]);
207 diskTable.insertInto('#disk_status_table');
208 }),
209 L.wireless.getWirelessStatus().then(function(radios) {
210 var phys = [ ];
211 for (var phy in radios)
212 phys.push(phy);
213
214 phys.sort();
215
216 $('#wifi_status_table').empty();
217
218 for (var i = 0; i < phys.length; i++)
219 {
220 var rows = [ ];
221 var radio = radios[phys[i]];
222
223 rows.push([false, {
224 name: radio.hardware
225 ? '%s 802.11%s (%s)'.format(
226 radio.hardware.name, radio.hwmodes.join(''),
227 radio.phy.replace(/^[^0-9]+/, 'radio'))
228 : ('802.11%s ' + L.tr('Radio') + ' (%s)').format(
229 radio.hwmodes.join(''),
230 radio.phy.replace(/^[^0-9]+/, 'radio')),
231 channel: radio.channel,
232 frequency: radio.frequency,
233 txpower: radio.txpower
234 }]);
235
236 for (var j = 0; j < radio.networks.length; j++)
237 {
238 var network = radio.networks[j];
239
240 if (network.bssid && network.bssid != '00:00:00:00:00:00' && radio.channel)
241 rows[0][0] = true;
242
243 rows.push([{
244 signal: network.signal,
245 noise: network.noise,
246 device: network.device
247 }, {
248 ssid: network.ssid,
249 bssid: network.bssid,
250 mode: network.mode,
251 encryption: network.encryption,
252 bitrate: network.bitrate
253 }]);
254 }
255
256 var wifiTable = new L.ui.table({
257 caption: i ? null : L.tr('Wireless'),
258 columns: [ {
259 width: '34px',
260 align: 'right',
261 format: function(v, n)
262 {
263 if (typeof(v) != 'boolean')
264 {
265 return new L.ui.devicebadge(v).render();
266 }
267 else
268 {
269 var img = document.createElement('img');
270 img.src = L.globals.resource + '/icons/wifi_big' + (v ? '' : '_disabled') + '.png';
271
272 return img;
273 }
274 }
275 }, {
276 format: function(v, n)
277 {
278 if (typeof(rows[n][0]) != 'boolean')
279 {
280 var s = '<strong>' + L.tr('Mode') + ':</strong> %s | ' +
281 '<strong>' + L.tr('Bitrate') + ':</strong> %s | ' +
282 '<strong>' + L.tr('SSID') + ':</strong> %s<br />' +
283 '<strong>' + L.tr('BSSID') + ':</strong> %s | ' +
284 '<strong>' + L.tr('Encryption') + ':</strong> %s';
285
286 return s.format(
287 v.mode, v.bitrate ? ('~ %.1f ' + L.tr('Mbit/s')).format(v.bitrate / 1000) : '?',
288 v.ssid, v.bssid, L.wireless.formatEncryption(v.encryption)
289 );
290 }
291 else
292 {
293 var s = '<big><strong>%s</strong></big><br />' +
294 '<strong>' + L.tr('Channel') + ':</strong> %d (%.3f ' + L.tr('GHz') + ') | ' +
295 '<strong>' + L.tr('TX Power') + ':</strong> %d ' + L.tr('dBm') + '';
296
297 return s.format(
298 v.name,
299 v.channel, v.frequency / 1000,
300 v.txpower
301 );
302 }
303 }
304 } ]
305 });
306
307 wifiTable.rows(rows);
308 $('#wifi_status_table').append(wifiTable.render());
309 }
310 }),
311 L.wireless.getAssocLists().then(function(assoclist) {
312 var formatRate = function(v)
313 {
314 return (typeof v.mcs != 'undefined')
315 ? ('%.1f ' + L.tr('Mbit/s') + ', MCS %d, %d%s').format(v.rate / 1000, v.mcs, v['40mhz'] ? 40 : 20, L.tr('MHz'))
316 : ('%.1f ' + L.tr('Mbit/s')).format(v.rate / 1000);
317 };
318
319 var assocTable = new L.ui.table({
320 caption: L.tr('Associated Stations'),
321 placeholder: L.tr('No information available'),
322 columns: [ {
323 format: function(v, n) {
324 return new L.ui.devicebadge(assoclist[n]).render();
325 },
326 width: '34px',
327 align: 'right',
328 key: 'signal'
329 }, {
330 caption: L.tr('MAC-Address'),
331 key: 'mac'
332 }, {
333 caption: L.tr('Signal'),
334 format: '%d ' + L.tr('dBm') + '',
335 key: 'signal'
336 }, {
337 caption: L.tr('Noise'),
338 format: '%d ' + L.tr('dBm') + '',
339 key: 'noise'
340 }, {
341 caption: L.tr('RX Rate'),
342 format: formatRate,
343 key: 'rx'
344 }, {
345 caption: L.tr('TX Rate'),
346 format: formatRate,
347 key: 'tx'
348 } ]
349 });
350
351 assocTable.rows(assoclist);
352 assocTable.insertInto('#wifi_assoc_table');
353 }),
354 self.getDHCPLeases().then(function(leases) {
355 var leaseTable = new L.ui.table({
356 caption: L.tr('DHCP Leases'),
357 placeholder: L.tr('There are no active leases.'),
358 columns: [ {
359 caption: L.tr('Hostname'),
360 placeholder: '?',
361 key: 'hostname'
362 }, {
363 caption: L.tr('IPv4-Address'),
364 key: 'ipaddr'
365 }, {
366 caption: L.tr('MAC-Address'),
367 key: 'macaddr'
368 }, {
369 caption: L.tr('Leasetime remaining'),
370 key: 'expires',
371 format: function(v) {
372 return (v <= 0) ? L.tr('expired') : '%t'.format(v);
373 }
374 } ]
375 });
376
377 leaseTable.rows(leases);
378 leaseTable.insertInto('#lease_status_table');
379 }),
380 self.getDHCPv6Leases().then(function(leases) {
381 if (!leases.length)
382 return;
383
384 var leaseTable = new L.ui.table({
385 caption: L.tr('DHCPv6 Leases'),
386 columns: [ {
387 caption: L.tr('Hostname'),
388 placeholder: '?',
389 key: 'hostname'
390 }, {
391 caption: L.tr('IPv6-Address'),
392 key: 'ip6addr'
393 }, {
394 caption: L.tr('DUID'),
395 key: 'duid'
396 }, {
397 caption: L.tr('Leasetime remaining'),
398 key: 'expires',
399 format: function(v) {
400 return (v <= 0) ? L.tr('expired') : '%t'.format(v);
401 }
402 } ]
403 });
404
405 leaseTable.rows(leases);
406 leaseTable.insertInto('#lease6_status_table');
407 })
408 )
409 },
410
411 execute: function()
412 {
413 var self = this;
414 return L.network.load().then(function() {
415 self.repeat(self.renderContents, 5000);
416 });
417 }
418 });