mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-26 19:01:39 -04:00
controller: Desktop start/stop toggle; rename hotspot/bluetooth actions to what they do
Add a Desktop toggle to the Controller (both UIs) that starts/stops display-manager.service. Fail open: the unit is never enabled/disabled, so the desktop always returns on reboot; users who want it disabled across reboots can set the default target themselves. Rename the hotspot and bluetooth actions to reflect their real behavior: - enable/disable_hotspot -> start/stop_hotspot (/api/hotspot/start|stop) - enable/disable_bluetooth -> unblock/block_bluetooth (rfkill semantics, /api/bluetooth/unblock|block) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
a4eeba14ee
commit
3e559e1bf8
14 changed files with 712 additions and 132 deletions
|
|
@ -7,6 +7,8 @@ from fastapi import APIRouter, HTTPException
|
|||
from controller.api.schemas import (
|
||||
BluetoothActionResponse,
|
||||
BluetoothStatusResponse,
|
||||
DesktopActionResponse,
|
||||
DesktopStatusResponse,
|
||||
HotspotActionResponse,
|
||||
HotspotDevicesResponse,
|
||||
HotspotProtocolsResponse,
|
||||
|
|
@ -27,13 +29,11 @@ from controller.api.schemas import (
|
|||
TimezoneStatusResponse,
|
||||
)
|
||||
from controller.lib.admin import (
|
||||
disable_bluetooth,
|
||||
disable_hotspot,
|
||||
block_bluetooth,
|
||||
disable_throttle,
|
||||
enable_bluetooth,
|
||||
enable_hotspot,
|
||||
enable_throttle,
|
||||
get_bluetooth_status_dict,
|
||||
get_desktop_status_dict,
|
||||
get_device_hotspot_protocols,
|
||||
get_hotspot_device,
|
||||
get_hotspot_password,
|
||||
|
|
@ -47,6 +47,11 @@ from controller.lib.admin import (
|
|||
restart_all_services,
|
||||
set_timezone,
|
||||
shutdown_system,
|
||||
start_desktop,
|
||||
start_hotspot,
|
||||
stop_desktop,
|
||||
stop_hotspot,
|
||||
unblock_bluetooth,
|
||||
update_hotspot_settings,
|
||||
)
|
||||
from controller.lib.config import is_docker_mode
|
||||
|
|
@ -105,19 +110,19 @@ async def hotspot_settings_update(request: HotspotSettingsRequest) -> HotspotSet
|
|||
protocol=result["protocol"])
|
||||
|
||||
|
||||
@router.post("/api/hotspot/enable", response_model=HotspotActionResponse)
|
||||
async def hotspot_enable() -> HotspotActionResponse:
|
||||
"""Enable WiFi hotspot."""
|
||||
result = enable_hotspot()
|
||||
@router.post("/api/hotspot/start", response_model=HotspotActionResponse)
|
||||
async def hotspot_start() -> HotspotActionResponse:
|
||||
"""Start the WiFi hotspot."""
|
||||
result = start_hotspot()
|
||||
if not result.get("success"):
|
||||
raise HTTPException(status_code=500, detail=result.get("error", "Failed"))
|
||||
return HotspotActionResponse(**result)
|
||||
|
||||
|
||||
@router.post("/api/hotspot/disable", response_model=HotspotActionResponse)
|
||||
async def hotspot_disable() -> HotspotActionResponse:
|
||||
"""Disable WiFi hotspot."""
|
||||
result = disable_hotspot()
|
||||
@router.post("/api/hotspot/stop", response_model=HotspotActionResponse)
|
||||
async def hotspot_stop() -> HotspotActionResponse:
|
||||
"""Stop the WiFi hotspot by turning the WiFi radio off."""
|
||||
result = stop_hotspot()
|
||||
if not result.get("success"):
|
||||
raise HTTPException(status_code=500, detail=result.get("error", "Failed"))
|
||||
return HotspotActionResponse(**result)
|
||||
|
|
@ -131,24 +136,50 @@ async def bluetooth_status() -> BluetoothStatusResponse:
|
|||
return BluetoothStatusResponse(**await get_bluetooth_status_dict())
|
||||
|
||||
|
||||
@router.post("/api/bluetooth/enable", response_model=BluetoothActionResponse)
|
||||
async def bluetooth_enable() -> BluetoothActionResponse:
|
||||
"""Enable Bluetooth radio."""
|
||||
result = await enable_bluetooth()
|
||||
@router.post("/api/bluetooth/unblock", response_model=BluetoothActionResponse)
|
||||
async def bluetooth_unblock() -> BluetoothActionResponse:
|
||||
"""Unblock the Bluetooth radio (turn it on)."""
|
||||
result = await unblock_bluetooth()
|
||||
if not result.get("success"):
|
||||
raise HTTPException(status_code=500, detail=result.get("error", "Failed"))
|
||||
return BluetoothActionResponse(**result)
|
||||
|
||||
|
||||
@router.post("/api/bluetooth/disable", response_model=BluetoothActionResponse)
|
||||
async def bluetooth_disable() -> BluetoothActionResponse:
|
||||
"""Disable Bluetooth radio."""
|
||||
result = await disable_bluetooth()
|
||||
@router.post("/api/bluetooth/block", response_model=BluetoothActionResponse)
|
||||
async def bluetooth_block() -> BluetoothActionResponse:
|
||||
"""Block the Bluetooth radio (turn it off)."""
|
||||
result = await block_bluetooth()
|
||||
if not result.get("success"):
|
||||
raise HTTPException(status_code=500, detail=result.get("error", "Failed"))
|
||||
return BluetoothActionResponse(**result)
|
||||
|
||||
|
||||
# --- Desktop ---
|
||||
|
||||
@router.get("/api/desktop/status", response_model=DesktopStatusResponse)
|
||||
async def desktop_status() -> DesktopStatusResponse:
|
||||
"""Get graphical desktop (display manager) status."""
|
||||
return DesktopStatusResponse(**await get_desktop_status_dict())
|
||||
|
||||
|
||||
@router.post("/api/desktop/start", response_model=DesktopActionResponse)
|
||||
async def desktop_start() -> DesktopActionResponse:
|
||||
"""Start the graphical desktop until stopped or reboot."""
|
||||
result = await start_desktop()
|
||||
if not result.get("success"):
|
||||
raise HTTPException(status_code=500, detail=result.get("error", "Failed"))
|
||||
return DesktopActionResponse(**result)
|
||||
|
||||
|
||||
@router.post("/api/desktop/stop", response_model=DesktopActionResponse)
|
||||
async def desktop_stop() -> DesktopActionResponse:
|
||||
"""Stop the graphical desktop; it returns on the next boot (fail open)."""
|
||||
result = await stop_desktop()
|
||||
if not result.get("success"):
|
||||
raise HTTPException(status_code=500, detail=result.get("error", "Failed"))
|
||||
return DesktopActionResponse(**result)
|
||||
|
||||
|
||||
# --- Samba ---
|
||||
|
||||
@router.get("/api/samba/status", response_model=SambaStatusResponse)
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ class HotspotSettingsResponse(BaseModel):
|
|||
|
||||
|
||||
class HotspotActionResponse(BaseModel):
|
||||
"""Response model for hotspot enable/disable actions."""
|
||||
"""Response model for hotspot start/stop actions."""
|
||||
|
||||
success: bool = Field(description="Whether the action succeeded")
|
||||
ssid: Optional[str] = Field(default=None, description="Hotspot SSID")
|
||||
|
|
@ -211,7 +211,26 @@ class BluetoothStatusResponse(BaseModel):
|
|||
|
||||
|
||||
class BluetoothActionResponse(BaseModel):
|
||||
"""Response model for Bluetooth enable/disable actions."""
|
||||
"""Response model for Bluetooth block/unblock actions."""
|
||||
|
||||
success: bool = Field(description="Whether the action succeeded")
|
||||
error: Optional[str] = Field(default=None, description="Error message if failed")
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Admin - Desktop
|
||||
# ============================================================================
|
||||
|
||||
class DesktopStatusResponse(BaseModel):
|
||||
"""Response model for /api/desktop/status endpoint."""
|
||||
|
||||
running: bool = Field(description="Whether the display manager is currently running")
|
||||
available: bool = Field(description="Whether a display manager is installed")
|
||||
reason: Optional[str] = Field(default=None, description="Reason if unavailable")
|
||||
|
||||
|
||||
class DesktopActionResponse(BaseModel):
|
||||
"""Response model for desktop start/stop actions."""
|
||||
|
||||
success: bool = Field(description="Whether the action succeeded")
|
||||
error: Optional[str] = Field(default=None, description="Error message if failed")
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ wrol_mode) remain in the main WROLPi API at /api/status.
|
|||
from fastapi import APIRouter, Request
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from controller.lib.admin import get_bluetooth_status, get_hotspot_ssid, get_hotspot_status, get_throttle_status, \
|
||||
BluetoothStatus, HotspotStatus
|
||||
from controller.lib.admin import get_bluetooth_status, get_desktop_status, get_hotspot_ssid, get_hotspot_status, \
|
||||
get_throttle_status, BluetoothStatus, HotspotStatus
|
||||
from controller.lib.config import is_docker_mode, is_rpi, is_rpi4, is_rpi5
|
||||
from controller.lib.status import (
|
||||
get_cpu_status,
|
||||
|
|
@ -39,6 +39,7 @@ async def get_system_info() -> dict:
|
|||
"""
|
||||
hotspot_status = get_hotspot_status()
|
||||
bluetooth_status = await get_bluetooth_status()
|
||||
desktop_status = await get_desktop_status()
|
||||
throttle_status = get_throttle_status()
|
||||
|
||||
# Get hotspot SSID from config if hotspot is connected
|
||||
|
|
@ -50,6 +51,7 @@ async def get_system_info() -> dict:
|
|||
"is_rpi4": is_rpi4(),
|
||||
"is_rpi5": is_rpi5(),
|
||||
"bluetooth_status": bluetooth_status.name,
|
||||
"desktop_status": desktop_status.name,
|
||||
"hotspot_status": hotspot_status.name,
|
||||
"hotspot_ssid": hotspot_ssid,
|
||||
"throttle_status": throttle_status.name,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue