macotron.network
Check and switch Wi-Fi, Bluetooth, and AirDrop, list paired Bluetooth devices with their battery, read interface addresses and traffic counters, and ping a host.
// Toggle Wi-Fi and say what happened.
const wifi = await macotron.network.wifi();
const r = await macotron.network.setWifi(!wifi.on);
macotron.notify.toast("Wi-Fi", r.ok ? (r.on ? r.ssid || "On" : "Off") : r.error);
Wi-Fi
The Wi-Fi calls run /usr/sbin/networksetup, which takes a moment, so they return promises.
wifiSSID(): Promise<string | null>
The name of the joined network, or null when Wi-Fi is off, not joined, or missing.
wifi(): Promise<{ available, on, ssid? }>
available is false on a Mac with no Wi-Fi hardware. on is whether the radio is on. ssid is present only while joined to a network.
setWifi(on: boolean): Promise<{ ok, available, on, ssid?, error? }>
Turns the radio on or off and resolves with the new state, read back after the change. ok is false with an error when there is no Wi-Fi hardware or networksetup fails.
Bluetooth
bluetooth(): Promise<{ on, devices }>
on is whether the Bluetooth radio is on. devices lists paired devices as { name, address, connected, battery? }. battery is a charge from 0 to 100. For devices that report several levels, such as AirPods, it is the lowest one. When the charge is unknown, battery is null.
Battery levels come from system_profiler, which takes over a second, so Macotron reuses them for 30 seconds.
setBluetooth(on: boolean): { ok, on, error? }
Turns the Bluetooth radio on or off. Unlike the other setters, this call returns at once instead of a promise. on is the state you asked for. ok is false only when macOS does not offer the power switch.
AirDrop
A mode is "off", "contacts" (Contacts Only), or "everyone".
airDrop(): { mode }
Who can find this Mac over AirDrop right now.
setAirDrop(mode: "off" | "contacts" | "everyone"): Promise<{ ok, mode, error? }>
Changes the AirDrop mode. Macotron writes the setting and restarts the AirDrop service so it takes effect, which is why this returns a promise. An unknown mode resolves { ok: false } with the current mode and an error.
Interfaces
interfaces(): Array<{ name, ip }>
Every IPv4 address on the Mac, one row per address, such as { name: "en0", ip: "192.168.1.20" }. The loopback interface is left out.
counters(): Array<{ name, ip?, bytesIn, bytesOut }>
Bytes received and sent on each interface since it came up, sorted by name. ip is the interface's first IPv4 address, when it has one. The loopback interface is left out.
To get a rate, call counters() twice and divide the difference by the time between the calls.
The counters are 32-bit and wrap to zero after 4 GiB. When a new reading is smaller than the last one, skip that sample.
ping(host?: string): Promise<{ ms, host, error? }>
Sends one ping with /sbin/ping and resolves with the round-trip time in milliseconds. host defaults to 1.1.1.1. The ping waits at most 2 seconds. On failure, ms is null and error holds the first line of ping's output.
const r = await macotron.network.ping();
macotron.menubar.status("ping", { title: r.ms == null ? "offline" : Math.round(r.ms) + " ms" });
Events
wifi:changed
Fires when Wi-Fi turns on or off, or the joined network changes. The payload is { on, ssid }, where ssid is null when not joined. Macotron checks about one second after macOS reports a network change, and fires only when on or ssid differs from the last check.
Macotron watches Wi-Fi only when a plugin registers a wifi:changed listener while it loads. A listener added later, for example inside a timer, gets no events until the next reload.
// Switch settings by network.
macotron.on("wifi:changed", ({ ssid }) => {
if (ssid === "Office") macotron.audio.setMuted(true);
});
See also
- macotron.bonjour to find services on the local network.
- macotron.http for web requests.
- The
wifi.js,bluetooth.js,network-path.js, andprofiles.jsplugins.