🌴 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

+11
View File
@@ -0,0 +1,11 @@
include $(TOPDIR)/rules.mk
LUCI_TITLE:=Information dashboard for 3G/LTE dongle
LUCI_DEPENDS:=+modeminfo
PKG_LICENSE:=GPLv3
PKG_VERSION:=0.4.5
PKG_RELEASE:=1
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
+83
View File
@@ -0,0 +1,83 @@
# luci-app-modeminfo
3G/LTE dongle information for OpenWrt LuCi
luci-app-modeminfo is fork from https://github.com/IceG2020/luci-app-3ginfo
Supported devices:
- Quectel EC200T/EC21/EC25/EP06/EM12/EM160R-GL
- SimCom SIM7600E-H/SIM7906/A7600/A7906-M2
- STYX MG8224
- Huawei E3372 (LTE)/MU709/ME909
- Sierra Wireless EM7455/EM9191
- HP LT4220
- Dell DW5821e/DW5829e
- MEIGLink SLM750-R2/SLM820/SLM828
- MikroTik R11e-LTE/R11e-LTE6
- Fibocom NL668/NL678/L850/L860/NL952/FM150/FM190/FM350
- Gosuncnwelink GM510
- ThinkWill ML7820+
- Yuge CLM920
- ZTE MF823/MF823D
<details>
<summary>Package contents:</summary>
|Package |Description |
|:-------|:-----------|
|luci-app-modeminfo |LuCI web interface |
|modeminfo |common files |
|modeminfo-qmi |Qualcomm MSM Interface support |
|modeminfo-serial-quectel |Quectel modems support |
|modeminfo-serial-telit |Telit LN940 (HP LT4220) modem support |
|modeminfo-serial-huawei |Huawei MU709/ME909/E3372(stick mode, LTE only) modems support|
|modeminfo-serial-sierra |Sierra EM7455/EM9191 modem support |
|modeminfo-serial-simcom |SimCOM modems support |
|modeminfo-serial-dell |Dell DW5821e/DW5829e modem support |
|modeminfo-serial-fibocom |Fibocom LN668/NL678/NL952/FM150/FM190 modems support |
|modeminfo-serial-xmm |Fibocom L850/L860/FM350 modems support |
|modeminfo-serial-mikrotik |MikroTik R11e-LTE/R11e-LTE6 modems support |
|modeminfo-serial-gosun |Gosuncnwelink GM510 support |
|modeminfo-serial-tw |ThinkWill ML7820+ support |
|modeminfo-serial-yuge |Yuge CLM920 support |
|modeminfo-serial-meig |MEIGLink SLM750-R2/SLM820/SLM828 support |
|modeminfo-serial-zte |ZTE MF823/MF823D support |
|modeminfo-serial-styx |STYX MG8224 support |
</details>
<details>
<summary>Screenshots</summary>
* Overview page. Short network info.
![](https://raw.githubusercontent.com/koshev-msk/modemfeed/master/luci/applications/luci-app-modeminfo/screenshots/modeminfo-overview.png)
* Modeminfo index page. Verbose network info.
![](https://raw.githubusercontent.com/koshev-msk/modemfeed/master/luci/applications/luci-app-modeminfo/screenshots/modeminfo-network.png)
* Modeminfo hardware page.
![](https://raw.githubusercontent.com/koshev-msk/modemfeed/master/luci/applications/luci-app-modeminfo/screenshots/modeminfo-hardware.png)
* Modeminfo setup page.
![](https://raw.githubusercontent.com/koshev-msk/modemfeed/master/luci/applications/luci-app-modeminfo/screenshots/modeminfo-setup.png)
</details>
@@ -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'));
}
},
});
+148
View File
@@ -0,0 +1,148 @@
"Language: ru\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Last-Translator: Konstantine Shevlyakov <shevlakov@132lan.ru>\n"
msgid "Modem"
msgstr "Модем"
msgid "Modeminfo"
msgstr "Модеминфо"
msgid "Network"
msgstr "Сеть"
msgid "Hardware"
msgstr "Оборудование"
msgid "Setup"
msgstr "Настройка"
msgid "Modeminfo: Network"
msgstr "Модеминфо: Сеть"
msgid "No Registration"
msgstr "Нет регистрации"
msgid "Registered"
msgstr "Зарегистрирован"
msgid "Searching"
msgstr "Поиск сети"
msgid "Denied"
msgstr "Запрет регистрации"
msgid "Unknown"
msgstr "Неизвестно"
msgid "Roaming"
msgstr "Гостевая сеть"
msgid "No Data"
msgstr "Нет данных"
msgid "Network/Band/Bandwidth"
msgstr "Сеть/Диапазон/Полоса"
msgid "Network/Band"
msgstr "Сеть/Диапазон"
msgid "Cellular network"
msgstr "Сотовая сеть"
msgid "Operator"
msgstr "Оператор"
msgid "Status"
msgstr "Состояние"
msgid "Modeminfo: Hardware"
msgstr "Модеминфо: Устройство"
msgid "Hardware and sim-card info."
msgstr "Информация о модеме и сим-карте"
msgid "Device"
msgstr "Устройство"
msgid "Firmware"
msgstr "Встроенное ПО"
msgid "Chiptemp"
msgstr "Температура"
msgid "In automatic mode detect first answered DATA port."
msgstr "В автоматическом режиме находит первый отвечающий порт данных."
msgid "Please select a port"
msgstr "Пожалуйста выберите порт"
msgid "Modeminfo: Configuration"
msgstr "Модеминфо: Конфигурация"
msgid "Configuration panel of Modeminfo."
msgstr "Страница конфигурации Modeminfo."
msgid "Use QMI"
msgstr "Использовать QMI"
msgid "Get modem data via qmicli (experimental). Require install qmi-utils."
msgstr "Получать данные модема через qmicli (экспериментально). Требуется установленный qmi-utils."
msgid "Data port"
msgstr "Порт данных"
msgid "Select serial port."
msgstr "Выберите последовательный порт."
msgid "Select qmi port."
msgstr "Выберите порт qmi."
msgid "Show decimal"
msgstr "Показать в десятичных"
msgid "Show LAC and CID in decimal."
msgstr "Показать LAC и CID соты в десятичных."
msgid "Get device hardware name via mmcli utility if aviable."
msgstr "Если доступно, использовать утилиту mmcli для имени модема."
msgid "Name via mmcli"
msgstr "Имя модема через mmcli"
msgid "QMI proxy"
msgstr "QMI прокси"
msgid "Enable qmi-proxy mode."
msgstr "Задействовать режим прокси."
msgid "Index page"
msgstr "На главную"
msgid "Short info on Overview page"
msgstr "Краткая информация о сети на главной странице"
msgid "sec"
msgstr "сек"
msgid "none"
msgstr "нет"
msgid "Interval"
msgstr "Интервал"
msgid "Poll interval data"
msgstr "Интервал обновления данных"
msgid "General option"
msgstr "Общие настройки"
msgid "Devices setup"
msgstr "Настройки устройств"
msgid "Wait devices information"
msgstr "Ожидание ответа от устройств"
msgid "Error loading information"
msgstr "Получение данных завершилось ошибкой"
+1
View File
@@ -0,0 +1 @@
zh_Hans
+132
View File
@@ -0,0 +1,132 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "Modem"
msgstr "移动网络"
msgid "Modeminfo"
msgstr "调制解调器信息"
msgid "Network"
msgstr "网络"
msgid "China Mobile"
msgstr "中国移动"
msgid "China Unicom"
msgstr "中国联通"
msgid "China Telecom"
msgstr "中国电信"
msgid "Hardware"
msgstr "硬件"
msgid "Setup"
msgstr "设置"
msgid "Modeminfo: Network"
msgstr "调制解调器信息: 网络"
msgid "No Registration"
msgstr "未注册"
msgid "Registered"
msgstr "已注册"
msgid "Searching"
msgstr "搜索中"
msgid "Denied"
msgstr "禁止注册"
msgid "Unknown"
msgstr "未知"
msgid "Roaming"
msgstr "漫游"
msgid "No Data"
msgstr "无数据"
msgid "Network/Band/Bandwidth"
msgstr "网络/频段/带宽"
msgid "Network/Band"
msgstr "网络/频段"
msgid "Cellular network"
msgstr "蜂窝网络"
msgid "Operator"
msgstr "运营商"
msgid "Status"
msgstr "状态"
msgid "Modeminfo: Hardware"
msgstr "调制解调器信息: 硬件"
msgid "Hardware and sim card info."
msgstr "硬件和sim卡信息。"
msgid "Device"
msgstr "设备"
msgid "Firmware"
msgstr "固件"
msgid "Chiptemp"
msgstr "芯片温度"
msgid "In automatic mode detect first answered DATA port."
msgstr "在自动模式下,检测第一个应答的DATA端口。"
msgid "Please select a port"
msgstr "请选择端口"
msgid "Modeminfo: Configuration"
msgstr "调制解调器信息:配置"
msgid "Configuration panel of Modeminfo."
msgstr "调制解调器信息配置面板。"
msgid "Use QMI"
msgstr "使用 QMI"
msgid "Get modem data via qmicli (experimental). Require install qmi-utils."
msgstr "通过qmicli获取调制解调器数据(实验)。需要安装qmi utils。"
msgid "Data port"
msgstr "数据端口"
msgid "Select serial port."
msgstr "选择串口。"
msgid "Select qmi port."
msgstr "选择qmi端口。"
msgid "Show decimal"
msgstr "十进制显示"
msgid "Show LAC and CID in decimal."
msgstr "以十进制显示LAC和CID。"
msgid "Get device hardware name via mmcli utility if aviable."
msgstr "如果可用,请通过mmcli 获取设备硬件名称。"
msgid "Name via mmcli"
msgstr "通过mmcli命名"
msgid "QMI proxy"
msgstr "QMI 代理"
msgid "Enable qmi-proxy mode."
msgstr "启用qmi代理模式。"
msgid "Index page"
msgstr "主页显示"
msgid "Short info on Overview page"
msgstr "在概览页面显示简单的信息。"
@@ -0,0 +1,50 @@
{
"admin/modem": {
"title": "Modem",
"order": 45,
"action": {
"type": "firstchild",
"recurse": true
}
},
"admin/modem/main": {
"title": "Modeminfo",
"order": 10,
"action": {
"type": "alias",
"path": "admin/modem/main/main"
},
"depends": {
"acl": [ "luci-app-modeminfo" ],
"uci": { "modeminfo": true }
}
},
"admin/modem/main/main": {
"title": "Network",
"order": 51,
"action": {
"type": "view",
"path": "modem/main"
}
},
"admin/modem/main/hw": {
"title": "Hardware",
"order": 52,
"action": {
"type": "view",
"path": "modem/hw"
}
},
"admin/modem/main/config": {
"title": "Setup",
"order": 53,
"action": {
"type": "view",
"path": "modem/setup"
}
}
}
@@ -0,0 +1,23 @@
{
"luci-app-modeminfo": {
"description": "Grant access to modeminfo configuration",
"read": {
"ubus": {
"file": [ "read" ],
"luci": [ "getConntrackHelpers" ]
},
"file": {
"/usr/bin/modeminfo": [ "exec" ],
"/usr/share/modeminfo/scripts/rmtmp": [ "exec" ]
},
"uci": [ "modeminfo" ]
},
"write": {
"ubus": {
"file": [ "write" ]
},
"uci": [ "modeminfo" ]
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB