set_switch_state
Control smart switches and lights by turning them on or off using device index or name.
Instructions
Set a switch or light to On or Off.
Args: state: Must be 'On' or 'Off'. idx: Device index. name: Device name (case-insensitive).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| state | Yes | ||
| idx | No | ||
| name | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/domoticz_mcp/server.py:580-598 (handler)The main handler function for the 'set_switch_state' tool. It accepts state ('On'/'Off'), idx, and name, validates inputs, resolves the device index, and sends the switchlight command to Domoticz.
@mcp.tool() async def set_switch_state(state: str, idx: int | None = None, name: str | None = None) -> str: """Set a switch or light to On or Off. Args: state: Must be 'On' or 'Off'. idx: Device index. name: Device name (case-insensitive). """ if idx is None and name is None: return '{"status": "error", "message": "Must provide either idx or name"}' if state.lower() not in ['on', 'off']: return '{"status": "error", "message": "state must be \'On\' or \'Off\'"}' async with create_client() as client: resolved_idx = await _resolve_device_idx(client, idx, name) if resolved_idx is None: return '{"status": "error", "message": "Device not found"}' response = await _do_request(client, "GET", f"{DOMOTICZ_API_URL}?type=command¶m=switchlight&idx={resolved_idx}&switchcmd={state.capitalize()}") return response.text - src/domoticz_mcp/server.py:580-580 (registration)The tool is registered via the @mcp.tool() decorator on the set_switch_state function. The mcp object is a FastMCP instance ('Domoticz') created at line 70.
@mcp.tool() - src/domoticz_mcp/server.py:582-588 (schema)The input schema is defined in the function signature and docstring: state (str, required, must be 'On' or 'Off'), idx (int, optional), name (str, optional). Validation occurs at lines 589-592.
"""Set a switch or light to On or Off. Args: state: Must be 'On' or 'Off'. idx: Device index. name: Device name (case-insensitive). """ - src/domoticz_mcp/server.py:373-375 (helper)Helper function _resolve_device_idx used by set_switch_state to resolve a device name or idx to a numeric idx via cached API data.
async def _resolve_device_idx(client: "httpx.AsyncClient", idx: Optional[int] = None, name: Optional[str] = None) -> Optional[int]: """Resolve a device to its idx.""" return await _resolve_idx(client, idx, name, _device_cache, f"{DOMOTICZ_API_URL}?type=command¶m=getdevices&filter=all&used=true") - src/domoticz_mcp/server.py:269-295 (helper)HTTP request helper _do_request used by set_switch_state to make API calls with automatic retry on 401 (token refresh).
async def _do_request(client: httpx.AsyncClient, method: str, url: str, **kwargs) -> httpx.Response: """Perform a request with a single retry on 401 Unauthorized to handle expired tokens.""" global _oauth_token_cache try: resp = await client.request(method, url, **kwargs) if resp.status_code == 401: # Token might be expired. Clear cache and retry once. _oauth_token_cache = None # Re-fetch token (this will trigger OAuth flow if needed) new_token = await _fetch_oauth_token(force_refresh=True) if new_token: # Update headers for the retry if "headers" not in kwargs: kwargs["headers"] = {} kwargs["headers"]["Authorization"] = f"Bearer {new_token}" # Retry the request resp = await client.request(method, url, **kwargs) resp.raise_for_status() return resp except httpx.HTTPStatusError as e: if e.response.status_code == 401: raise Exception("Authentication failed. Please check your credentials or re-authenticate.") raise e