乐于分享
好东西不私藏

控制软件和硬件的技能system-controller

控制软件和硬件的技能system-controller

## system-controller 技能详细介绍### 定位这是一个**统一的Windows系统控制接口**,能让我通过自然语言指令控制你的电脑软件、硬件和外部设备。---### 五大模块#### 1️⃣ 窗口管理 (window_manager.py)| 功能 | 示例指令 ||------|----------|| 列出所有窗口 | "有哪些窗口开着" || 聚焦/置前窗口 | "把微信调到前台" || 关闭窗口 | "关掉Chrome" || 最小化/最大化 | "全屏当前窗口" || 调整大小/位置 | "把窗口移到左边" || 发送按键 | "给记事本输入Hello" |#### 2️⃣ 进程管理 (process_manager.py)| 功能 | 示例指令 ||------|----------|| 查看系统状态 | "系统运行怎么样" || 列出进程 | "看看有哪些进程" || 启动程序 | "打开VS Code" || 结束进程 | "关掉所有记事本" |#### 3️⃣ 硬件控制 (hardware_controller.py)| 功能 | 示例指令 ||------|----------|| 音量调节 | "把音量调到50" / "静音" || 屏幕亮度 | "屏幕调暗" || 显示信息 | "显示器是什么配置" || 电源管理 | "锁屏" / "睡眠" / "关机" || 网络控制 | "扫描WiFi" / "查看网络配置" || USB设备 | "插了哪些USB设备" |#### 4️⃣ 串口通信 (serial_comm.py)| 功能 | 示例指令 ||------|----------|| 列出串口 | "有哪些COM口" || 发送指令 | "给Arduino发开灯指令" || 读取数据 | "读取温度传感器" || 实时监听 | "监听串口数据30秒" || 自动检测波特率 | "检测设备波特率" |#### 5️⃣ IoT控制 (iot_controller.py)| 功能 | 示例指令 ||------|----------|| Home Assistant | "列出所有智能设备" || 开关设备 | "打开客厅灯" / "关掉空调" || 调节参数 | "把卧室灯亮度设为30%" || 通用HTTP API | "调用这个设备的API" |---### 用法**直接用自然语言告诉我你想做什么就行。** 例如:"打开记事本""查看系统资源占用""把屏幕亮度调到70%""锁屏""扫描附近WiFi""给COM3口发一条指令"我会自动解析意图,调用对应的脚本执行操作。### 安全机制- 关闭窗口、结束进程、电源操作等**都会先确认**- 危险操作(关机、重启、禁用网络)**需要明确批准**### 适用场景```电脑控制 → 窗口管理 + 进程管理系统设置 → 音量/亮度/网络/电源硬件扩展 → 串口通信(Arduino等)智能家居 → Home Assistant / HTTP API```这个技能现在已安装在你的系统上,随时可以调用。想试试什么功能?

1″C:\Users\username\.workbuddy\skills\system-controller\SKILL.md”

---name: system-controllerdescription: >  Control Windows desktop software, hardware, and IoT devices.  This skill should be used when the user wants to open/close/resize windows,  start/stop/monitor processes, adjust volume/brightness, manage power settings,  control network adapters, communicate with Arduino or serial devices,  or interact with smart home platforms like Home Assistant.  Trigger phrases include "open app""close window""set volume""adjust brightness",  "lock screen""shutdown""list processes""send serial command""control light",  "connect Arduino""enable WiFi""USB devices"or any request involving  controlling software, hardware, or external devices.---# System ControllerUnified control interface for Windows desktop software, system hardware, serial devices, and IoT platforms.## Architecture```User Request → Natural Language Understanding → Script Execution → System Action```Five control modules, each with a dedicated Python script:| Module | Script | Scope ||--------|--------|-------|| Window Manager | `scripts/window_manager.py` | Desktop window control || Process Manager | `scripts/process_manager.py` | System process management || Hardware Controller | `scripts/hardware_controller.py` | System hardware settings || Serial Communication | `scripts/serial_comm.py` | Arduino / serial devices || IoT Controller | `scripts/iot_controller.py` | Smart home / HTTP APIs |All scripts are standalone CLI tools. No inter-script dependencies.## Execution Model### Prerequisites- **OS**: Windows 10/11- **PowerShell**: 5.1+ (built-in)- **Python**: Managed runtime (auto-provided by WorkBuddy)- **Optional**: `pyserial` (auto-installed by serial_comm.py), `requests` (auto-installed by iot_controller.py), `nircmd` (for precise volume control)### Python PathUse the managed Python runtime for all script executions:```C:\Users\wave\.workbuddy\binaries\python\versions\3.13.12\python.exe```If packages are needed, install them into a venv first:```C:\Users\wave\.workbuddy\binaries\python\versions\3.13.12\python.exe -m venv C:\Users\wave\.workbuddy\binaries\python\envs\defaultC:\Users\wave\.workbuddy\binaries\python\envs\default\bin\pip install pyserial requests```### Script PathAll scripts are located at:```~/.workbuddy/skills/system-controller/scripts/```### Execution PatternAlways use `execute_command` to run scripts. Never try to run them inline.Pattern:```{python_path} {script_path} {action} {flags}```### Safety Rules1. **NEVER execute destructive actions without explicit user confirmation** (shutdown, restart, kill processes, close windows, disable network adapters).2. **Always list/query first** before taking action. Example: run `list` before `close``list --name` before `kill`.3. **Warn the user** before power operations (shutdown, restart, sleep, hibernate) and require explicit confirmation.4. **Never disable critical network adapters** (the one used for active internet connection) without warning.5. **For serial communication**, always `list` ports first to confirm the correct port name.## Module Details### 1. Window Manager (`window_manager.py`)Control desktop application windows via Windows UI Automation and Win32 API.**Capabilities**: list, activate, close, minimize, maximize, resize, send-keys**Decision flow**:1. User says "open/close/focus X" → `list` to find the window → confirm with user → execute action2. User says "resize/move X" → `list` to find PID → `resize` with coordinates3. User says "type/send X to Y" → `activate` target window → `send-keys`**Common examples**:"打开记事本" → `process_manager.py start "notepad.exe"`"关闭Chrome" → `window_manager.py list` → find Chrome → `window_manager.py close --title "Chrome"`"把微信调到前台" → `window_manager.py activate --title "微信"`"全屏当前窗口" → `window_manager.py maximize --title "..."`### 2. Process Manager (`process_manager.py`)List, start, stop, and monitor system processes.**Capabilities**: list, kill, start, info, system**Decision flow**:1. User says "查看进程" → `list` or `list --name`2. User says "结束X进程" → `list --name X` → confirm → `kill --name X`3. User says "启动X" → `start "X"`4. User says "系统状态" → `system`**Common examples**:"有哪些程序在运行" → `process_manager.py system`"关掉所有记事本" → `process_manager.py kill --name notepad`"启动VS Code" → `process_manager.py start "code"`### 3. Hardware Controller (`hardware_controller.py`)Control system hardware settings via PowerShell and WMI.**Capabilities**:- Volume: get, set, mute- Screen: brightness (get/set), display info- Power: lock, sleep, hibernate, shutdown, restart, cancel- Network: list adapters, enable/disable, WiFi scan, network info- USB: list devices**Decision flow**:1. User says "音量/声音" → volume commands2. User says "亮度/屏幕" → screen/brightness commands3. User says "关机/锁屏/睡眠" → power commands (**always confirm**)4. User says "网络/WiFi" → network commands5. User says "USB" → usb list**Common examples**:"把音量调到50" → `hardware_controller.py volume set --level 50`"静音" → `hardware_controller.py volume mute`"屏幕调暗一点" → `hardware_controller.py screen brightness --level 30`"锁屏" → `hardware_controller.py power lock`"扫描WiFi" → `hardware_controller.py network wifi`### 4. Serial Communication (`serial_comm.py`)Communicate with Arduino, ESP32, and other serial devices via pyserial.**Capabilities**: list ports, detect baud rate, send, receive, chat, monitor**Decision flow**:1. User says "串口/Arduino/COM" → `list` ports first2. User says "发送到Arduino" → `send --port COMx --data "..."`3. User says "读取传感器" → `chat --port COMx --data "READ"`**Auto-install**: Automatically installs `pyserial` on first use.**Common examples**:"有哪些串口" → `serial_comm.py list`"给Arduino发指令开灯" → `serial_comm.py send --port COM3 --data "LED_ON"`"读取温度传感器" → `serial_comm.py chat --port COM3 --data "GET_TEMP"`"监听串口数据" → `serial_comm.py monitor --port COM3 --duration 30`### 5. IoT Controller (`iot_controller.py`)Control smart home devices via Home Assistant REST API, Mijia, or generic HTTP endpoints.**Capabilities**:- Home Assistant: list entities, get state, turn on/off/toggle, call any service- Generic HTTP: GET, POST, PUT to any REST endpoint- Mijia: device discovery guidance**Decision flow**:1. User mentions "智能家居/Home Assistant/灯光/温度" → IoT commands2. User says "控制设备/开关灯" → requires URL and token from user3. User says "调用API" → generic HTTP commands**Auto-install**: Automatically installs `requests` on first use.**Common examples**:"列出所有智能设备" → `iot_controller.py homeassistant --url ... --token ... list`"打开客厅灯" → `iot_controller.py homeassistant --url ... --token ... on --entity-id light.living_room`"关掉卧室空调" → `iot_controller.py homeassistant --url ... --token ... off --entity-id climate.bedroom`"调用这个API" → `iot_controller.py http --url ... get --path ...`## Handling Unknown DevicesWhen the user requests control of a device or software not directly covered:1. **Check if it can be started as a process**: Use `process_manager.py start "app_name"`2. **Check if it has windows**: Use `window_manager.py list` to find it3. **Check if it has an API**: Use `iot_controller.py http` to interact4. **Check if it's USB-connected**: Use `hardware_controller.py usb list` then `serial_comm.py list`5. **Suggest alternatives**: If none of the above work, explain the limitation and suggest MCP Server or custom script## Quick ReferenceFor detailed command syntax, read `references/command_reference.md`.

2″C:\Users\username\.workbuddy\skills\system-controller\references\command_reference.md”

# Windows System Controller - Command Reference## Script LocationsAll scripts are located at: `~/.workbuddy/skills/system-controller/scripts/`---## 1. window_manager.py - Window Management### List all visible windows```python window_manager.py list```Returns JSON array of windows with PID, title, and process name.### Activate (bring to foreground)```python window_manager.py activate --title "Notepad"python window_manager.py activate --pid 1234```### Close a window```python window_manager.py close --title "Untitled - Notepad"python window_manager.py close --pid 1234```### Minimize / Maximize```python window_manager.py minimize --title "Chrome"python window_manager.py maximize --pid 1234```### Resize and move```python window_manager.py resize --pid 1234 --x 100 --y 100 --width 800 --height 600```### Send keystrokes (SendKeys format)```python window_manager.py send-keys --title "Notepad" --text "Hello World"```SendKeys special keys`{ENTER}``{TAB}``{ESC}``{F1}``^(c)` for Ctrl+C, `%(f)` for Alt+F---## 2. process_manager.py - Process Management### List all processes```python process_manager.py listpython process_manager.py list --name chrome```### Kill a process```python process_manager.py kill --name notepadpython process_manager.py kill --pid 1234python process_manager.py kill --name chrome --force```### Start a process```python process_manager.py start "notepad.exe"python process_manager.py start "code" --dir "C:\Projects"```### Get process details```python process_manager.py info --pid 1234```### System resource overview```python process_manager.py system```---## 3. hardware_controller.py - Hardware Control### Volume```python hardware_controller.py volume getpython hardware_controller.py volume set --level 75python hardware_controller.py volume mute```Note: Precise volume control requires NirCmd (nircmd.com)### Screen brightness```python hardware_controller.py screen brightnesspython hardware_controller.py screen brightness --level 50```Works on laptop screens and DDC/CI-enabled monitors.### Display info```python hardware_controller.py screen info```### Power management```python hardware_controller.py power lockpython hardware_controller.py power sleeppython hardware_controller.py power hibernatepython hardware_controller.py power shutdown --delay 30python hardware_controller.py power restart --delay 30python hardware_controller.py power cancel```### Network```python hardware_controller.py network adapterspython hardware_controller.py network enable --name "Wi-Fi"python hardware_controller.py network disable --name "Ethernet"python hardware_controller.py network wifipython hardware_controller.py network info```### USB devices```python hardware_controller.py usb list```---## 4. serial_comm.py - Serial Communication### List serial ports```python serial_comm.py list```### Auto-detect baud rate```python serial_comm.py detect --port COM3```### Send data```python serial_comm.py send --port COM3 --data "LED_ON" --baud 9600```### Receive data```python serial_comm.py receive --port COM3 --baud 9600 --timeout 5```### Send and wait for response```python serial_comm.py chat --port COM3 --data "GET_TEMP" --baud 9600```### Monitor mode (real-time)```python serial_comm.py monitor --port COM3 --baud 9600 --duration 30```Dependencies: `pip install pyserial` (auto-installed on first use)---## 5. iot_controller.py - IoT / Smart Home### Home Assistant```# List all entitiespython iot_controller.py homeassistant --url http://192.168.1.100:8123 --token YOUR_TOKEN list# Get entity statepython iot_controller.py homeassistant --url http://192.168.1.100:8123 --token YOUR_TOKEN state --entity-id light.living_room# Turn on/off/togglepython iot_controller.py homeassistant --url http://192.168.1.100:8123 --token YOUR_TOKEN on --entity-id light.living_roompython iot_controller.py homeassistant --url http://192.168.1.100:8123 --token YOUR_TOKEN off --entity-id light.living_roompython iot_controller.py homeassistant --url http://192.168.1.100:8123 --token YOUR_TOKEN toggle --entity-id switch.fan# Call any service with parameterspython iot_controller.py homeassistant --url http://192.168.1.100:8123 --token YOUR_TOKEN on --entity-id light.living_room --data '{"brightness_pct": 50, "color_temp": 350}'# Call arbitrary servicepython iot_controller.py homeassistant --url http://192.168.1.100:8123 --token YOUR_TOKEN call --domain climate --service set_temperature --entity-id climate.bedroom --data '{"temperature": 24}'```### Generic HTTP/REST```# GET requestpython iot_controller.py http --url http://192.168.1.50:8080 get --path /api/statuspython iot_controller.py http --url http://192.168.1.50:8080 get --path /api/data --header "Authorization: Bearer TOKEN"# POST requestpython iot_controller.py http --url http://192.168.1.50:8080 post --path /api/command --body '{"action":"on"}'# PUT requestpython iot_controller.py http --url http://192.168.1.50:8080 put --path /api/config --body '{"name":"updated"}'```### Mijia / XiaoMi```python iot_controller.py mijia discover```Requires: `pip install miio` (manual installation)Dependencies: `pip install requests` (auto-installed on first use)---## Common Patterns### Arduino LED Control1. Connect Arduino via USB2. List ports: `python serial_comm.py list`3. Send command: `python serial_comm.py send --port COM3 --data "LED_ON" --baud 9600`4. Read sensor: `python serial_comm.py chat --port COM3 --data "READ_TEMP" --baud 9600`### Smart Home Automation1. List lights: `python iot_controller.py homeassistant --url ... --token ... list`2. Turn on: `python iot_controller.py homeassistant --url ... --token ... on --entity-id light.bedroom`3. Set brightness: `python iot_controller.py homeassistant --url ... --token ... on --entity-id light.bedroom --data '{"brightness_pct":30}'`### Application Automation1. Find window: `python window_manager.py list`2. Activate: `python window_manager.py activate --title "Excel"`3. Send input: `python window_manager.py send-keys --title "Excel" --text "^(s)"`  (Ctrl+S)4. Close: `python window_manager.py close --title "Excel"`

3″C:\Users\username\.workbuddy\skills\system-controller\scripts\common.py”

#!/usr/bin/env python3"""Shared utilities for system-controller scripts.Handles Windows encoding issues and PowerShell execution."""import subprocessimport sysimport osdef run_ps(script, timeout=30):    """    Execute PowerShell script with proper encoding handling.    Returns (stdout: str, stderr: str, returncode: int)    """    env = os.environ.copy()    env["PYTHONIOENCODING"] = "utf-8"    # Prepend encoding setup to ensure UTF-8 output    encoding_setup = (        "[Console]::InputEncoding = [Console]::OutputEncoding = "        "[System.Text.Encoding]::UTF8; "        "$OutputEncoding = [System.Text.Encoding]::UTF8; "    )    try:        result = subprocess.run(            ["powershell""-NoProfile""-NonInteractive""-Command",             encoding_setup + script],            capture_output=True,            text=True,            encoding="utf-8",            errors="replace",            timeout=timeout,            env=env        )        stdout = (result.stdout or "").strip()        stderr = (result.stderr or "").strip()        return stdout, stderr, result.returncode    except subprocess.TimeoutExpired:        return """ERROR: Command timed out", -1    except Exception as e:        return ""f"ERROR: {e}", -1def run_cmd(command, timeout=30):    """    Execute a shell command with proper encoding.    Returns (stdout: str, stderr: str, returncode: int)    """    env = os.environ.copy()    env["PYTHONIOENCODING"] = "utf-8"    try:        result = subprocess.run(            command,            capture_output=True,            text=True,            encoding="utf-8",            errors="replace",            timeout=timeout,            shell=True,            env=env        )        stdout = (result.stdout or "").strip()        stderr = (result.stderr or "").strip()        return stdout, stderr, result.returncode    except subprocess.TimeoutExpired:        return """ERROR: Command timed out", -1    except Exception as e:        return ""f"ERROR: {e}", -1def json_safe(obj):    """Ensure output is serializable, replacing None with null."""    if obj is None:        return "null"    return obj

4″C:\Users\username\.workbuddy\skills\system-controller\scripts\window_manager.py”

#!/usr/bin/env python3"""Window Manager - Windows desktop application control via PowerShell UI Automation.Requirements: Windows 10/11, PowerShell 5.1+Dependencies: None (uses built-in PowerShell and Windows APIs)"""import subprocessimport jsonimport sysimport timeimport os# Fix print encoding for Windowsif sys.stdout.encoding != 'utf-8':    sys.stdout.reconfigure(encoding='utf-8', errors='replace')if sys.stderr.encoding != 'utf-8':    sys.stderr.reconfigure(encoding='utf-8', errors='replace')sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))from common import run_ps as _run_psdef list_windows():    """List all visible windows with title, process name, position, and size."""    script = r"""Add-Type -AssemblyName UIAutomationClient$windows = Get-Process | Where-Object { $_.MainWindowTitle -ne '' } | ForEach-Object {    try {        $rect = $_.MainWindowHandle | ForEach-Object {            $r = New-Object System.Drawing.Rectangle            [System.Drawing.Rectangle]::Intersect([System.Drawing.Rectangle]::Empty, $r)            [void][System.Runtime.InteropServices.Marshal]::GetClassLongHash($_.Handle)        }        [PSCustomObject]@{            PID = $_.Id            Title = $_.MainWindowTitle            ProcessName = $_.ProcessName            MainWindowHandle = $_.MainWindowHandle.ToInt64()        }    } catch { }}$windows = $windows | Sort-Object -Property Title -Unique | Where-Object { $_.Title -ne '' }$windows | ConvertTo-Json -Compress"""    stdout, stderr, code = _run_ps(script)    if code != 0 or not stdout:        # Fallback: simpler approach        script2 = """Get-Process | Where-Object { $_.MainWindowTitle -ne '' } | Select-Object Id, ProcessName, MainWindowTitle | ConvertTo-Json -Compress"""        stdout, stderr, code = _run_ps(script2)    return stdoutdef activate_window(pid=None, title=None):    """Bring a window to the foreground by PID or title substring."""    if pid:        script = f"""Add-Type @"using System;using System.Runtime.InteropServices;public classWin32 {{    [DllImport("user32.dll")]    public static extern bool SetForegroundWindow(IntPtr hWnd);    [DllImport("user32.dll")]    public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);    [DllImport("user32.dll")]    public static extern bool IsIconic(IntPtr hWnd);}}"@$proc = Get-Process -Id {pid} -ErrorAction SilentlyContinueif ($proc) {{    $hwnd = $proc.MainWindowHandle    if ([Win32]::IsIconic($hwnd)) {{ [Win32]::ShowWindow($hwnd, 9) }}    [Win32]::SetForegroundWindow($hwnd)    Write-Output "OK: Activated window (PID: {pid}, Title: $($proc.MainWindowTitle))"}} else {{    Write-Output "ERROR: Process with PID {pid} not found"}}"""    elif title:        escaped_title = title.replace("'""''")        script = f"""Add-Type @"using System;using System.Runtime.InteropServices;public classWin32 {{    [DllImport("user32.dll")]    public static extern bool SetForegroundWindow(IntPtr hWnd);    [DllImport("user32.dll")]    public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);    [DllImport("user32.dll")]    public static extern bool IsIconic(IntPtr hWnd);}}"@$proc = Get-Process | Where-Object {{ $_.MainWindowTitle -like '*{escaped_title}*' }} | Select-Object -First 1if ($proc) {{    $hwnd = $proc.MainWindowHandle    if ([Win32]::IsIconic($hwnd)) {{ [Win32]::ShowWindow($hwnd, 9) }}    [Win32]::SetForegroundWindow($hwnd)    Write-Output "OK: Activated window (PID: $($proc.Id), Title: $($proc.MainWindowTitle))"}} else {{    Write-Output "ERROR: No window found matching '{title}'"}}"""    else:        return "ERROR: Provide --pid or --title"    stdout, stderr, code = _run_ps(script)    return stdout if stdout else stderrdef close_window(pid=None, title=None):    """Close a window by PID or title substring."""    if pid:        script = f"""$proc = Get-Process -Id {pid} -ErrorAction SilentlyContinueif ($proc) {{    $proc.CloseMainWindow() | Out-Null    Start-Sleep -Seconds 1    if (!$proc.HasExited) {{ $proc | Stop-Process -Force }}    Write-Output "OK: Closed window (PID: {pid})"}} else {{    Write-Output "ERROR: Process not found"}}"""    elif title:        escaped_title = title.replace("'""''")        script = f"""$procs = Get-Process | Where-Object {{ $_.MainWindowTitle -like '*{escaped_title}*' }}if ($procs) {{    $procs | ForEach-Object {{        $_.CloseMainWindow() | Out-Null    }}    Start-Sleep -Seconds 1    $procs | Where-Object {{ !$_.HasExited }} | Stop-Process -Force    Write-Output "OK: Closed $($procs.Count) window(s) matching '{title}'"}} else {{    Write-Output "ERROR: No window found"}}"""    else:        return "ERROR: Provide --pid or --title"    stdout, stderr, code = _run_ps(script)    return stdout if stdout else stderrdef minimize_window(pid=None, title=None):    """Minimize a window by PID or title substring."""    if pid:        script = f"""Add-Type @"using System;using System.Runtime.InteropServices;public classWin32 {{    [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);}}"@$proc = Get-Process -Id {pid} -ErrorAction SilentlyContinueif ($proc) {{    [Win32]::ShowWindow($proc.MainWindowHandle, 6)    Write-Output "OK: Minimized (PID: {pid})"}} else {{    Write-Output "ERROR: Process not found"}}"""    elif title:        escaped_title = title.replace("'""''")        script = f"""Add-Type @"using System;using System.Runtime.InteropServices;public classWin32 {{    [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);}}"@$proc = Get-Process | Where-Object {{ $_.MainWindowTitle -like '*{escaped_title}*' }} | Select-Object -First 1if ($proc) {{    [Win32]::ShowWindow($proc.MainWindowHandle, 6)    Write-Output "OK: Minimized: $($proc.MainWindowTitle)"}} else {{    Write-Output "ERROR: No window found"}}"""    else:        return "ERROR: Provide --pid or --title"    stdout, stderr, code = _run_ps(script)    return stdout if stdout else stderrdef maximize_window(pid=None, title=None):    """Maximize a window by PID or title substring."""    if pid:        script = f"""Add-Type @"using System;using System.Runtime.InteropServices;public classWin32 {{    [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);}}"@$proc = Get-Process -Id {pid} -ErrorAction SilentlyContinueif ($proc) {{    [Win32]::ShowWindow($proc.MainWindowHandle, 3)    Write-Output "OK: Maximized (PID: {pid})"}} else {{    Write-Output "ERROR: Process not found"}}"""    elif title:        escaped_title = title.replace("'""''")        script = f"""Add-Type @"using System;using System.Runtime.InteropServices;public classWin32 {{    [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);}}"@$proc = Get-Process | Where-Object {{ $_.MainWindowTitle -like '*{escaped_title}*' }} | Select-Object -First 1if ($proc) {{    [Win32]::ShowWindow($proc.MainWindowHandle, 3)    Write-Output "OK: Maximized: $($proc.MainWindowTitle)"}} else {{    Write-Output "ERROR: No window found"}}"""    else:        return "ERROR: Provide --pid or --title"    stdout, stderr, code = _run_ps(script)    return stdout if stdout else stderrdef resize_window(pid=None, title=None, x=None, y=None, width=None, height=None):    """Move and resize a window. All position/size parameters in pixels."""    if not (pid or title):        return "ERROR: Provide --pid or --title"    if x is None or y is None or width is None or height is None:        return "ERROR: Provide --x, --y, --width, --height"    target = ""    if pid:        target = f"$proc = Get-Process -Id {pid} -ErrorAction SilentlyContinue"    else:        escaped_title = title.replace("'""''")        target = f'$proc = Get-Process | Where-Object {{ $_.MainWindowTitle -like \'*{escaped_title}*\' }} | Select-Object -First 1'    script = f"""Add-Type @"using System;using System.Runtime.InteropServices;public classWin32 {{    [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndAfter, int X, int Y, int cx, int cy, uint uFlags);}}"@{target}if ($proc) {{    $result = [Win32]::SetWindowPos($proc.MainWindowHandle, [IntPtr]::Zero, {x}, {y}, {width}, {height}, 0x0040)    if ($result) {{ Write-Output "OK: Window moved to ({x},{y}) size {width}x{height}" }}    else {{ Write-Output "ERROR: Failed to resize" }}}} else {{    Write-Output "ERROR: Window not found"}}"""    stdout, stderr, code = _run_ps(script)    return stdout if stdout else stderrdef send_keys(text, pid=None, title=None):    """Send keystrokes to a window. Uses SendKeys format."""    if not text:        return "ERROR: Provide text to send"    if pid:        script = f"""Add-Type -AssemblyName System.Windows.Forms$proc = Get-Process -Id {pid} -ErrorAction SilentlyContinueif ($proc) {{    Start-Sleep -Milliseconds 200    [System.Windows.Forms.SendKeys]::SendWait('{text}')    Write-Output "OK: Sent keys to PID {pid}"}} else {{    Write-Output "ERROR: Process not found"}}"""    elif title:        escaped_title = title.replace("'""''")        script = f"""Add-Type -AssemblyName System.Windows.Forms$proc = Get-Process | Where-Object {{ $_.MainWindowTitle -like '*{escaped_title}*' }} | Select-Object -First 1if ($proc) {{    [Win32Helper]::BringToForeground($proc.MainWindowHandle)    Start-Sleep -Milliseconds 200    [System.Windows.Forms.SendKeys]::SendWait('{text}')    Write-Output "OK: Sent keys"}} else {{    Write-Output "ERROR: Window not found"}}"""    else:        return "ERROR: Provide --pid or --title"    stdout, stderr, code = _run_ps(script)    return stdout if stdout else stderrdef main():    import argparse    parser = argparse.ArgumentParser(description="Window Manager - Control desktop windows")    sub = parser.add_subparsers(dest="action")    p_list = sub.add_parser("list", help="List all visible windows")    p_act = sub.add_parser("activate", help="Bring window to foreground")    p_act.add_argument("--pid"type=int)    p_act.add_argument("--title"type=str)    p_close = sub.add_parser("close", help="Close a window")    p_close.add_argument("--pid"type=int)    p_close.add_argument("--title"type=str)    p_min = sub.add_parser("minimize", help="Minimize a window")    p_min.add_argument("--pid"type=int)    p_min.add_argument("--title"type=str)    p_max = sub.add_parser("maximize", help="Maximize a window")    p_max.add_argument("--pid"type=int)    p_max.add_argument("--title"type=str)    p_resize = sub.add_parser("resize", help="Move and resize a window")    p_resize.add_argument("--pid"type=int)    p_resize.add_argument("--title"type=str)    p_resize.add_argument("--x"type=int, required=True)    p_resize.add_argument("--y"type=int, required=True)    p_resize.add_argument("--width"type=int, required=True)    p_resize.add_argument("--height"type=int, required=True)    p_keys = sub.add_parser("send-keys", help="Send keystrokes to a window")    p_keys.add_argument("--pid"type=int)    p_keys.add_argument("--title"type=str)    p_keys.add_argument("--text"type=str, required=True)    args = parser.parse_args()    if args.action == "list":        print(list_windows())    elif args.action == "activate":        print(activate_window(args.pid, args.title))    elif args.action == "close":        print(close_window(args.pid, args.title))    elif args.action == "minimize":        print(minimize_window(args.pid, args.title))    elif args.action == "maximize":        print(maximize_window(args.pid, args.title))    elif args.action == "resize":        print(resize_window(args.pid, args.title, args.x, args.y, args.width, args.height))    elif args.action == "send-keys":        print(send_keys(args.text, args.pid, args.title))    else:        parser.print_help()if __name__ == "__main__":    main()

5″C:\Users\username\.workbuddy\skills\system-controller\scripts\process_manager.py”

#!/usr/bin/env python3"""Process Manager - List, start, stop, and monitor system processes.Requirements: Windows 10/11, PowerShell 5.1+Dependencies: None (uses built-in PowerShell)"""import subprocessimport sysimport osif sys.stdout.encoding != 'utf-8':    sys.stdout.reconfigure(encoding='utf-8', errors='replace')if sys.stderr.encoding != 'utf-8':    sys.stderr.reconfigure(encoding='utf-8', errors='replace')sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))from common import run_ps as _run_psdef list_processes(name=None):    """List running processes. Optionally filter by name."""    if name:        escaped = name.replace("'""''")        script = f"""Get-Process -Name '*{escaped}*' -ErrorAction SilentlyContinue |    Select-Object Id, ProcessName, CPU, WorkingSet64, MainWindowTitle |    ForEach-Object {{        [PSCustomObject]@{{            PID = $_.Id            Name = $_.ProcessName            CPU_sec = [math]::Round($_.CPU, 2)            Memory_MB = [math]::Round($_.WorkingSet64 / 1MB, 2)            Window = if ($_.MainWindowTitle) {{ $_.MainWindowTitle }} else {{ '' }}        }}    }} | ConvertTo-Json -Compress"""    else:        script = r"""Get-Process | Select-Object Id, ProcessName, CPU, WorkingSet64, MainWindowTitle |    ForEach-Object {        [PSCustomObject]@{            PID = $_.Id            Name = $_.ProcessName            CPU_sec = [math]::Round($_.CPU, 2)            Memory_MB = [math]::Round($_.WorkingSet64 / 1MB, 2)            Window = if ($_.MainWindowTitle) { $_.MainWindowTitle } else { '' }        }    } | ConvertTo-Json -Compress"""    stdout, stderr, code = _run_ps(script)    if not stdout:        # Fallback for empty result        return "[]"    return stdoutdef kill_process(pid=None, name=None, force=False):    """Kill a process by PID or name."""    flag = "-Force" if force else ""    if pid:        script = f"""Stop-Process -Id {pid} {flag} -ErrorAction SilentlyContinueif ($?) {{    Write-Output "OK: Killed process PID {pid}"}} else {{    Write-Output "ERROR: Process PID {pid} not found or access denied"}}"""    elif name:        escaped = name.replace("'""''")        script = f"""$procs = Get-Process -Name '*{escaped}*' -ErrorAction SilentlyContinueif ($procs) {{    $procs | Stop-Process {flag} -ErrorAction SilentlyContinue    Write-Output "OK: Killed $($procs.Count) process(es) matching '{name}'"}} else {{    Write-Output "ERROR: No process found matching '{name}'"}}"""    else:        return "ERROR: Provide --pid or --name"    stdout, stderr, code = _run_ps(script)    return stdout if stdout else stderrdef start_process(command, working_dir=None, wait=False):    """Start a new process."""    escaped = command.replace('"''\\"')    dir_part = f"-WorkingDirectory '{working_dir}'" if working_dir else ""    wait_part = "-Wait" if wait else ""    script = f"""try {{    Start-Process -FilePath "{escaped}{dir_part} {wait_part} -ErrorAction Stop    Write-Output "OK: Started '{command}'"}} catch {{    Write-Output "ERROR: $($_.Exception.Message)"}}"""    stdout, stderr, code = _run_ps(script)    return stdout if stdout else stderrdef get_process_info(pid):    """Get detailed information about a specific process."""    script = f"""$proc = Get-Process -Id {pid} -ErrorAction SilentlyContinueif ($proc) {{    [PSCustomObject]@{{        PID = $proc.Id        Name = $proc.ProcessName        Path = $proc.Path        StartTime = $proc.StartTime        CPU_sec = [math]::Round($proc.CPU, 2)        Memory_MB = [math]::Round($proc.WorkingSet64 / 1MB, 2)        Threads = $proc.Threads.Count        Handles = $proc.HandleCount        MainWindowTitle = $proc.MainWindowTitle        Responding = $proc.Responding    }} | ConvertTo-Json}} else {{    Write-Output "ERROR: Process PID {pid} not found"}}"""    stdout, stderr, code = _run_ps(script)    return stdout if stdout else stderrdef get_system_info():    """Get overall system resource usage."""    script = r"""$os = Get-CimInstance Win32_OperatingSystem$totalGB = [math]::Round($os.TotalVisibleMemorySize / 1MB, 2)$freeGB = [math]::Round($os.FreePhysicalMemory / 1MB, 2)$usedGB = [math]::Round($totalGB - $freeGB, 2)$cpu = Get-CimInstance Win32_Processor | Select-Object -First 1$uptime = (Get-Date) - $os.LastBootUpTime[PSCustomObject]@{    ComputerName = $env:COMPUTERNAME    OS = $os.Caption    CPU_Load_Pct = $cpu.LoadPercentage    RAM_Total_GB = $totalGB    RAM_Used_GB = $usedGB    RAM_Free_GB = $freeGB    RAM_Usage_Pct = [math]::Round($usedGB / $totalGB * 100, 1)    Uptime_Days = [math]::Floor($uptime.TotalDays)    Uptime_Hours = $uptime.Hours    Process_Count = (Get-Process).Count} | ConvertTo-Json"""    stdout, stderr, code = _run_ps(script)    return stdout if stdout else stderrdef main():    import argparse    parser = argparse.ArgumentParser(description="Process Manager")    sub = parser.add_subparsers(dest="action")    p_list = sub.add_parser("list"help="List processes")    p_list.add_argument("--name"type=strhelp="Filter by name")    p_kill = sub.add_parser("kill"help="Kill a process")    p_kill.add_argument("--pid"type=int)    p_kill.add_argument("--name"type=str)    p_kill.add_argument("--force", action="store_true")    p_start = sub.add_parser("start"help="Start a process")    p_start.add_argument("command"type=str)    p_start.add_argument("--dir"type=strhelp="Working directory")    p_start.add_argument("--wait", action="store_true")    p_info = sub.add_parser("info"help="Get process details")    p_info.add_argument("--pid"type=int, required=True)    p_sys = sub.add_parser("system"help="Get system resource info")    args = parser.parse_args()    if args.action == "list":        print(list_processes(args.name))    elif args.action == "kill":        print(kill_process(args.pid, args.name, args.force))    elif args.action == "start":        print(start_process(args.command, args.dir, args.wait))    elif args.action == "info":        print(get_process_info(args.pid))    elif args.action == "system":        print(get_system_info())    else:        parser.print_help()if __name__ == "__main__":    main()

6″C:\Users\username\.workbuddy\skills\system-controller\scripts\hardware_controller.py”

#!/usr/bin/env python3"""Hardware Controller - Control Windows system hardware settings.Capabilities:  - Volume control (get/set/mute)  - Screen brightness (get/set)  - Display settings (resolution, orientation)  - Power management (sleep, hibernate, shutdown, restart, lock)  - Network adapters (list, enable, disable)  - WiFi (list networks)  - USB devices (list)Requirements: Windows 10/11, PowerShell 5.1+Dependencies: None for basic features."""import subprocessimport sysimport osif sys.stdout.encoding != 'utf-8':    sys.stdout.reconfigure(encoding='utf-8', errors='replace')if sys.stderr.encoding != 'utf-8':    sys.stderr.reconfigure(encoding='utf-8', errors='replace')sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))from common import run_ps as _run_ps# ========== Volume Control ==========def get_volume():    """Get current volume level and mute state."""    script = r"""try {    Get-WmiObject Win32_SoundDevice | Select-Object -First 1 | ForEach-Object {        [PSCustomObject]@{            Device = $_.Name            Status = $_.Status        }    } | ConvertTo-Json} catch {    Write-Output '{"Note":"Audio device info unavailable"}'}"""    stdout, _, _ = _run_ps(script)    return stdoutdef set_volume(level):    """Set volume level (0-100). Requires NirCmd for precise control."""    if not (0 <= level <= 100):        return "ERROR: Volume level must be 0-100"    script = f"""try {{    $nircmd = Get-Command nircmd -ErrorAction SilentlyContinue    if ($nircmd) {{        & nircmd.exe setsysvolume {int(level * 655.35)}        Write-Output "OK: Volume set to {level}%"        return    }}    Write-Output "INFO: For precise volume control, install NirCmd (nircmd.com) and add to PATH"}} catch {{    Write-Output "ERROR: $($_.Exception.Message)"}}"""    stdout, _, _ = _run_ps(script)    return stdoutdef toggle_mute():    """Toggle system mute."""    script = r"""Add-Type -TypeDefinition @"using System;using System.Runtime.InteropServices;public class AudioMute {    [DllImport("user32.dll")]    public static extern IntPtr SendMessageW(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);    public const int WM_APPCOMMAND = 0x319;    public const int APPCMD_VOLUME_MUTE = 0x08;}"@$hwnd = (Get-Process -Id $PID).MainWindowHandle[AudioMute]::SendMessageW($hwnd, [AudioMute]::WM_APPCOMMAND, [IntPtr]::Zero, (IntPtr)([AudioMute]::APPCMD_VOLUME_MUTE * 0x10000))Write-Output "OK: Toggle mute sent""""    stdout, _, _ = _run_ps(script)    return stdout# ========== Screen / Display ==========def get_brightness():    """Get screen brightness level."""    script = r"""try {    $brightness = Get-CimInstance -Namespace root/WMI -ClassName WmiMonitorBrightness -ErrorAction Stop    $current = $brightness.CurrentBrightness    [PSCustomObject]@{        Brightness = $current        MaxBrightness = 100        MinBrightness = 0    } | ConvertTo-Json} catch {    Write-Output '{"Error":"Could not read brightness (may not be supported on this display)"}'}"""    stdout, _, _ = _run_ps(script)    return stdoutdef set_brightness(level):    """Set screen brightness (0-100)."""    if not (0 <= level <= 100):        return "ERROR: Brightness must be 0-100"    script = f"""try {{    $delay = 0    Get-CimInstance -Namespace root/WMI -ClassName WmiMonitorBrightnessMethods -ErrorAction Stop |        WmiSetBrightness($delay, {level})    Write-Output "OK: Brightness set to {level}%"}} catch {{    Write-Output "ERROR: Could not set brightness. Requires compatible display (laptop or DDC/CI monitor)."}}"""    stdout, _, _ = _run_ps(script)    return stdoutdef get_display_info():    """Get display adapter and resolution information."""    script = r"""Get-CimInstance Win32_VideoController | ForEach-Object {    [PSCustomObject]@{        Name = $_.Name        Resolution = "$($_.CurrentHorizontalResolution)x$($_.CurrentVerticalResolution)"        RefreshRate = $_.CurrentRefreshRate        VRAM_MB = [math]::Round($_.AdapterRAM / 1MB, 0)        DriverVersion = $_.DriverVersion        Status = $_.Status    }} | ConvertTo-Json -Compress"""    stdout, _, _ = _run_ps(script)    return stdout# ========== Power Management ==========def lock_screen():    """Lock the workstation."""    script = r"rundll32.exe user32.dll,LockWorkStation"    _run_ps(script)    return "OK: Screen locked"def sleep_system():    """Put the system to sleep."""    script = r"""Add-Type -AssemblyName System.Windows.Forms[System.Windows.Forms.Application]::SetSuspendState([System.Windows.Forms.PowerState]::Suspend, $false, $false)Write-Output "OK: System entering sleep mode""""    stdout, _, _ = _run_ps(script)    return stdoutdef hibernate():    """Hibernate the system."""    script = r"""Add-Type -AssemblyName System.Windows.Forms[System.Windows.Forms.Application]::SetSuspendState([System.Windows.Forms.PowerState]::Hibernate, $false, $false)Write-Output "OK: System hibernating""""    stdout, _, _ = _run_ps(script)    return stdoutdef shutdown(delay_sec=60):    """Schedule system shutdown."""    script = f"""shutdown /s /t {delay_sec} /c "Shutdown initiated by system-controller"Write-Output "OK: System will shutdown in {delay_sec} seconds. Run 'shutdown /a' to cancel.""""    stdout, _, _ = _run_ps(script)    return stdoutdef restart(delay_sec=60):    """Schedule system restart."""    script = f"""shutdown /r /t {delay_sec} /c "Restart initiated by system-controller"Write-Output "OK: System will restart in {delay_sec} seconds. Run 'shutdown /a' to cancel.""""    stdout, _, _ = _run_ps(script)    return stdoutdef cancel_shutdown():    """Cancel a scheduled shutdown/restart."""    script = r"shutdown /a; Write-Output 'OK: Shutdown/restart cancelled'"    stdout, _, _ = _run_ps(script)    return stdout# ========== Network ==========def list_network_adapters():    """List all network adapters with status."""    script = r"""Get-NetAdapter | Select-Object Name, InterfaceDescription, Status, LinkSpeed, MacAddress |    ForEach-Object {        [PSCustomObject]@{            Name = $_.Name            Description = $_.InterfaceDescription            Status = $_.Status            Speed = $_.LinkSpeed            MAC = $_.MacAddress        }    } | ConvertTo-Json -Compress"""    stdout, _, _ = _run_ps(script)    return stdoutdef enable_adapter(name):    """Enable a network adapter."""    escaped = name.replace("'""''")    script = f"""try {{    Enable-NetAdapter -Name '{escaped}' -Confirm:$false -ErrorAction Stop    Write-Output "OK: Adapter '{name}' enabled"}} catch {{    Write-Output "ERROR: $($_.Exception.Message)"}}"""    stdout, _, _ = _run_ps(script)    return stdoutdef disable_adapter(name):    """Disable a network adapter."""    escaped = name.replace("'""''")    script = f"""try {{    Disable-NetAdapter -Name '{escaped}' -Confirm:$false -ErrorAction Stop    Write-Output "OK: Adapter '{name}' disabled"}} catch {{    Write-Output "ERROR: $($_.Exception.Message)"}}"""    stdout, _, _ = _run_ps(script)    return stdoutdef list_wifi_networks():    """List available WiFi networks."""    script = r"""try {    netsh wlan show networks mode=bssid} catch {    Write-Output "ERROR: Could not scan WiFi networks."}"""    stdout, _, _ = _run_ps(script)    return stdoutdef get_network_info():    """Get current network configuration."""    script = r"""Get-NetIPConfiguration | ForEach-Object {    [PSCustomObject]@{        Interface = $_.InterfaceAlias        IPv4 = if ($_.IPv4Address) { $_.IPv4Address.IPAddress -join ', ' } else { '' }        IPv6 = if ($_.IPv6Address) { $_.IPv6Address.IPAddress -join ', ' } else { '' }        DNS = if ($_.DNSServer) { $_.DNSServer.ServerAddresses -join ', ' } else { '' }    }} | ConvertTo-Json -Compress"""    stdout, _, _ = _run_ps(script)    return stdout# ========== USB / Device ==========def list_usb_devices():    """List connected USB devices."""    script = r"""Get-PnpDevice -PresentOnly | Where-Object { $_.InstanceId -like 'USB\*' } |    Select-Object FriendlyName, Status, Class, InstanceId |    ForEach-Object {        [PSCustomObject]@{            Device = $_.FriendlyName            Status = $_.Status            Class = $_.Class            InstanceId = $_.InstanceId        }    } | ConvertTo-Json -Compress"""    stdout, _, _ = _run_ps(script)    return stdoutdef main():    import argparse    parser = argparse.ArgumentParser(description="Hardware Controller")    sub = parser.add_subparsers(dest="category")    # Volume    p_vol = sub.add_parser("volume"help="Volume control")    vol_sub = p_vol.add_subparsers(dest="action")    vol_sub.add_parser("get"help="Get volume level")    vol_set = vol_sub.add_parser("set"help="Set volume")    vol_set.add_argument("--level"type=int, required=Truehelp="0-100")    vol_sub.add_parser("mute"help="Toggle mute")    # Screen    p_scr = sub.add_parser("screen"help="Screen/display control")    scr_sub = p_scr.add_subparsers(dest="action")    scr_sub.add_parser("info"help="Get display info")    bri_get = scr_sub.add_parser("brightness"help="Get/set brightness")    bri_get.add_argument("--level"type=inthelp="0-100")    # Power    p_pwr = sub.add_parser("power"help="Power management")    pwr_sub = p_pwr.add_subparsers(dest="action")    pwr_sub.add_parser("lock"help="Lock screen")    pwr_sub.add_parser("sleep"help="Sleep mode")    pwr_sub.add_parser("hibernate"help="Hibernate")    pwr_sd = pwr_sub.add_parser("shutdown"help="Shutdown")    pwr_sd.add_argument("--delay"type=int, default=60help="Seconds")    pwr_rs = pwr_sub.add_parser("restart"help="Restart")    pwr_rs.add_argument("--delay"type=int, default=60help="Seconds")    pwr_sub.add_parser("cancel"help="Cancel scheduled shutdown")    # Network    p_net = sub.add_parser("network"help="Network control")    net_sub = p_net.add_subparsers(dest="action")    net_sub.add_parser("adapters"help="List network adapters")    net_en = net_sub.add_parser("enable"help="Enable adapter")    net_en.add_argument("--name"type=str, required=True)    net_dis = net_sub.add_parser("disable"help="Disable adapter")    net_dis.add_argument("--name"type=str, required=True)    net_sub.add_parser("wifi"help="List WiFi networks")    net_sub.add_parser("info"help="Get network config")    # USB    p_usb = sub.add_parser("usb"help="USB devices")    usb_sub = p_usb.add_subparsers(dest="action")    usb_sub.add_parser("list"help="List USB devices")    args = parser.parse_args()    if args.category == "volume":        if args.action == "get":            print(get_volume())        elif args.action == "set":            print(set_volume(args.level))        elif args.action == "mute":            print(toggle_mute())        else:            p_vol.print_help()    elif args.category == "screen":        if args.action == "info":            print(get_display_info())        elif args.action == "brightness":            if args.level is not None:                print(set_brightness(args.level))            else:                print(get_brightness())        else:            p_scr.print_help()    elif args.category == "power":        if args.action == "lock":            print(lock_screen())        elif args.action == "sleep":            print(sleep_system())        elif args.action == "hibernate":            print(hibernate())        elif args.action == "shutdown":            print(shutdown(args.delay))        elif args.action == "restart":            print(restart(args.delay))        elif args.action == "cancel":            print(cancel_shutdown())        else:            p_pwr.print_help()    elif args.category == "network":        if args.action == "adapters":            print(list_network_adapters())        elif args.action == "enable":            print(enable_adapter(args.name))        elif args.action == "disable":            print(disable_adapter(args.name))        elif args.action == "wifi":            print(list_wifi_networks())        elif args.action == "info":            print(get_network_info())        else:            p_net.print_help()    elif args.category == "usb":        if args.action == "list":            print(list_usb_devices())        else:            p_usb.print_help()    else:        parser.print_help()if __name__ == "__main__":    main()

7″C:\Users\username\.workbuddy\skills\system-controller\scripts\serial_comm.py”

#!/usr/bin/env python3"""Serial Communication - Communicate with Arduino and other serial devices.Capabilities:  - List available serial ports  - Connect to a serial device  - Send data (text or bytes)  - Receive data (with timeout)  - Continuous monitor mode  - Auto-detect common baud ratesRequirements: pyserial (pip install pyserial)"""import sysimport jsonimport timeimport subprocessimport osif sys.stdout.encoding != 'utf-8':    sys.stdout.reconfigure(encoding='utf-8', errors='replace')if sys.stderr.encoding != 'utf-8':    sys.stderr.reconfigure(encoding='utf-8', errors='replace')def check_pyserial():    """Check if pyserial is installed, install if not."""    try:        import serial        import serial.tools.list_ports        return True    except ImportError:        print("Installing pyserial...")        subprocess.check_call(            [sys.executable, "-m""pip""install""pyserial""-q"],            stdout=subprocess.DEVNULL        )        try:            import serial            return True        except ImportError:            return Falsedef list_ports():    """List all available serial ports."""    if not check_pyserial():        return '{"error":"Failed to install pyserial"}'    import serial.tools.list_ports    ports = []    for port in serial.tools.list_ports.comports():        ports.append({            "device": port.device,            "description": port.description,            "hwid": port.hwid,            "vendor": port.vid if port.vid else None,            "product": port.pid if port.pid else None,        })    if not ports:        return json.dumps({"info""No serial ports found"}, ensure_ascii=False)    return json.dumps(ports, indent=2, ensure_ascii=False)def detect_baud_rate(port, timeout=2):    """Try to detect the baud rate by testing common rates."""    if not check_pyserial():        return "ERROR: pyserial not available"    import serial    common_rates = [9600115200576003840019200480024001200]    for rate in common_rates:        try:            ser = serial.Serial(port, rate, timeout=timeout)            ser.write(b'\n')            time.sleep(0.5)            response = ser.read(ser.in_waiting or 1)            ser.close()            if response:                return json.dumps({                    "detected_rate": rate,                    "response_preview": response.decode('utf-8', errors='replace')[:100]                })        except Exception:            continue    return json.dumps({"detected_rate"9600"note""Could not auto-detect, using default 9600"})def send_data(port, data, baud_rate=9600, encoding="utf-8", newline=True):    """Send data to a serial port."""    if not check_pyserial():        return "ERROR: pyserial not available"    import serial    try:        ser = serial.Serial(port, baud_rate, timeout=2)        payload = (data + '\n').encode(encoding) if newline else data.encode(encoding)        ser.write(payload)        ser.flush()        ser.close()        return f"OK: Sent {len(payload)} bytes to {port} at {baud_rate} baud"    except serial.SerialException as e:        return f"ERROR: {e}"def receive_data(port, baud_rate=9600, timeout=2, max_bytes=1024, encoding="utf-8"):    """Receive data from a serial port."""    if not check_pyserial():        return "ERROR: pyserial not available"    import serial    try:        ser = serial.Serial(port, baud_rate, timeout=timeout)        data = ser.read(max_bytes)        ser.close()        if data:            try:                text = data.decode(encoding)            except UnicodeDecodeError:                text = data.hex()            return json.dumps({                "bytes_received"len(data),                "data": text,                "hex": data.hex()[:200]            }, ensure_ascii=False)        else:            return '{"info":"No data received within timeout"}'    except serial.SerialException as e:        return f"ERROR: {e}"def send_and_receive(port, data, baud_rate=9600, timeout=2, encoding="utf-8"):    """Send data and wait for response."""    if not check_pyserial():        return "ERROR: pyserial not available"    import serial    try:        ser = serial.Serial(port, baud_rate, timeout=timeout)        ser.write((data + '\n').encode(encoding))        ser.flush()        time.sleep(0.1)        response = ser.read(ser.in_waiting or 1024)        ser.close()        try:            text = response.decode(encoding)        except UnicodeDecodeError:            text = response.hex()        return json.dumps({            "sent": data,            "received": text,            "bytes"len(response)        }, ensure_ascii=False)    except serial.SerialException as e:        return f"ERROR: {e}"def monitor(port, baud_rate=9600, duration=10, encoding="utf-8"):    """Monitor serial port output for a duration (outputs in real-time)."""    if not check_pyserial():        return "ERROR: pyserial not available"    import serial    try:        ser = serial.Serial(port, baud_rate, timeout=0.1)        print(f"Monitoring {port} at {baud_rate} baud for {duration}s...")        print("--- Press Ctrl+C to stop ---")        start = time.time()        buffer = b""        while time.time() - start < duration:            if ser.in_waiting:                chunk = ser.read(ser.in_waiting)                buffer += chunk                try:                    print(chunk.decode(encoding), end="", flush=True)                except UnicodeDecodeError:                    print(chunk.hex(), flush=True)            time.sleep(0.05)        ser.close()        print(f"\n--- Monitor ended. Total bytes: {len(buffer)} ---")        return ""    except KeyboardInterrupt:        ser.close()        print("\n--- Monitor stopped by user ---")        return ""    except serial.SerialException as e:        return f"ERROR: {e}"def main():    import argparse    parser = argparse.ArgumentParser(description="Serial Communication")    sub = parser.add_subparsers(dest="action")    p_list = sub.add_parser("list"help="List serial ports")    p_detect = sub.add_parser("detect"help="Detect baud rate")    p_detect.add_argument("--port"type=str, required=True)    p_send = sub.add_parser("send"help="Send data")    p_send.add_argument("--port"type=str, required=True)    p_send.add_argument("--data"type=str, required=True)    p_send.add_argument("--baud"type=int, default=9600)    p_send.add_argument("--no-newline", action="store_true")    p_recv = sub.add_parser("receive"help="Receive data")    p_recv.add_argument("--port"type=str, required=True)    p_recv.add_argument("--baud"type=int, default=9600)    p_recv.add_argument("--timeout"type=float, default=2)    p_chat = sub.add_parser("chat"help="Send and receive")    p_chat.add_argument("--port"type=str, required=True)    p_chat.add_argument("--data"type=str, required=True)    p_chat.add_argument("--baud"type=int, default=9600)    p_mon = sub.add_parser("monitor"help="Monitor port")    p_mon.add_argument("--port"type=str, required=True)    p_mon.add_argument("--baud"type=int, default=9600)    p_mon.add_argument("--duration"type=int, default=10)    args = parser.parse_args()    if args.action == "list":        print(list_ports())    elif args.action == "detect":        print(detect_baud_rate(args.port))    elif args.action == "send":        print(send_data(args.port, args.data, args.baud, newline=not args.no_newline))    elif args.action == "receive":        print(receive_data(args.port, args.baud, args.timeout))    elif args.action == "chat":        print(send_and_receive(args.port, args.data, args.baud))    elif args.action == "monitor":        monitor(args.port, args.baud, args.duration)    else:        parser.print_help()if __name__ == "__main__":    main()

8″C:\Users\username\.workbuddy\skills\system-controller\scripts\iot_controller.py”

#!/usr/bin/env python3"""IoT Controller - Control smart home devices via APIs.Supported platforms:  - Home Assistant (REST API)  - Mijia / XiaoMi (HTTP API, requires token)  - Generic HTTP/REST endpointsRequirements: requests (pip install requests)Usage examples:  python iot_controller.py homeassistant --url http://192.168.1.100:8123 --token YOUR_TOKEN --action list_entities  python iot_controller.py homeassistant --url http://192.168.1.100:8123 --token YOUR_TOKEN --action call_service --domain light --service turn_on --entity_id light.living_room  python iot_controller.py http --url http://192.168.1.50/api --action get --path /status  python iot_controller.py http --url http://192.168.1.50/api --action post --path /command --body '{"command":"on"}'"""import sysimport jsonimport subprocessimport osif sys.stdout.encoding != 'utf-8':    sys.stdout.reconfigure(encoding='utf-8', errors='replace')if sys.stderr.encoding != 'utf-8':    sys.stderr.reconfigure(encoding='utf-8', errors='replace')def check_requests():    """Ensure requests library is available."""    try:        import requests        return requests    except ImportError:        print("Installing requests...")        subprocess.check_call(            [sys.executable, "-m""pip""install""requests""-q"],            stdout=subprocess.DEVNULL        )        import requests        return requests# ========== Home Assistant ==========def ha_list_entities(base_url, token):    """List all entities from Home Assistant."""    requests = check_requests()    url = f"{base_url.rstrip('/')}/api/states"    headers = {"Authorization"f"Bearer {token}""Content-Type""application/json"}    try:        resp = requests.get(url, headers=headers, timeout=10)        if resp.status_code == 200:            entities = []            for entity in resp.json():                entities.append({                    "entity_id": entity["entity_id"],                    "state": entity["state"],                    "friendly_name": entity["attributes"].get("friendly_name"""),                    "domain": entity["entity_id"].split(".")[0]                })            return json.dumps(entities, indent=2, ensure_ascii=False)        else:            return f"ERROR: HTTP {resp.status_code} - {resp.text}"    except Exception as e:        return f"ERROR: {e}"def ha_get_state(base_url, token, entity_id):    """Get state of a specific entity."""    requests = check_requests()    url = f"{base_url.rstrip('/')}/api/states/{entity_id}"    headers = {"Authorization"f"Bearer {token}"}    try:        resp = requests.get(url, headers=headers, timeout=10)        if resp.status_code == 200:            return json.dumps(resp.json(), indent=2, ensure_ascii=False)        else:            return f"ERROR: HTTP {resp.status_code}"    except Exception as e:        return f"ERROR: {e}"def ha_call_service(base_url, token, domain, service, entity_id, service_data=None):    """Call a Home Assistant service."""    requests = check_requests()    url = f"{base_url.rstrip('/')}/api/services/{domain}/{service}"    headers = {"Authorization"f"Bearer {token}""Content-Type""application/json"}    payload = {"entity_id": entity_id}    if service_data:        if isinstance(service_data, str):            try:                payload.update(json.loads(service_data))            except json.JSONDecodeError:                return "ERROR: Invalid service_data JSON"        else:            payload.update(service_data)    try:        resp = requests.post(url, headers=headers, json=payload, timeout=10)        if resp.status_code == 200:            return f"OK: Called {domain}.{service} on {entity_id}"        else:            return f"ERROR: HTTP {resp.status_code} - {resp.text}"    except Exception as e:        return f"ERROR: {e}"def ha_turn_on(base_url, token, entity_id, params=None):    """Turn on an entity."""    domain = entity_id.split(".")[0]    return ha_call_service(base_url, token, domain, "turn_on", entity_id, params)def ha_turn_off(base_url, token, entity_id):    """Turn off an entity."""    domain = entity_id.split(".")[0]    return ha_call_service(base_url, token, domain, "turn_off", entity_id)def ha_toggle(base_url, token, entity_id):    """Toggle an entity."""    domain = entity_id.split(".")[0]    return ha_call_service(base_url, token, domain, "toggle", entity_id)# ========== Generic HTTP ==========def http_get(url, path="", headers=None):    """Send HTTP GET request."""    requests = check_requests()    full_url = f"{url.rstrip('/')}/{path.lstrip('/')}" if path else url    hdrs = {}    if headers:        for h in headers:            k, v = h.split(":"1)            hdrs[k.strip()] = v.strip()    try:        resp = requests.get(full_url, headers=hdrs, timeout=10)        try:            body = resp.json()            return json.dumps({"status": resp.status_code, "data": body}, indent=2, ensure_ascii=False)        except Exception:            return f"Status: {resp.status_code}\n{resp.text[:2000]}"    except Exception as e:        return f"ERROR: {e}"def http_post(url, path="", body=None, headers=None):    """Send HTTP POST request."""    requests = check_requests()    full_url = f"{url.rstrip('/')}/{path.lstrip('/')}" if path else url    hdrs = {"Content-Type""application/json"}    if headers:        for h in headers:            k, v = h.split(":"1)            hdrs[k.strip()] = v.strip()    payload = None    if body:        try:            payload = json.loads(body) if isinstance(body, strelse body        except json.JSONDecodeError:            payload = body    try:        resp = requests.post(full_url, headers=hdrs, json=payload, timeout=10)        try:            rbody = resp.json()            return json.dumps({"status": resp.status_code, "data": rbody}, indent=2, ensure_ascii=False)        except Exception:            return f"Status: {resp.status_code}\n{resp.text[:2000]}"    except Exception as e:        return f"ERROR: {e}"def http_put(url, path="", body=None, headers=None):    """Send HTTP PUT request."""    requests = check_requests()    full_url = f"{url.rstrip('/')}/{path.lstrip('/')}" if path else url    hdrs = {"Content-Type""application/json"}    if headers:        for h in headers:            k, v = h.split(":"1)            hdrs[k.strip()] = v.strip()    payload = None    if body:        try:            payload = json.loads(body) if isinstance(body, strelse body        except json.JSONDecodeError:            payload = body    try:        resp = requests.put(full_url, headers=hdrs, json=payload, timeout=10)        try:            rbody = resp.json()            return json.dumps({"status": resp.status_code, "data": rbody}, indent=2, ensure_ascii=False)        except Exception:            return f"Status: {resp.status_code}\n{resp.text[:2000]}"    except Exception as e:        return f"ERROR: {e}"# ========== Mijia / XiaoMi ==========def mijia_discover():    """Discover Mijia devices on local network (basic SSDP scan)."""    print("INFO: For Mijia device control, use the miio library:")    print("  pip install miio")    print("  python -m miio discover")    return "INFO: Run the above commands to discover Mijia devices"# ========== Main ==========def main():    import argparse    parser = argparse.ArgumentParser(description="IoT Controller")    sub = parser.add_subparsers(dest="platform")    # Home Assistant    p_ha = sub.add_parser("homeassistant"help="Home Assistant control")    ha_sub = p_ha.add_subparsers(dest="action")    ha_sub.add_parser("list"help="List all entities")    ha_state = ha_sub.add_parser("state"help="Get entity state")    ha_state.add_argument("--entity-id"type=str, required=True)    ha_call = ha_sub.add_parser("call"help="Call service")    ha_call.add_argument("--domain"type=str, required=True)    ha_call.add_argument("--service"type=str, required=True)    ha_call.add_argument("--entity-id"type=str, required=True)    ha_call.add_argument("--data"type=strhelp="JSON service data")    ha_on = ha_sub.add_parser("on"help="Turn on entity")    ha_on.add_argument("--entity-id"type=str, required=True)    ha_on.add_argument("--data"type=strhelp="JSON params (e.g. brightness)")    ha_off = ha_sub.add_parser("off"help="Turn off entity")    ha_off.add_argument("--entity-id"type=str, required=True)    ha_tog = ha_sub.add_parser("toggle"help="Toggle entity")    ha_tog.add_argument("--entity-id"type=str, required=True)    p_ha.add_argument("--url"type=str, required=Truehelp="Home Assistant base URL")    p_ha.add_argument("--token"type=str, required=Truehelp="Long-lived access token")    # Generic HTTP    p_http = sub.add_parser("http"help="Generic HTTP/REST control")    http_sub = p_http.add_subparsers(dest="action")    http_get_p = http_sub.add_parser("get"help="HTTP GET")    http_get_p.add_argument("--path"type=str, default="")    http_post_p = http_sub.add_parser("post"help="HTTP POST")    http_post_p.add_argument("--path"type=str, default="")    http_post_p.add_argument("--body"type=str, default=None)    http_put_p = http_sub.add_parser("put"help="HTTP PUT")    http_put_p.add_argument("--path"type=str, default="")    http_put_p.add_argument("--body"type=str, default=None)    p_http.add_argument("--url"type=str, required=True)    p_http.add_argument("--header"type=str, action="append"help="Header in 'Key: Value' format")    # Mijia    p_mi = sub.add_parser("mijia"help="Mijia/XiaoMi control")    mi_sub = p_mi.add_subparsers(dest="action")    mi_sub.add_parser("discover"help="Discover devices")    args = parser.parse_args()    if args.platform == "homeassistant":        url = args.url        token = args.token        if args.action == "list":            print(ha_list_entities(url, token))        elif args.action == "state":            print(ha_get_state(url, token, args.entity_id))        elif args.action == "call":            print(ha_call_service(url, token, args.domain, args.service, args.entity_id, args.data))        elif args.action == "on":            print(ha_turn_on(url, token, args.entity_id, args.data))        elif args.action == "off":            print(ha_turn_off(url, token, args.entity_id))        elif args.action == "toggle":            print(ha_toggle(url, token, args.entity_id))        else:            p_ha.print_help()    elif args.platform == "http":        if args.action == "get":            print(http_get(args.url, args.path, args.header))        elif args.action == "post":            print(http_post(args.url, args.path, args.body, args.header))        elif args.action == "put":            print(http_put(args.url, args.path, args.body, args.header))        else:            p_http.print_help()    elif args.platform == "mijia":        if args.action == "discover":            print(mijia_discover())        else:            p_mi.print_help()    else:        parser.print_help()if __name__ == "__main__":    main()