mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-26 10:51:36 -04:00
Hotspot was reported as "not supported" on x86 machines (Ubuntu/Debian PCs) because the Controller only watched the hardcoded default wlan0 device, while predictable interface naming produces names like wlp2s0. The Settings page saved hotspot_device to wrolpi.yaml, which the Controller never read. The Controller now owns hotspot settings in controller.yaml: * New endpoints: GET/POST /api/hotspot/settings, GET /api/hotspot/devices (WiFi interfaces discovered via nmcli). * Legacy hotspot_* values in wrolpi.yaml are migrated into controller.yaml once on startup, unless controller.yaml already sets them. * The Hotspot SSID/password/device fields moved from the Settings page to the Control page next to the Hotspot toggle; the device is now a dropdown of the WiFi devices found on the machine. * The Controller fallback UI gets the same hotspot settings form for parity. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
252 lines
6.7 KiB
JavaScript
252 lines
6.7 KiB
JavaScript
/**
|
|
* Controller API client for WROLPi.
|
|
*
|
|
* These functions call the Controller service endpoints.
|
|
* Controller handles system-level operations that need to work
|
|
* even when the main API is down.
|
|
*/
|
|
|
|
// Controller endpoints are served under /controller/api
|
|
const CONTROLLER_BASE = '/controller/api';
|
|
|
|
/**
|
|
* Fetch with error handling for Controller endpoints.
|
|
*/
|
|
async function controllerFetch(endpoint, options = {}) {
|
|
const url = `${CONTROLLER_BASE}${endpoint}`;
|
|
const response = await fetch(url, {
|
|
...options,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
...options.headers,
|
|
},
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const error = await response.json().catch(() => ({detail: response.statusText}));
|
|
throw new Error(error.detail || 'Controller request failed');
|
|
}
|
|
|
|
return response.json();
|
|
}
|
|
|
|
// --- Status Endpoints ---
|
|
|
|
/**
|
|
* Get all system stats from the Controller.
|
|
* Returns CPU, memory, load, drives, network, power, iostat, processes,
|
|
* disk_bandwidth along with system info (dockerized, is_rpi, hotspot, throttle).
|
|
*/
|
|
export async function getControllerStats() {
|
|
return controllerFetch('/stats');
|
|
}
|
|
|
|
export async function getCpuStatus() {
|
|
return controllerFetch('/status/cpu');
|
|
}
|
|
|
|
export async function getMemoryStatus() {
|
|
return controllerFetch('/status/memory');
|
|
}
|
|
|
|
export async function getLoadStatus() {
|
|
return controllerFetch('/status/load');
|
|
}
|
|
|
|
export async function getDrivesStatus() {
|
|
return controllerFetch('/status/drives');
|
|
}
|
|
|
|
export async function getPrimaryDriveStatus() {
|
|
return controllerFetch('/status/primary-drive');
|
|
}
|
|
|
|
export async function getNetworkStatus() {
|
|
return controllerFetch('/status/network');
|
|
}
|
|
|
|
export async function getPowerStatus() {
|
|
return controllerFetch('/status/power');
|
|
}
|
|
|
|
// --- Admin Endpoints ---
|
|
|
|
export async function getHotspotStatus() {
|
|
return controllerFetch('/hotspot/status');
|
|
}
|
|
|
|
export async function getHotspotDevices() {
|
|
return controllerFetch('/hotspot/devices');
|
|
}
|
|
|
|
export async function getHotspotSettings() {
|
|
return controllerFetch('/hotspot/settings');
|
|
}
|
|
|
|
export async function updateHotspotSettings(settings) {
|
|
return controllerFetch('/hotspot/settings', {method: 'POST', body: JSON.stringify(settings)});
|
|
}
|
|
|
|
export async function enableHotspot() {
|
|
return controllerFetch('/hotspot/enable', {method: 'POST'});
|
|
}
|
|
|
|
export async function disableHotspot() {
|
|
return controllerFetch('/hotspot/disable', {method: 'POST'});
|
|
}
|
|
|
|
export async function getThrottleStatus() {
|
|
return controllerFetch('/throttle/status');
|
|
}
|
|
|
|
export async function enableThrottle() {
|
|
return controllerFetch('/throttle/enable', {method: 'POST'});
|
|
}
|
|
|
|
export async function disableThrottle() {
|
|
return controllerFetch('/throttle/disable', {method: 'POST'});
|
|
}
|
|
|
|
export async function getBluetoothStatus() {
|
|
return controllerFetch('/bluetooth/status');
|
|
}
|
|
|
|
export async function enableBluetooth() {
|
|
return controllerFetch('/bluetooth/enable', {method: 'POST'});
|
|
}
|
|
|
|
export async function disableBluetooth() {
|
|
return controllerFetch('/bluetooth/disable', {method: 'POST'});
|
|
}
|
|
|
|
// --- Samba Endpoints ---
|
|
|
|
export async function getSambaStatus() {
|
|
return controllerFetch('/samba/status');
|
|
}
|
|
|
|
export async function addSambaShare(name, path, readOnly = true, comment = '') {
|
|
return controllerFetch('/samba/shares', {
|
|
method: 'POST',
|
|
body: JSON.stringify({name, path, read_only: readOnly, comment}),
|
|
});
|
|
}
|
|
|
|
export async function removeSambaShare(shareName) {
|
|
return controllerFetch(`/samba/shares/${encodeURIComponent(shareName)}`, {method: 'DELETE'});
|
|
}
|
|
|
|
export async function shutdownSystem() {
|
|
return controllerFetch('/shutdown', {method: 'POST'});
|
|
}
|
|
|
|
export async function rebootSystem() {
|
|
return controllerFetch('/reboot', {method: 'POST'});
|
|
}
|
|
|
|
export async function restartServices() {
|
|
return controllerFetch('/restart', {method: 'POST'});
|
|
}
|
|
|
|
// --- Service Endpoints ---
|
|
|
|
export async function getServices() {
|
|
return controllerFetch('/services');
|
|
}
|
|
|
|
export async function getServiceStatus(serviceName) {
|
|
return controllerFetch(`/services/${serviceName}`);
|
|
}
|
|
|
|
export async function startService(serviceName) {
|
|
return controllerFetch(`/services/${serviceName}/start`, {method: 'POST'});
|
|
}
|
|
|
|
export async function stopService(serviceName) {
|
|
return controllerFetch(`/services/${serviceName}/stop`, {method: 'POST'});
|
|
}
|
|
|
|
export async function restartService(serviceName) {
|
|
return controllerFetch(`/services/${serviceName}/restart`, {method: 'POST'});
|
|
}
|
|
|
|
export async function enableService(serviceName) {
|
|
return controllerFetch(`/services/${serviceName}/enable`, {method: 'POST'});
|
|
}
|
|
|
|
export async function disableService(serviceName) {
|
|
return controllerFetch(`/services/${serviceName}/disable`, {method: 'POST'});
|
|
}
|
|
|
|
export async function getServiceLogs(serviceName, lines = 100) {
|
|
return controllerFetch(`/services/${serviceName}/logs?lines=${lines}`);
|
|
}
|
|
|
|
// --- Disk Endpoints ---
|
|
|
|
export async function getDisks() {
|
|
return controllerFetch('/disks');
|
|
}
|
|
|
|
export async function getMounts() {
|
|
return controllerFetch('/disks/mounts');
|
|
}
|
|
|
|
export async function mountDisk(device, mountPoint, fstype = null, options = 'defaults', persist = false, forceShadowed = false) {
|
|
return controllerFetch('/disks/mount', {
|
|
method: 'POST',
|
|
body: JSON.stringify({
|
|
device,
|
|
mount_point: mountPoint,
|
|
fstype,
|
|
options,
|
|
persist,
|
|
force_shadowed: forceShadowed,
|
|
}),
|
|
});
|
|
}
|
|
|
|
export async function unmountDisk(mountPoint, lazy = false) {
|
|
return controllerFetch('/disks/unmount', {
|
|
method: 'POST',
|
|
body: JSON.stringify({mount_point: mountPoint, lazy}),
|
|
});
|
|
}
|
|
|
|
export async function detectWrolpiDrives() {
|
|
return controllerFetch('/disks/detect-wrolpi');
|
|
}
|
|
|
|
export async function getSmartStatus() {
|
|
return controllerFetch('/disks/smart');
|
|
}
|
|
|
|
// --- Fstab Endpoints ---
|
|
|
|
export async function getFstabEntries() {
|
|
return controllerFetch('/disks/fstab');
|
|
}
|
|
|
|
export async function addFstabEntry(device, mountPoint, fstype, options = 'defaults,nofail,x-systemd.device-timeout=10s') {
|
|
return controllerFetch('/disks/fstab', {
|
|
method: 'POST',
|
|
body: JSON.stringify({device, mount_point: mountPoint, fstype, options}),
|
|
});
|
|
}
|
|
|
|
export async function removeFstabEntry(mountPoint) {
|
|
const encodedPath = encodeURIComponent(mountPoint.slice(1));
|
|
return controllerFetch(`/disks/fstab/${encodedPath}`, {method: 'DELETE'});
|
|
}
|
|
|
|
// --- Health Check ---
|
|
|
|
export async function healthCheck() {
|
|
return controllerFetch('/health');
|
|
}
|
|
|
|
// --- Controller Info ---
|
|
|
|
export async function getControllerInfo() {
|
|
return controllerFetch('/info');
|
|
}
|