🌴 Sync 2026-03-05 23:51:42

This commit is contained in:
github-actions[bot] committed 2026-03-05 23:51:42 +08:00
1 parent 97c049ed0a
commit 0acff03804
14253 files changed
+3893239

No files matched your search

@@ -0,0 +1,166 @@
'use strict';
'require baseclass';
'require form';
'require fs';
'require view';
'require ui';
'require uci';
'require poll';
'require dom';
'require tools.widgets as widgets';
/*
Copyright Konstantine Shevlakov <shevlakov@132lan.ru> 2023
Licensed to the GNU General Public License v3.0.
*/
return view.extend({
load: function(data) {
return L.resolveDefault(fs.exec_direct('/usr/bin/modeminfo'));
},
polldata: poll.add(function() {
return L.resolveDefault(fs.exec_direct('/usr/bin/modeminfo')).then(function(res) {
var json = JSON.parse(res);
if (!json || !json.modem || !Array.isArray(json.modem)) return;
for (var i = 0; i < json.modem.length; i++) {
if (document.getElementById('device'+i)) {
var view = document.getElementById('device'+i);
if (json.modem[i].device == '--') {
view = document.getElementById('--');
} else {
view.innerHTML = String.format(json.modem[i].device);
}
}
if (document.getElementById('firmware'+i)) {
var view = document.getElementById('firmware'+i);
if (json.modem[i].firmware == '--') {
view = document.getElementById('--');
} else {
view.innerHTML = String.format(json.modem[i].firmware);
}
}
if (document.getElementById('imsi'+i)) {
var view = document.getElementById('imsi'+i);
if (json.modem[i].imsi == '--') {
view = document.getElementById('--');
} else {
view.innerHTML = String.format(json.modem[i].imsi);
}
}
if (document.getElementById('iccid'+i)) {
var view = document.getElementById('iccid'+i);
if (json.modem[i].iccid == '--') {
view = document.getElementById('--');
} else {
view.innerHTML = String.format(json.modem[i].iccid);
}
}
if (document.getElementById('imei'+i)) {
var view = document.getElementById('imei'+i);
if (json.modem[i].imei == '--') {
view = document.getElementById('--');
} else {
view.innerHTML = String.format(json.modem[i].imei);
}
}
if (document.getElementById('chiptemp'+i)) {
var view = document.getElementById('chiptemp'+i);
if (json.modem[i].chiptemp == '--') {
view = document.getElementById('--');
} else {
view.innerHTML = String.format(json.modem[i].chiptemp+' °C');
}
}
};
});
}),
render: function(data){
var m, s, o;
m = new form.Map('modeminfo', _('Modeminfo: Hardware'), _('Hardware and sim-card info.'));
s = m.section(form.TypedSection, 'general', null);
var json = JSON.parse(data);
// for future use
/*
var vendors = [];
var duplicate_modem_index = 1;
json.modem.forEach(obj => {
const device = obj.device;
if (!vendors.includes(device)) {
vendors.push(device);
} else {
vendors.push(device+" ("+duplicate_modem_index+")");
duplicate_modem_index++;
}
});
*/
for (var i = 0; i < json.modem.length; i++) {
let device = 'device'+i;
let firmware = 'firmware'+i;
let imsi = 'imsi'+i;
let iccid = 'iccid'+i;
let imei = 'imei'+i;
let chiptemp = 'chiptemp'+i;
let m = i+1;
if ( json.modem.length > 1 ) {
s.tab('modem'+i, _('Modem')+' '+m);
o = s.taboption('modem'+i, form.HiddenValue, 'generic');
} else {
o = s.option(form.HiddenValue, 'generic');
}
o.render = L.bind(function(data){
return (
E('div', {}, [
E('h3', { 'class': 'data-tab' }),
E('div', { 'class': 'cbi-section', 'data-title': 'modem'+i }, [
E('table', { 'class': 'table' }, [
E('tr', { 'class': 'tr cbi-rowstyle-2' }, [
E('td', { 'class': 'td left', 'width': '50%' }, [ _('Device')]),
E('td', { 'class': 'td left', 'id': device }, [ '--' ]),
]),
E('tr', { 'class': 'tr cbi-rowstyle-1' }, [
E('td', { 'class': 'td left', 'width': '50%' }, [ _('Firmware')]),
E('td', { 'class': 'td left', 'id': firmware }, [ '--' ]),
]),
E('tr', { 'class': 'tr cbi-rowstyle-2' }, [
E('td', { 'class': 'td left', 'width': '50%' }, [ _('IMSI')]),
E('td', { 'class': 'td left', 'id': imsi }, [ '--' ]),
]),
E('tr', { 'class': 'tr cbi-rowstyle-1' }, [
E('td', { 'class': 'td left', 'width': '50%' }, [ _('ICCID')]),
E('td', { 'class': 'td left', 'id': iccid }, [ '--' ]),
]),
E('tr', { 'class': 'tr cbi-rowstyle-2' }, [
E('td', { 'class': 'td left', 'width': '50%' }, [ _('IMEI')]),
E('td', { 'class': 'td left', 'id': imei }, [ '--' ]),
]),
E('tr', { 'class': 'tr cbi-rowstyle-1' }, [
E('td', { 'class': 'td left', 'width': '50%' }, [ _('Chiptemp')]),
E('td', { 'class': 'td left', 'id': chiptemp }, [ '--' ]),
])
])
]),
]
)
)}, o, this.polldata);
o.anonymous = true;
o.rmempty = true;
};
s.anonymous = true;
return m.render();
},
handleSaveApply: null,
handleSave: null,
handleReset: null
});
@@ -0,0 +1 @@
<svg height="32" width="32" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="b"><stop offset="0" stop-color="#aaa"/><stop offset="1" stop-color="#f0f0f0"/></linearGradient><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="76" x2="76" xlink:href="#b" y1="14" y2="-66"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="56" x2="56" xlink:href="#b" y1="14" y2="-50"/><linearGradient id="e" gradientUnits="userSpaceOnUse" x1="44" x2="44" xlink:href="#b" y1="14" y2="-34"/><linearGradient id="f" gradientUnits="userSpaceOnUse" x1="16" x2="16" xlink:href="#b" y1="14" y2="-18"/><linearGradient id="g" gradientUnits="userSpaceOnUse" x1="78" x2="78" xlink:href="#a" y1="-66" y2="6.027772"/><linearGradient id="h" gradientUnits="userSpaceOnUse" x1="19" x2="19" xlink:href="#a" y1="-18" y2="14.140317"/><linearGradient id="i" gradientUnits="userSpaceOnUse" x1="37" x2="37" xlink:href="#a" y1="-34" y2="14.010415"/><linearGradient id="j" gradientUnits="userSpaceOnUse" x1="57" x2="57" xlink:href="#a" y1="-50" y2="14.007812"/><g transform="translate(0 74)"><path d="m74-67.96875c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v24c0 3.827486 3.141264 6.96875 6.96875 6.96875h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c3.827486 0 6.96875-3.141264 6.96875-6.96875v-72c0-3.827486-3.141264-6.96875-6.96875-6.96875z" opacity=".08"/><path d="m74-66.96875c-3.283091 0-5.96875 2.685659-5.96875 5.96875v72c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-72c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v56c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-56c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v40c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-40c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v24c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-24c0-3.283091-2.685659-5.96875-5.96875-5.96875z" opacity=".1"/><path d="m74-66.03125c-2.763365 0-5.03125 2.267885-5.03125 5.03125v72c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-72c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v56c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-56c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v40c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-40c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v24c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-24c0-2.763365-2.267885-5.03125-5.03125-5.03125z" opacity=".15"/><path d="m74-65c-2.216 0-4 1.784-4 4v72c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-72c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v56c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-56c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v40c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-40c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v24c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-24c0-2.216-1.784-4-4-4z" opacity=".3"/><rect fill="url(#c)" height="80" rx="4" width="16" x="70" y="-66"/><rect fill="url(#d)" height="64" rx="4" width="16" x="50" y="-50"/><rect fill="url(#e)" height="48" rx="4" width="16" x="30" y="-34"/><rect fill="url(#f)" height="32" rx="4" width="16" x="10" y="-18"/><path d="m74-66c-2.216 0-4 1.784-4 4v72c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-72c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 1.333678 3.03125 3.03125v72c0 1.273179-.75249 2.326579-1.84375 2.78125 1.628072-.506247 2.8125-1.982301 2.8125-3.78125v-72c0-2.216-1.784-4-4-4z" fill="url(#g)" opacity=".6"/><path d="m54-50c-2.216 0-4 1.784-4 4v56c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-56c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 1.333678 3.03125 3.03125v56c0 1.273179-.75249 2.326579-1.84375 2.78125 1.62807Line truncated

After

Width:  |  Height:  |  Size: 5.7 KiB

@@ -0,0 +1 @@
<svg height="32" width="32" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="b"><stop offset="0" stop-color="#aaa"/><stop offset="1" stop-color="#f0f0f0"/></linearGradient><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="76" x2="76" xlink:href="#b" y1="14" y2="-66"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="56" x2="56" xlink:href="#b" y1="14" y2="-50"/><linearGradient id="e" gradientUnits="userSpaceOnUse" x1="44" x2="44" xlink:href="#b" y1="14" y2="-34"/><linearGradient id="f" gradientUnits="userSpaceOnUse" x1="16" x2="16" y1="14" y2="-18"><stop offset="0" stop-color="#395d93"/><stop offset="1" stop-color="#6e92c7"/></linearGradient><linearGradient id="g" gradientUnits="userSpaceOnUse" x1="78" x2="78" xlink:href="#a" y1="-66" y2="6.027772"/><linearGradient id="h" gradientUnits="userSpaceOnUse" x1="19" x2="19" xlink:href="#a" y1="-18" y2="14.140317"/><linearGradient id="i" gradientUnits="userSpaceOnUse" x1="37" x2="37" xlink:href="#a" y1="-34" y2="14.010415"/><linearGradient id="j" gradientUnits="userSpaceOnUse" x1="57" x2="57" xlink:href="#a" y1="-50" y2="14.007812"/><g transform="translate(0 74)"><path d="m74-67.96875c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v24c0 3.827486 3.141264 6.96875 6.96875 6.96875h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c3.827486 0 6.96875-3.141264 6.96875-6.96875v-72c0-3.827486-3.141264-6.96875-6.96875-6.96875z" opacity=".08"/><path d="m74-66.96875c-3.283091 0-5.96875 2.685659-5.96875 5.96875v72c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-72c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v56c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-56c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v40c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-40c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v24c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-24c0-3.283091-2.685659-5.96875-5.96875-5.96875z" opacity=".1"/><path d="m74-66.03125c-2.763365 0-5.03125 2.267885-5.03125 5.03125v72c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-72c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v56c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-56c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v40c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-40c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v24c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-24c0-2.763365-2.267885-5.03125-5.03125-5.03125z" opacity=".15"/><path d="m74-65c-2.216 0-4 1.784-4 4v72c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-72c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v56c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-56c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v40c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-40c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v24c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-24c0-2.216-1.784-4-4-4z" opacity=".3"/><rect fill="url(#c)" height="80" rx="4" width="16" x="70" y="-66"/><rect fill="url(#d)" height="64" rx="4" width="16" x="50" y="-50"/><rect fill="url(#e)" height="48" rx="4" width="16" x="30" y="-34"/><rect fill="url(#f)" height="32" rx="4" width="16" x="10" y="-18"/><path d="m74-66c-2.216 0-4 1.784-4 4v72c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-72c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 1.333678 3.03125 3.03125v72c0 1.273179-.75249 2.326579-1.84375 2.78125 1.628072-.506247 2.8125-1.982301 2.8125-3.78125v-72c0-2.216-1.784-4-4-4z" fill="url(#g)" opacity=".6"/><path d="m54-50c-2.216 0-4 1.784-4 4v56c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-56c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 Line truncated

After

Width:  |  Height:  |  Size: 5.8 KiB

@@ -0,0 +1 @@
<svg height="32" width="32" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="b"><stop offset="0" stop-color="#395d93"/><stop offset="1" stop-color="#6e92c7"/></linearGradient><linearGradient id="c"><stop offset="0" stop-color="#aaa"/><stop offset="1" stop-color="#f0f0f0"/></linearGradient><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="76" x2="76" xlink:href="#c" y1="14" y2="-66"/><linearGradient id="e" gradientUnits="userSpaceOnUse" x1="56" x2="56" xlink:href="#c" y1="14" y2="-50"/><linearGradient id="f" gradientUnits="userSpaceOnUse" x1="44" x2="44" xlink:href="#b" y1="14" y2="-34"/><linearGradient id="g" gradientUnits="userSpaceOnUse" x1="16" x2="16" xlink:href="#b" y1="14" y2="-18"/><linearGradient id="h" gradientUnits="userSpaceOnUse" x1="78" x2="78" xlink:href="#a" y1="-66" y2="6.027772"/><linearGradient id="i" gradientUnits="userSpaceOnUse" x1="19" x2="19" xlink:href="#a" y1="-18" y2="14.140317"/><linearGradient id="j" gradientUnits="userSpaceOnUse" x1="37" x2="37" xlink:href="#a" y1="-34" y2="14.010415"/><linearGradient id="k" gradientUnits="userSpaceOnUse" x1="57" x2="57" xlink:href="#a" y1="-50" y2="14.007812"/><g transform="translate(0 74)"><path d="m74-67.96875c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v24c0 3.827486 3.141264 6.96875 6.96875 6.96875h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c3.827486 0 6.96875-3.141264 6.96875-6.96875v-72c0-3.827486-3.141264-6.96875-6.96875-6.96875z" opacity=".08"/><path d="m74-66.96875c-3.283091 0-5.96875 2.685659-5.96875 5.96875v72c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-72c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v56c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-56c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v40c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-40c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v24c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-24c0-3.283091-2.685659-5.96875-5.96875-5.96875z" opacity=".1"/><path d="m74-66.03125c-2.763365 0-5.03125 2.267885-5.03125 5.03125v72c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-72c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v56c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-56c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v40c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-40c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v24c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-24c0-2.763365-2.267885-5.03125-5.03125-5.03125z" opacity=".15"/><path d="m74-65c-2.216 0-4 1.784-4 4v72c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-72c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v56c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-56c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v40c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-40c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v24c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-24c0-2.216-1.784-4-4-4z" opacity=".3"/><rect fill="url(#d)" height="80" rx="4" width="16" x="70" y="-66"/><rect fill="url(#e)" height="64" rx="4" width="16" x="50" y="-50"/><rect fill="url(#f)" height="48" rx="4" width="16" x="30" y="-34"/><rect fill="url(#g)" height="32" rx="4" width="16" x="10" y="-18"/><path d="m74-66c-2.216 0-4 1.784-4 4v72c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-72c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 1.333678 3.03125 3.03125v72c0 1.273179-.75249 2.326579-1.84375 2.78125 1.628072-.506247 2.8125-1.982301 2.8125-3.78125v-72c0-2.216-1.784-4-4-4z" fill="url(#h)" opacity=".6"/><path d="m54-50c-2.216 0-4 1.784-4 4v56c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-56c0-1.697572 1.333678-3.031Line truncated

After

Width:  |  Height:  |  Size: 5.8 KiB

@@ -0,0 +1 @@
<svg height="32" width="32" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="b"><stop offset="0" stop-color="#395d93"/><stop offset="1" stop-color="#6e92c7"/></linearGradient><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="76" x2="76" y1="14" y2="-66"><stop offset="0" stop-color="#aaa"/><stop offset="1" stop-color="#f0f0f0"/></linearGradient><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="56" x2="56" xlink:href="#b" y1="14" y2="-50"/><linearGradient id="e" gradientUnits="userSpaceOnUse" x1="44" x2="44" xlink:href="#b" y1="14" y2="-34"/><linearGradient id="f" gradientUnits="userSpaceOnUse" x1="16" x2="16" xlink:href="#b" y1="14" y2="-18"/><linearGradient id="g" gradientUnits="userSpaceOnUse" x1="78" x2="78" xlink:href="#a" y1="-66" y2="6.027772"/><linearGradient id="h" gradientUnits="userSpaceOnUse" x1="19" x2="19" xlink:href="#a" y1="-18" y2="14.140317"/><linearGradient id="i" gradientUnits="userSpaceOnUse" x1="37" x2="37" xlink:href="#a" y1="-34" y2="14.010415"/><linearGradient id="j" gradientUnits="userSpaceOnUse" x1="57" x2="57" xlink:href="#a" y1="-50" y2="14.007812"/><g transform="translate(0 74)"><path d="m74-67.96875c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v24c0 3.827486 3.141264 6.96875 6.96875 6.96875h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c3.827486 0 6.96875-3.141264 6.96875-6.96875v-72c0-3.827486-3.141264-6.96875-6.96875-6.96875z" opacity=".08"/><path d="m74-66.96875c-3.283091 0-5.96875 2.685659-5.96875 5.96875v72c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-72c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v56c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-56c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v40c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-40c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v24c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-24c0-3.283091-2.685659-5.96875-5.96875-5.96875z" opacity=".1"/><path d="m74-66.03125c-2.763365 0-5.03125 2.267885-5.03125 5.03125v72c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-72c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v56c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-56c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v40c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-40c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v24c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-24c0-2.763365-2.267885-5.03125-5.03125-5.03125z" opacity=".15"/><path d="m74-65c-2.216 0-4 1.784-4 4v72c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-72c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v56c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-56c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v40c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-40c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v24c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-24c0-2.216-1.784-4-4-4z" opacity=".3"/><rect fill="url(#c)" height="80" rx="4" width="16" x="70" y="-66"/><rect fill="url(#d)" height="64" rx="4" width="16" x="50" y="-50"/><rect fill="url(#e)" height="48" rx="4" width="16" x="30" y="-34"/><rect fill="url(#f)" height="32" rx="4" width="16" x="10" y="-18"/><path d="m74-66c-2.216 0-4 1.784-4 4v72c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-72c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 1.333678 3.03125 3.03125v72c0 1.273179-.75249 2.326579-1.84375 2.78125 1.628072-.506247 2.8125-1.982301 2.8125-3.78125v-72c0-2.216-1.784-4-4-4z" fill="url(#g)" opacity=".6"/><path d="m54-50c-2.216 0-4 1.784-4 4v56c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-56c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 Line truncated

After

Width:  |  Height:  |  Size: 5.8 KiB

@@ -0,0 +1 @@
<svg height="32" width="32" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="b"><stop offset="0" stop-color="#395d93"/><stop offset="1" stop-color="#6e92c7"/></linearGradient><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="76" x2="76" xlink:href="#b" y1="14" y2="-66"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="56" x2="56" xlink:href="#b" y1="14" y2="-50"/><linearGradient id="e" gradientUnits="userSpaceOnUse" x1="44" x2="44" xlink:href="#b" y1="14" y2="-34"/><linearGradient id="f" gradientUnits="userSpaceOnUse" x1="16" x2="16" xlink:href="#b" y1="14" y2="-18"/><linearGradient id="g" gradientUnits="userSpaceOnUse" x1="78" x2="78" xlink:href="#a" y1="-66" y2="6.027772"/><linearGradient id="h" gradientUnits="userSpaceOnUse" x1="19" x2="19" xlink:href="#a" y1="-18" y2="14.140317"/><linearGradient id="i" gradientUnits="userSpaceOnUse" x1="37" x2="37" xlink:href="#a" y1="-34" y2="14.010415"/><linearGradient id="j" gradientUnits="userSpaceOnUse" x1="57" x2="57" xlink:href="#a" y1="-50" y2="14.007812"/><g transform="translate(0 74)"><path d="m74-67.96875c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v24c0 3.827486 3.141264 6.96875 6.96875 6.96875h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c3.827486 0 6.96875-3.141264 6.96875-6.96875v-72c0-3.827486-3.141264-6.96875-6.96875-6.96875z" opacity=".08"/><path d="m74-66.96875c-3.283091 0-5.96875 2.685659-5.96875 5.96875v72c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-72c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v56c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-56c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v40c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-40c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v24c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-24c0-3.283091-2.685659-5.96875-5.96875-5.96875z" opacity=".1"/><path d="m74-66.03125c-2.763365 0-5.03125 2.267885-5.03125 5.03125v72c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-72c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v56c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-56c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v40c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-40c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v24c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-24c0-2.763365-2.267885-5.03125-5.03125-5.03125z" opacity=".15"/><path d="m74-65c-2.216 0-4 1.784-4 4v72c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-72c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v56c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-56c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v40c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-40c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v24c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-24c0-2.216-1.784-4-4-4z" opacity=".3"/><rect fill="url(#c)" height="80" rx="4" width="16" x="70" y="-66"/><rect fill="url(#d)" height="64" rx="4" width="16" x="50" y="-50"/><rect fill="url(#e)" height="48" rx="4" width="16" x="30" y="-34"/><rect fill="url(#f)" height="32" rx="4" width="16" x="10" y="-18"/><path d="m74-66c-2.216 0-4 1.784-4 4v72c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-72c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 1.333678 3.03125 3.03125v72c0 1.273179-.75249 2.326579-1.84375 2.78125 1.628072-.506247 2.8125-1.982301 2.8125-3.78125v-72c0-2.216-1.784-4-4-4z" fill="url(#g)" opacity=".6"/><path d="m54-50c-2.216 0-4 1.784-4 4v56c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-56c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 1.333678 3.03125 3.03125v56c0 1.273179-.75249 2.326579-1.84375 2.78125 1.62Line truncated

After

Width:  |  Height:  |  Size: 5.7 KiB

@@ -0,0 +1,472 @@
'use strict';
'require baseclass';
'require form';
'require fs';
'require view';
'require ui';
'require uci';
'require poll';
'require dom';
'require tools.widgets as widgets';
/*
Copyright Konstantine Shevlakov <shevlakov@132lan.ru> 2023
Licensed to the GNU General Public License v3.0.
*/
const REGISTERED_STATUSES = [1, 6, 9];
const ROAMING_STATUSES = [3, 5, 7, 10];
return view.extend({
load: function(data) {
return L.resolveDefault(fs.exec_direct('/usr/bin/modeminfo'), '{"modem": []}');
},
polldata: poll.add(function() {
return L.resolveDefault(fs.exec_direct('/usr/bin/modeminfo'), '{"modem": []}').then(function(res) {
var json = JSON.parse(res);
if (!json || !json.modem || !Array.isArray(json.modem)) return;
for (var i = 0; i < json.modem.length; i++) {
// progressbar cellular metric
const progressConfig = {
rssi: {
selector: '#rssi', min: -110, max: -50,
calc: (vn, mn) => Math.floor(100 * (1 - (-50 - vn) / (-50 - mn)))
},
rsrp: {
selector: '#rsrp', min: -140, max: -50,
calc: (vn, mn) => Math.floor(120 * (1 - (-50 - vn) / (-70 - mn)))
},
sinr: {
selector: '#sinr', min: -20, max: 30,
calc: (vn, mn) => Math.floor(100 - (100 * (1 - ((mn - vn) / (mn - 30)))))
},
rsrq: {
selector: '#rsrq', min: -20, max: 0,
calc: (vn, mn) => Math.floor(115 - (100 / mn) * vn)
},
ecio: {
selector: '#sinr', min: -24, max: 0,
calc: (vn, mn) => Math.floor(100 - (100 / mn) * vn)
}
};
function updateProgressBar(type, value, max, i) {
const config = progressConfig[type];
if (!config) return;
const pg = document.querySelector(`${config.selector}${i}`);
if (!pg) return;
const vn = Math.max(config.min, Math.min(config.max, parseInt(value) || 0));
const mn = parseInt(max) || 100;
const pc = config.calc(vn, mn);
pg.firstElementChild.style.width = `${pc}%`;
pg.style.width = '%d%%';
pg.firstElementChild.style.animationDirection = "reverse";
pg.setAttribute('title', '%s'.format(value));
}
function formatDistance(dist) {
if (!dist || dist === "--" || dist === "" || dist === "0.00") {
return '';
}
return ' ~' + dist + ' km';
}
function formatModemStatus(modem, icon, reg) {
var rg = parseInt(modem.reg) || 0;
var p = modem.csq_per || 0;
var cops = modem.cops || '--';
var color = modem.csq_col || '#000000';
var distanceHtml = formatDistance(modem.distance);
var iconHtml = icon ? '<img class="modem-signal-icon" src="' + icon + '"/>' : '';
var percentWithColor = p + '%';
if (REGISTERED_STATUSES.includes(rg)) {
return '<span class="ifacebadge">' + cops + ' ' + iconHtml +
' <b style="color:' + color + '">' + percentWithColor + '</b>' +
distanceHtml + '</span>';
} else if (ROAMING_STATUSES.includes(rg)) {
return '<span class="ifacebadge">' + cops + ' (' + reg + ') ' + iconHtml +
' <b style="color:' + color + '">' + percentWithColor + '</b>' +
distanceHtml + '</span>';
} else {
return '<span class="ifacebadge">' + (reg || '--') + '</span>';
}
}
// icon signal strength
var icn;
var signalIcons = [
{ max: -1, icn: 'signal-000-000.svg' },
{ max: 0, icn: 'signal-000-000.svg' },
{ max: 10, icn: 'signal-000-000.svg' },
{ max: 25, icn: 'signal-000-025.svg' },
{ max: 50, icn: 'signal-025-050.svg' },
{ max: 75, icn: 'signal-050-075.svg' },
{ max: Infinity, icn: 'signal-075-100.svg' }
];
var p = json.modem[i].csq_per || 0;
var { icn } = signalIcons.find(({ max }) => p <= max);
var icon = L.resource(`view/modem/icons/${icn}`);
// Registration Status
var regStatuses = new Map([
[0, _('No Registration')],
[2, _('Searching')], [8, _('Searching')],
[3, _('Denied')],
[4, _('Unknown')],
[5, _('Roaming')], [7, _('Roaming')], [10, _('Roaming')]
]);
var rg = Number(json.modem[i].reg);
var reg = regStatuses.get(rg) || _('No Data');
// frequency band calculator
var offset, band, bw, frdl, frul;
var netmode = (json.modem[i].mode)
var rfcn = (json.modem[i].arfcn)
if (netmode === "LTE") {
// list LTE-bans
var lteBands = [
{ min: 0, max: 599, frdl: 2110, frul: 1920, offset: 0, band: "1" },
{ min: 600, max: 1199, frdl: 1930, frul: 1850, offset: 600, band: "2" },
{ min: 1200, max: 1949, frdl: 1805, frul: 1710, offset: 1200, band: "3" },
{ min: 1950, max: 2399, frdl: 2110, frul: 1710, offset: 1950, band: "4" },
{ min: 2400, max: 2469, frdl: 869, frul: 824, offset: 2400, band: "5" },
{ min: 2750, max: 3449, frdl: 2620, frul: 2500, offset: 2750, band: "7" },
{ min: 3450, max: 3799, frdl: 925, frul: 880, offset: 3450, band: "8" },
{ min: 6150, max: 6449, frdl: 791, frul: 832, offset: 6150, band: "20" },
{ min: 9210, max: 9659, frdl: 758, frul: 703, offset: 9210, band: "28" },
{ min: 9870, max: 9919, frdl: 452.5, frul: 462.5, offset: 9870, band: "31" },
{ min: 37750, max: 38249, frdl: 2570, frul: 2570, offset: 37750, band: "38" },
{ min: 38650, max: 39649, frdl: 2300, frul: 2300, offset: 38650, band: "40" },
{ min: 39650, max: 41589, frdl: 2496, frul: 2496, offset: 39650, band: "41" }
];
var bandConfig = lteBands.find(b => rfcn >= b.min && rfcn <= b.max) || {
frdl: 0, frul: 0, offset: 0, band: rfcn
};
({ frdl, frul, offset, band } = bandConfig);
// Bandwidth channel (bw)
var bandwidths = [1.4, 3, 5, 10, 15, 20];
var bw = bandwidths[json.modem[i].bwdl] || "";
// Calc frequency
var dlfreq = frdl + (rfcn - offset) / 10;
var ulfreq = frul + (rfcn - offset) / 10;
} else {
var nonLteBands = [
{
condition: (rfcn) => rfcn >= 10562 && rfcn <= 10838,
calc: (rfcn) => ({ offset: 950, dlfreq: rfcn / 5, ulfreq: (rfcn - 950) / 5, band: "IMT2100" })
},
{
condition: (rfcn) => rfcn >= 2937 && rfcn <= 3088,
calc: (rfcn) => ({ frul: 925, offset: 340, ulfreq: 340 + (rfcn / 5), dlfreq: (340 + (rfcn / 5)) - 45, band: "UMTS900" })
},
{
condition: (rfcn) => rfcn >= 955 && rfcn <= 1023,
calc: (rfcn) => ({ frul: 890, ulfreq: 890 + ((rfcn - 1024) / 5), dlfreq: (890 + ((rfcn - 1024) / 5)) + 45, band: "DSC900" })
},
{
condition: (rfcn) => rfcn >= 512 && rfcn <= 885,
calc: (rfcn) => ({ frul: 1710, ulfreq: 1710 + ((rfcn - 512) / 5), dlfreq: (1710 + ((rfcn - 512) / 5)) + 95, band: "DCS1800" })
},
{
condition: (rfcn) => rfcn >= 1 && rfcn <= 124,
calc: (rfcn) => ({ frul: 890, ulfreq: 890 + (rfcn / 5), dlfreq: (890 + (rfcn / 5)) + 45, band: "GSM900" })
}
];
var bandConfig = nonLteBands.find(b => b.condition(rfcn))?.calc(rfcn) || { ulfreq: 0, dlfreq: 0, band: String(rfcn) };
// CALC BANDS
({ frul, offset, ulfreq, dlfreq, band } = bandConfig);
}
var carrier = "";
var bcc, freq, distance, calte, namebnd;
var dist = (json.modem[i].distance)
var { enbid, cell, pci, lac, cid } = json.modem[i];
const parts = [lac, cid];
var namecid = "LAC/CID";
if (enbid) {
parts.push(enbid);
namecid += "/eNB ID";
if (cell) {
parts.push(`/${cell}`);
namecid += "/Cell";
if (pci) {
parts.push(`/${pci}`);
namecid += "/PCI";
}
}
}
var lactac = parts.join(' / ').replace(' ', ' ').replace('/ /', '/ ').replace('/ /', '/ ')
var UMTS_MODES = /(HS|3G|UMTS|WCDMA)/i;
var bcc, scc, cid;
var bca = "";
var arfcn = json.modem[i].arfcn + " (" + dlfreq + " / " + ulfreq + " MHz)";
// name channels and signal/noise
if (netmode == "LTE") {
var calte = (json.modem[i].lteca)
var bwca = json.modem[i].bwca;
distance = " ~"+ dist +" km";
if (calte > 0) {
carrier = "+";
scc = json.modem[i].scc;
bw = bwca;
bca = " / " + bw + " MHz";
bcc = " B" + band + "" + scc;
} else {
scc = "";
bcc = " B" + band;
if (bw) {
bca = " / " + bw + " MHz";
} else{
bca = ""
}
}
var namech = "EARFCN";
var namesnr = "SINR";
} else if (UMTS_MODES.test(netmode)) {
var namech = "UARFCN";
var namesnr = "ECIO";
var namecid = "LAC/CID";
var lactac = json.modem[i].lac + " / " + json.modem[i].cid;
var bcc = " " + band;
} else {
var namech = "ARFCN";
var namesnr = "SINR/ECIO";
var namecid = "LAC/CID";
var lactac = json.modem[i].lac + " / " + json.modem[i].cid;
var bcc = " " + band;
}
if (bw) {
namebnd = _('Network/Band/Bandwidth');
} else {
namebnd = _('Network/Band');
}
// data by element
if (document.getElementById('status'+i)) {
var view = document.getElementById('status'+i);
view.innerHTML = formatModemStatus(json.modem[i], icon, reg);
}
if (document.getElementById('mode'+i)){
var view = document.getElementById('mode'+i);
if (json.modem[i].signal = 0 || json.modem[i].signal == '') {
view.textContent = '--';
} else {
if (json.modem[i].mode == '') {
view.textContent = '--';
} else {
view.innerHTML = String.format(json.modem[i].mode + "" + carrier + " /"+ bcc +""+ bca);
}
}
}
if (document.getElementById('namebnd'+i)){
var view = document.getElementById('namebnd'+i);
view.innerHTML = String.format(namebnd);
}
if (document.getElementById('chname'+i)){
var view = document.getElementById('chname'+i);
view.innerHTML = String.format(namech);
}
if (document.getElementById('namecid'+i)){
var view = document.getElementById('namecid'+i);
view.innerHTML = String.format(namecid);
}
if (document.getElementById('arfcn'+i)){
var view = document.getElementById('arfcn'+i);
view.innerHTML = String.format(arfcn);
}
if (document.getElementById('lac'+i)){
var view = document.getElementById('lac'+i);
view.innerHTML = String.format(lactac);
}
if (document.getElementById('snrname'+i)) {
var view = document.getElementById('snrname'+i);
view.innerHTML = String.format(namesnr);
}
if (document.getElementById('rssi'+i)) {
var view = document.getElementById('rssi'+i);
if (json.modem[i].rssi == '') {
view.textContent = '--';
} else {
updateProgressBar('rssi', json.modem[i].rssi + ' dBm', -110, i);
}
}
if (document.getElementById('sinr'+i)) {
var sinrElement = document.getElementById('sinr'+i);
var sinrParent = sinrElement ? sinrElement.parentElement : null;
if (!json.modem[i].sinr || json.modem[i].sinr === "--" || json.modem[i].sinr === "") {
if (sinrParent && sinrParent.parentElement) {
sinrParent.parentElement.style.display = 'none';
}
} else {
if (sinrParent && sinrParent.parentElement) {
sinrParent.parentElement.style.display = '';
}
if (netmode == "LTE") {
updateProgressBar('sinr', json.modem[i].sinr + ' dB', -20, i);
} else {
updateProgressBar('ecio', json.modem[i].sinr + ' dB', -24, i);
}
}
}
if (document.getElementById('rsrp'+i)) {
var rsrpElement = document.getElementById('rsrp'+i);
var rsrpParent = rsrpElement ? rsrpElement.parentElement : null;
if (!json.modem[i].rsrp || json.modem[i].rsrp === "--" || json.modem[i].rsrp === "") {
if (rsrpParent && rsrpParent.parentElement) {
rsrpParent.parentElement.style.display = 'none';
}
} else {
if (rsrpParent && rsrpParent.parentElement) {
rsrpParent.parentElement.style.display = '';
}
updateProgressBar('rsrp', json.modem[i].rsrp + ' dBm', -140, i);
}
}
if (document.getElementById('rsrq'+i)) {
var rsrqElement = document.getElementById('rsrq'+i);
var rsrqParent = rsrqElement ? rsrqElement.parentElement : null;
if (!json.modem[i].rsrq || json.modem[i].rsrq === "--" || json.modem[i].rsrq === "") {
if (rsrqParent && rsrqParent.parentElement) {
rsrqParent.parentElement.style.display = 'none';
}
} else {
if (rsrqParent && rsrqParent.parentElement) {
rsrqParent.parentElement.style.display = '';
}
updateProgressBar('rsrq', json.modem[i].rsrq + ' dB', -20, i);
}
}
};
});
}),
render: function(data){
var m, s, o;
m = new form.Map('modeminfo', _('Modeminfo: Network'), _('Cellular network'));
s = m.section(form.TypedSection, 'general', null);
var json = JSON.parse(data);
for (var i = 0; i < json.modem.length; i++) {
let status = 'status'+i;
let mode = 'mode'+i;
let namebnd = 'namebnd'+i;
let chname = 'chname'+i;
let namecid = 'namecid'+i;
let arfcn = 'arfcn'+i;
let lac = 'lac'+i;
let rssi = 'rssi'+i;
let sinr = 'sinr'+i;
let snrname = 'snrname'+i;
let rsrp = 'rsrp'+i;
let rsrq = 'rsrq'+i;
let m = i+1;
if ( json.modem.length > 1 ) {
s.tab("modem" + i, _('Modem')+' '+m);
o = s.taboption('modem'+i, form.HiddenValue, 'generic');
} else {
o = s.option(form.HiddenValue, 'generic');
}
o.render = L.bind(function(data){
return (
E('div', {}, [
E('h3', { 'class': 'data-tab' }),
E('div', { 'class': 'cbi-section', 'data-title': 'modem'+i }, [
E('table', { 'class': 'table' }, [
E('tr', { 'class': 'tr cbi-rowstyle-2' }, [
E('td', { 'class': 'td left', 'width': '50%' }, [ _('Operator')]),
E('td', { 'class': 'td left', 'id': status }, [ '--' ]),
]),
E('tr', { 'class': 'tr cbi-rowstyle-1' }, [
E('td', { 'class': 'td left', 'width': '50%', 'id': namebnd }, [ _('Network/band')]),
E('td', { 'class': 'td left', 'id': mode }, [ '--' ]),
]),
E('tr', { 'class': 'tr cbi-rowstyle-2' }, [
E('td', { 'class': 'td left', 'width': '50%', 'id': chname }, [ _('E/U/ARFCN')]),
E('td', { 'class': 'td left', 'id': arfcn }, [ '--' ]),
]),
E('tr', { 'class': 'tr cbi-rowstyle-1' }, [
E('td', { 'class': 'td left', 'width': '50%', 'id': namecid }, [ _('LAC/CID')]),
E('td', { 'class': 'td left', 'id': lac }, [ '--' ]),
]),
E('tr', { 'class': 'tr cbi-rowstyle-2' }, [
E('td', { 'class': 'td left', 'width': '50%' }, [ _('RSSI')]),
E('td', { 'class': 'td left'}, E('div', {'id': rssi, 'class': 'cbi-progressbar', 'title': '--' }, E('div'))),
]),
E('tr', { 'class': 'tr cbi-rowstyle-1' }, [
E('td', { 'class': 'td left', 'width': '50%', 'id': snrname }, [ _('SINR/EcIO')]),
E('td', { 'class': 'td left'}, E('div', {'id': sinr, 'class': 'cbi-progressbar', 'title': '--'}, E('div'))),
]),
E('tr', { 'class': 'tr cbi-rowstyle-2' }, [
E('td', { 'class': 'td left', 'width': '50%' }, [ _('RSRP')]),
E('td', { 'class': 'td left'}, E('div', {'id': rsrp, 'class': 'cbi-progressbar', 'title': '--'}, E('div'))),
]),
E('tr', { 'class': 'tr cbi-rowstyle-1' }, [
E('td', { 'class': 'td left', 'width': '50%' }, [ _('RSRQ')]),
E('td', { 'class': 'td left'}, E('div', {'id': rsrq, 'class': 'cbi-progressbar', 'title': '--'}, E('div'))),
])
])
])
])
)
}, this.polldata);
o.anonymous = true;
o.rmempty = true;
};
s.anonymous = true;
return m.render();
},
handleSaveApply: null,
handleSave: null,
handleReset: null
});
@@ -0,0 +1,126 @@
'use strict';
'require form';
'require rpc';
'require fs';
'require view';
'require uci';
'require ui';
'require tools.widgets as widgets'
/*
Written by Konstantine Shevlakov at <shevlakov@132lan.ru> 2023
Licensed to the GNU General Public License v3.0.
*/
var callSerialPort = rpc.declare({
object: 'file',
method: 'list',
params: [ 'path' ],
expect: { entries: [] },
filter: function(list, params) {
var rv = [];
for (var i = 0; i < list.length; i++)
if (list[i].name.match(/^ttyACM/) ||
list[i].name.match(/^ttyUSB/) ||
list[i].name.match(/^wwan\d+at\d+/))
rv.push(params.path + list[i].name);
return rv.sort((a, b) => a.name > b.name);
}
});
var callQMIPort = rpc.declare({
object: 'file',
method: 'list',
params: [ 'path' ],
expect: { entries: [] },
filter: function(list, params) {
var rv = [];
for (var i = 0; i < list.length; i++)
if (list[i].name.match(/^cdc-wdm/))
rv.push(params.path + list[i].name);
return rv.sort();
}
});
var maindesc = _('Modeminfo: Configuration');
var mdesc = _('Configuration panel of Modeminfo.');
var qfdesc = _('Get modem data via qmicli (experimental). Require install qmi-utils.');
var sdesc = _('Select serial port.');
var qdesc = _('Select qmi port.');
var lacdec = _('Show LAC and CID in decimal.');
var mmdesc = _('Get device hardware name via mmcli utility if aviable.');
var qmidesc = _('Enable qmi-proxy mode.');
var idesc = _('Short info on Overview page');
var portplace = _('Please select a port');
return view.extend({
render: function(){
var m, s, o;
m = new form.Map('modeminfo', maindesc, mdesc);
s = m.section(form.TypedSection, 'general', _('General option'), null);
s.anonymous = true;
o = s.option(form.Flag, 'index', _('Index page'), idesc);
s.anonymous = true;
o.rmempty = true;
o = s.option(form.Flag, 'decimail', _('Show decimal'), lacdec);
o.rmempty = true;
o = s.option(form.ListValue, 'delay', _('Interval'), _('Poll interval data'));
o.value('', _('none'));
o.value('1', '1 '+_('sec'));
o.value('2', '2 '+_('sec'));
o.value('5', '5 '+_('sec'));
o.value('10', '10 '+_('sec'));
o.value('30', '30 '+_('sec'));
s = m.section(form.TypedSection, 'modeminfo', _('Devices setup'), null);
s.anonymous = true;
s.addremove = true;
o = s.option(form.Flag, 'qmi_mode', _('Use QMI'), qfdesc);
o.rmempty = true;
o = s.option(form.ListValue, 'device', _('Data port'), sdesc);
o.load = function(section_id) {
return callSerialPort('/dev/').then(L.bind(function(devices) {
this.keylist = [];
this.vallist = [];
devices.reverse().forEach(device => this.value(device));
return form.Value.prototype.load.apply(this, [section_id]);
}, this));
};
o.placeholder = portplace;
o.rmempty = true;
o.depends('qmi_mode', '0');
o = s.option(form.ListValue, 'device_qmi', _('Data port'), qdesc);
o.load = function(section_id) {
return callQMIPort('/dev/').then(L.bind(function(devices) {
this.keylist = [];
this.vallist = [];
for (var i = 0; i < devices.length; i++)
this.value(devices[i]);
return form.Value.prototype.load.apply(this, [section_id]);
}, this));
};
o.placeholder = portplace;
o.rmempty = true;
o.depends('qmi_mode', '1');
o = s.option(form.Flag, 'mmcli_name', _('Name via mmcli'), mmdesc);
o.rmempty = true;
o.depends('qmi_mode', '0');
o = s.option(form.Flag, 'qmi_proxy', _('QMI proxy'), qmidesc);
o.rmempty = true;
o.depends('qmi_mode', '1');
return m.render();
}
});
@@ -0,0 +1,108 @@
'use strict';
'require baseclass';
'require form';
'require fs';
'require ui';
'require uci';
/*
Written by Konstantine Shevlakov at <shevlakov@132lan.ru> 2023
Licensed to the GNU General Public License v3.0.
Special Thanks to Vladislav Kadulin aka @Kodo-kakaku
https://github.com/Kodo-kakaku/ to fix update overview page
*/
return baseclass.extend({
title: _('Cellular network'),
load: async function() {
uci.load('modeminfo');
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
reject(new Error('Timeout: modeminfo execution took too long'));
}, 30000); // 30 sec timeout
fs.exec_direct('/usr/bin/modeminfo')
.then(result => {
clearTimeout(timeout);
resolve(result);
})
.catch(error => {
clearTimeout(timeout);
reject(error);
});
}).catch(error => {
console.error('Error loading modeminfo:', error);
return '';
});
},
render: function(data){
if (!data || data.trim() === '') {
return E('div', {
'class': 'cbi-section',
'style': 'color: #999; text-align: center;'
}, _('Wait devices information'));
}
try {
var json = JSON.parse(data);
var index = uci.sections('modeminfo', 'general');
let modemTBL = E('div', { 'class': 'cbi-section' });
if (json.modem && index[0].index == "1"){
for (var i = 0; i < json.modem.length; i++) {
var signal = document.createElement('div');
var icn;
var signalIcons = [
{ max: -1, icn: 'signal-000-000.svg' },
{ max: 0, icn: 'signal-000-000.svg' },
{ max: 10, icn: 'signal-000-000.svg' },
{ max: 25, icn: 'signal-000-025.svg' },
{ max: 50, icn: 'signal-025-050.svg' },
{ max: 75, icn: 'signal-050-075.svg' },
{ max: Infinity, icn: 'signal-075-100.svg' }
];
var p = json.modem[i].csq_per || 0;
var { icn } = signalIcons.find(({ max }) => p <= max);
var icon = L.resource(`view/modem/icons/${icn}`);
var per = p+'%';
var ca;
if (json.modem[i].lteca > 0) {
ca = "+";
} else {
ca = "";
}
signal.innerHTML = String.format(
'<span class="ifacebadge">' + json.modem[i].cops + " " +
'<img src="%s"/><b>'+per.fontcolor(json.modem[i].csq_col) + "</b> " +
json.modem[i].mode+ca + '</span>', icon, p );
modemTBL.append(
E('table', { 'class': 'table' }, [
E('tr', { 'class': 'tr' }, [
E('td', { 'class': 'td left', 'width': '33%' }, [ json.modem[i].device ]),
E('td', { 'class': 'td left', 'id': 'device' }, [ signal ])
])
])
);
};
return modemTBL;
};
} catch (error) {
console.error('Error parsing modeminfo data:', error);
return E('div', {
'class': 'cbi-section',
'style': 'color: #999; text-align: center;'
}, _('Error loading information'));
}
},
});