luci-mod-dsl: add page with DSL status information
[project/luci.git] / modules / luci-mod-dsl / htdocs / luci-static / resources / view / status / dsl / stats.js
1 'use strict';
2 'require view';
3 'require dom';
4 'require poll';
5 'require rpc';
6
7 var callDSLMetrics = rpc.declare({
8 object: 'dsl',
9 method: 'metrics',
10 expect: { '': {} }
11 });
12
13 function format_on_off(val) {
14 return val ? _('on') : _('off');
15 }
16
17 function format_latency(val) {
18 return '%.2f ms'.format(val / 1000);
19 }
20
21 return view.extend({
22 load: function() {
23 return L.resolveDefault(callDSLMetrics(), {});
24 },
25
26 pollData: function(container) {
27 poll.add(L.bind(function() {
28 return L.resolveDefault(callDSLMetrics(), {}).then(L.bind(function(data) {
29 dom.content(container, this.renderContent(data));
30 }, this));
31 }, this));
32 },
33
34 formatHelper: function(format, val) {
35 if (val != null) {
36 if (format instanceof Function) {
37 return format(val);
38 } else if (typeof format === 'string') {
39 return format.format(val);
40 } else {
41 return val;
42 }
43 }
44 return '-';
45 },
46
47 renderSimpleTable: function(data) {
48 var table = E('table', { 'class': 'table' });
49
50 for (var [i, item] of data.entries()) {
51 var label = item[0];
52 var val = item[1];
53
54 var rowstyle = (i % 2 == 0) ? 'cbi-rowstyle-1' : 'cbi-rowstyle-2';
55
56 table.appendChild(E('tr', { 'class': 'tr ' + rowstyle }, [
57 E('td', { 'class': 'td left', 'width': '33%' }, [ label ]),
58 E('td', { 'class': 'td left' }, [ this.formatHelper(null, val) ])
59 ]));
60 }
61
62 return table;
63 },
64
65 renderTable: function(data) {
66 var table = E('table', { 'class': 'table' });
67
68 for (var [i, item] of data.entries()) {
69 var label = item[0];
70 var format = item[1];
71 var val1 = item[2];
72 var val2 = item[3];
73
74 var rowstyle = (i % 2 == 0) ? 'cbi-rowstyle-1' : 'cbi-rowstyle-2';
75
76 table.appendChild(E('tr', { 'class': 'tr ' + rowstyle }, [
77 E('td', { 'class': 'td left', 'width': '33%' }, [ label ]),
78 E('td', { 'class': 'td right', 'width': '33%' }, [ this.formatHelper(format, val1) ]),
79 E('td', { 'class': 'td right', 'width': '33%' }, [ this.formatHelper(format, val2) ])
80 ]));
81 }
82
83 return table;
84 },
85
86 renderContent: function(data) {
87 return E([], [
88
89 E('h3', {}, [ _('Connection State') ]),
90
91 this.renderSimpleTable([
92 [ _('Line State'), data.state ],
93 [ _('Line Mode'), data.mode ],
94 [ _('Line Uptime'), '%t'.format(data.uptime) ],
95 [ _('Annex'), data.annex ],
96 [ _('Power Management Mode'), data.power_state ]
97 ]),
98
99 E('h3', {}, [ _('Inventory') ]),
100
101 this.renderSimpleTable([
102 [ _('Modem Chipset'), data.chipset ],
103 [ _('Modem Firmware'), data.firmware_version ],
104 [ _('xTU-C Vendor ID'), data.atu_c.vendor || data.atu_c.vendor_id ]
105 ]),
106
107 E('h3', {}, [ _('Line Details') ]),
108
109 E('h4', {}, [ _('Data Rates') ]),
110 this.renderTable([
111 [ _('Actual Data Rate'), '%1000.3mb/s', data.downstream.data_rate, data.upstream.data_rate ],
112 [ _('Attainable Data Rate (ATTNDR)'), '%1000.3mb/s', data.downstream.attndr, data.upstream.attndr ],
113 [ _('Minimum Error-Free Throughput (MINEFTR)'), '%1000.3mb/s', data.downstream.mineftr, data.upstream.mineftr ]
114 ]),
115
116 E('h4', {}, [ _('On-line Reconfiguration') ]),
117 this.renderTable([
118 [ _('Bitswap'), format_on_off, data.downstream.bitswap, data.upstream.bitswap ],
119 [ _('Rate Adaptation Mode'), '%s', data.downstream.ra_mode, data.upstream.ra_mode ]
120 ]),
121
122 E('h4', {}, [ _('Noise Protection') ]),
123 this.renderTable([
124 [ _('Latency'), format_latency, data.downstream.interleave_delay, data.upstream.interleave_delay ],
125 [ _('Impulse Noise Protection (INP)'), '%.1f symbols', data.downstream.inp, data.upstream.inp ],
126 [ _('Retransmission (G.INP)'), format_on_off, data.downstream.retx, data.upstream.retx ]
127 ]),
128
129 E('h4', {}, [ _('Line Parameters') ]),
130 this.renderTable([
131 [ _('Line Attenuation (LATN)'), '%.1f dB', data.downstream.latn, data.upstream.latn ],
132 [ _('Signal Attenuation (SATN)'), '%.1f dB', data.downstream.satn, data.upstream.satn ],
133 [ _('Noise Margin (SNRM)'), '%.1f dB', data.downstream.snr, data.upstream.snr ],
134 [ _('Aggregate Transmit Power (ACTATP)'), '%.1f dB', data.downstream.actatp, data.upstream.actatp ]
135 ]),
136
137 E('h3', {}, [ _('Error Counters') ]),
138
139 E('h4', {}, [ _('Error Seconds') ]),
140 this.renderTable([
141 [ _('Forward Error Correction Seconds (FECS)'), '%d', data.errors.near.fecs, data.errors.far.fecs ],
142 [ _('Errored Seconds (ES)'), '%d', data.errors.near.es, data.errors.far.es ],
143 [ _('Severely Errored Seconds (SES)'), '%d', data.errors.near.ses, data.errors.far.ses ],
144 [ _('Loss of Signal Seconds (LOSS)'), '%d', data.errors.near.loss, data.errors.far.loss ],
145 [ _('Unavailable Seconds (UAS)'), '%d', data.errors.near.uas, data.errors.far.uas ],
146 [ _('Seconds with Low Error-Free Throughput (LEFTRS)'), '%d', data.errors.near.leftrs, data.errors.far.leftrs ]
147 ]),
148
149 E('h4', {}, [ _('Channel Counters') ]),
150 this.renderTable([
151 [ _('CRC Errors (CV-C)'), '%d', data.errors.near.cv_c, data.errors.far.cv_c ],
152 [ _('Corrected by FEC (FEC-C)'), '%d', data.errors.near.fec_c, data.errors.far.fec_c ]
153 ]),
154
155 E('h4', {}, [ _('Data Path Counters') ]),
156 this.renderTable([
157 [ _('ATM Header Error Code Errors (HEC-P)'), '%d', data.errors.near.hec, data.errors.far.hec ],
158 [ _('PTM Non Pre-emptive CRC Errors (CRC-P)'), '%d', data.errors.near.crc_p, data.errors.far.crc_p ],
159 [ _('PTM Pre-emptive CRC Errors (CRCP-P)'), '%d', data.errors.near.crcp_p, data.errors.far.crcp_p ]
160 ]),
161
162 E('h4', {}, [ _('Retransmission Counters') ]),
163 this.renderTable([
164 [ _('Retransmitted DTUs (rtx-tx)'), '%d', data.errors.far.tx_retransmitted, data.errors.near.tx_retransmitted ],
165 [ _('Corrected DTUs (rtx-c)'), '%d', data.errors.near.rx_corrected, data.errors.far.rx_corrected ],
166 [ _('Uncorrected DTUs (rtx-uc)'), '%d', data.errors.near.rx_uncorrected_protected, data.errors.far.rx_uncorrected_protected ]
167 ])
168
169 ]);
170 },
171
172 render: function(data) {
173 var v = E([], [
174 E('h2', {}, [ _('DSL stats') ]),
175 E('div')
176 ]);
177
178 var container = v.lastElementChild;
179 dom.content(container, this.renderContent(data));
180 this.pollData(container);
181
182 return v;
183 },
184
185 handleSaveApply: null,
186 handleSave: null,
187 handleReset: null
188 });