jarvis-cloud / modules /bt_devices.py
Jarvis2345's picture
Squash history — remove all prior commits (secret hygiene, S4)
a31f556
Raw
History Blame
1.72 kB
"""
modules/bt_devices.py — Phase 4: Bluetooth disconnect by device name (best-effort).
Windows Bluetooth pairing/unpairing is not stable without additional tooling.
We provide a real "disconnect" approximation by disabling the matching Bluetooth PnP device.
This often requires admin.
"""
from __future__ import annotations
import subprocess
from dataclasses import dataclass
@dataclass(frozen=True, slots=True)
class BTResult:
ok: bool
message: str
def _ps(cmd: str) -> subprocess.CompletedProcess[str]:
return subprocess.run(
["powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", cmd],
capture_output=True,
text=True,
shell=False,
)
def disconnect(name_substring: str) -> BTResult:
s = (name_substring or "").strip()
if not s:
return BTResult(False, "Missing device name.")
cmd = (
"try { "
f"$d = Get-PnpDevice -Class Bluetooth -ErrorAction SilentlyContinue | Where-Object {{$_.FriendlyName -like '*{s}*'}} | Select-Object -First 1; "
"if($null -eq $d){ 'NOTFOUND' } else { Disable-PnpDevice -InstanceId $d.InstanceId -Confirm:$false -ErrorAction Stop; 'OK' }"
"} catch { 'FAIL:' + $_.Exception.Message }"
)
r = _ps(cmd)
out = (r.stdout or "").strip()
if out == "OK":
return BTResult(True, "Bluetooth device disconnected (disabled).")
if out == "NOTFOUND":
return BTResult(False, "Bluetooth device not found.")
if "access is denied" in out.lower():
return BTResult(False, "Bluetooth disconnect needs admin permission.")
return BTResult(False, f"Bluetooth disconnect failed: {out[:160]}")