⛄ Sync 2026-11-01 05:43:29

This commit is contained in:
github-actions[bot] committed 2026-11-01 05:43:29 +08:00
1 parent fae68afc83
commit d1e51134a0
187 files changed
+3752 -2114

No files matched your search

@@ -1,6 +1,6 @@
{
"luci-app-vantage": {
"description": "Vantage dashboard: read-only status of the device, uplink, radios and stations (wireless configuration without keys, through luci.vantage wireless)",
"description": "Vantage dashboard: read-only status of the device, uplink, radios and stations (wireless configuration without keys, through luci.vantage wireless) and its temperature sensors (luci.vantage thermal)",
"read": {
"file": {
"/proc/stat": [ "read" ]
@@ -11,7 +11,7 @@
"network.interface": [ "dump" ],
"network.device": [ "status" ],
"luci-rpc": [ "getHostHints" ],
"luci.vantage": [ "wireless" ],
"luci.vantage": [ "thermal", "wireless" ],
"iwinfo": [ "assoclist", "info" ],
"hostapd.*": [ "get_clients", "get_status" ],
"umdns": [ "hosts" ],
@@ -6,6 +6,9 @@
// wireless network.wireless status reduced to the fields the dashboard
// reads: no key, sae_password, RADIUS or 802.11r secrets, no
// EAP credentials. Read group luci-app-vantage.
// thermal the temperature of each thermal zone in /sys/class/thermal
// (millidegrees Celsius) with its type; nothing else is read.
// Read group luci-app-vantage.
// set_alias { mac, name, icon }: name one station, or remove its name
// with name ''. Validated here, whatever the browser did, and
// written to /etc/config/vantage only. Write group
@@ -19,12 +22,15 @@
import { cursor } from 'uci';
import { connect } from 'ubus';
import { lsdir, readfile } from 'fs';
const CONFIG = 'vantage';
const NAME_MAX = 48; // code points, after collapsing spaces
const NAME_MAX_UNITS = NAME_MAX * 8; // raw input cap, in UTF-16 code units (as names.js)
const MAX_ALIASES = 512; // client sections; bounds /etc/config/vantage
const ICONS = [ 'phone', 'laptop', 'tablet', 'desktop', 'tv', 'speaker', 'printer', 'camera', 'console', 'watch', 'iot', 'router', 'device' ];
const THERMAL = '/sys/class/thermal';
const MAX_ZONES = 16;
/* ------------------------------------------------------------ helpers */
@@ -306,6 +312,32 @@ function set_alias(args) {
return { ok: true, op, mac };
}
/* ------------------------------------------------------------ thermal */
// [ { zone, type, temp } ] in zone order, at most MAX_ZONES; a zone whose
// temperature cannot be read (switched off, no sensor yet) is left out,
// a type that is not a plain word is sent as ''
function thermal() {
let zones = filter(lsdir(THERMAL) ?? [], n => match(n, /^thermal_zone[0-9]{1,3}$/));
let out = [];
for (let n in sort(zones, (a, b) => int(substr(a, 12)) - int(substr(b, 12)))) {
if (length(out) >= MAX_ZONES)
break;
let temp = trim(readfile(THERMAL + '/' + n + '/temp', 16) ?? '');
if (!match(temp, /^-?[0-9]{1,7}$/))
continue;
let kind = trim(readfile(THERMAL + '/' + n + '/type', 64) ?? '');
push(out, { zone: n, type: match(kind, /^[A-Za-z0-9_.-]{1,40}$/) ? kind : '', temp: int(temp) });
}
return out;
}
/* ------------------------------------------------------------ methods */
const methods = {
@@ -325,6 +357,12 @@ const methods = {
}
},
thermal: {
call: function() {
return { zones: thermal() };
}
},
set_alias: {
args: { mac: 'mac', name: 'name', icon: 'icon' },
call: function(request) {