mirror of
https://github.com/henrygd/beszel.git
synced 2026-09-26 19:37:47 +02:00
wifi: omit empty info snapshot and tidy up
- Info.WiFi uses json "wf" with omitempty so systems without Wi-Fi no longer store/broadcast "wifi":null - move osascript exec into wifi_darwin.go; drop unused commandRunner - share strongest-connection logic between table cell and sorting - trim agent/wifi README
This commit is contained in:
@@ -1,47 +1,11 @@
|
||||
# Connected Wi-Fi signal
|
||||
|
||||
Each default-interval poll reports a snapshot of connected station interfaces
|
||||
in `info.wifi`. Map keys identify interfaces, not networks. `s` is optional SSID
|
||||
metadata; `r` is nullable native RSSI in dBm. Quality percentages are never
|
||||
converted to dBm. An associated interface without an accessible RSSI still
|
||||
appears with an unavailable signal. No scans or network changes occur.
|
||||
`stats.wf` stores only available RSSI values (integer dBm) keyed by interface.
|
||||
Real-time requests reuse the last snapshot instead of collecting again.
|
||||
Reports connected station interfaces only (no scans). `info.wf` holds the current
|
||||
snapshot keyed by interface (`s` SSID, `r` RSSI in dBm when available);
|
||||
`stats.wf` stores available RSSI as integer dBm. Collected on the default
|
||||
interval only; real-time requests reuse the last snapshot.
|
||||
|
||||
The hub panel gates exclusively on current `systems.info.wifi` and system `up`
|
||||
status, independently of the selected historical period. Empty/null snapshots
|
||||
clear it. Historical averages use only available readings per interface; gaps
|
||||
are not zero signal. Interface colors and keys remain stable on reconnect.
|
||||
|
||||
## Platforms
|
||||
|
||||
- Linux: native nl80211 through `github.com/mdlayher/wifi`, compiled into the
|
||||
static agent, including scratch and all other agent images. No `iw`, shared
|
||||
libraries, extra capabilities, or external helper required. Host network
|
||||
namespace access (Docker `network_mode: host`) is necessary to see host Wi-Fi.
|
||||
Only managed station interfaces with explicit associated BSS status appear.
|
||||
Kernel BSS cache reads do not trigger scans; station statistics supply native
|
||||
RSSI matched to the associated AP. Denied/missing station statistics retain
|
||||
association with unavailable RSSI, never substitute stale scan-cache signal.
|
||||
Missing nl80211/driver support or denied association reads yield no readings.
|
||||
A single two-second socket deadline bounds enumeration and interface queries
|
||||
after opening the client. The library's initial nl80211 family discovery is
|
||||
synchronous and does not expose a deadline.
|
||||
- macOS: system `osascript` uses public CoreWLAN via JXA. Station mode proves
|
||||
association; RSSI and optional SSID are read independently. No private airport
|
||||
binary, elevated command or compiled helper required. Privacy settings may
|
||||
redact SSIDs. The subprocess has a two-second deadline.
|
||||
- Windows: native WLAN API, interface GUID identity, connected interface state,
|
||||
optional current-connection SSID and native RSSI query. No localized `netsh`
|
||||
parsing. Missing WLAN service/API yields no readings; denied SSID/RSSI query
|
||||
leaves a connected interface with missing metadata/signal. Non-UTF-8 raw
|
||||
SSIDs are omitted so they cannot invalidate CBOR text in the agent response.
|
||||
Native synchronous WLAN calls cannot be interrupted by the Go deadline.
|
||||
- FreeBSD and other platforms: unsupported, empty snapshot. No approximation
|
||||
from ifconfig quality and no stale data retained.
|
||||
|
||||
Collectors retry each default-interval poll, allowing interfaces and capabilities to appear
|
||||
without an agent restart. Standard agent response caching still applies. Existing
|
||||
hub record JSON storage requires no database schema migration. Older agents
|
||||
without the field keep the panel hidden. Native macOS/Windows runtime checks and
|
||||
real adapter testing are still required; cross compilation is not hardware proof.
|
||||
- Linux: nl80211 via `github.com/mdlayher/wifi`. Docker needs `network_mode: host`.
|
||||
- macOS: CoreWLAN via `osascript` (JXA). SSID may be redacted by privacy settings.
|
||||
- Windows: native WLAN API, keyed by interface GUID.
|
||||
- Other platforms: unsupported.
|
||||
|
||||
@@ -5,23 +5,12 @@ package wifi
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
"os"
|
||||
"os/exec"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/henrygd/beszel/internal/entities/system"
|
||||
)
|
||||
|
||||
type commandRunner func(context.Context, string, ...string) ([]byte, error)
|
||||
|
||||
func run(ctx context.Context, name string, args ...string) ([]byte, error) {
|
||||
cmd := exec.CommandContext(ctx, name, args...)
|
||||
cmd.Env = append(os.Environ(), "LC_ALL=C", "LANG=C")
|
||||
cmd.WaitDelay = 100 * time.Millisecond
|
||||
return cmd.Output()
|
||||
}
|
||||
|
||||
// validSSID omits non-UTF-8 SSIDs: 802.11 permits arbitrary octets, but CBOR
|
||||
// text strings require UTF-8. Metadata must never invalidate the whole response.
|
||||
func validSSID(ssid string) string {
|
||||
|
||||
@@ -5,6 +5,9 @@ package wifi
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"github.com/henrygd/beszel/internal/entities/system"
|
||||
)
|
||||
@@ -31,7 +34,10 @@ if (interfaces) {
|
||||
JSON.stringify(result);`
|
||||
|
||||
func collect(ctx context.Context) map[string]system.WiFi {
|
||||
output, err := run(ctx, "/usr/bin/osascript", "-l", "JavaScript", "-e", coreWLANScript)
|
||||
cmd := exec.CommandContext(ctx, "/usr/bin/osascript", "-l", "JavaScript", "-e", coreWLANScript)
|
||||
cmd.Env = append(os.Environ(), "LC_ALL=C", "LANG=C")
|
||||
cmd.WaitDelay = 100 * time.Millisecond
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user