Skip to main content
Glama

control_device

Control WeMo smart devices by turning them on, off, toggling, or adjusting brightness levels through the WeMo MCP Server for smart home automation.

Instructions

Control a WeMo device (turn on, off, toggle, or set brightness).

Controls a device by sending turn on, turn off, or toggle commands. For dimmer devices, you can also set the brightness level (1-100). The device must have been discovered via scan_network first.

Args:

device_identifier: Device name (e.g., "Office Light") or IP address (e.g., "192.168.1.100")
action: Action to perform - must be one of: "on", "off", "toggle", "brightness"
brightness: Brightness level (1-100) - only used when action is "brightness" or "on" for dimmer devices
ctx: MCP context injected by FastMCP; used to elicit the correct device when identifier is ambiguous

Returns:

Dictionary containing:
- success: Boolean indicating if the action succeeded
- device_name: Name of the device
- action_performed: The action that was executed
- new_state: The state after the action
- brightness: Current brightness level (for dimmers)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
device_identifierYes
actionYes
brightnessNo

Implementation Reference

  • The main implementation of the "control_device" tool.
    async def control_device(
        device_identifier: str,
        action: str,
        brightness: int | None = None,
        ctx: Context | None = None,
    ) -> dict[str, Any]:
        """Control a WeMo device (turn on, off, toggle, or set brightness).
    
        Controls a device by sending turn on, turn off, or toggle commands.
        For dimmer devices, you can also set the brightness level (1-100).
        The device must have been discovered via scan_network first.
    
        Args:
        ----
            device_identifier: Device name (e.g., "Office Light") or IP address (e.g., "192.168.1.100")
            action: Action to perform - must be one of: "on", "off", "toggle", "brightness"
            brightness: Brightness level (1-100) - only used when action is "brightness" or "on" for dimmer devices
            ctx: MCP context injected by FastMCP; used to elicit the correct device when identifier is ambiguous
    
        Returns:
        -------
            Dictionary containing:
            - success: Boolean indicating if the action succeeded
            - device_name: Name of the device
            - action_performed: The action that was executed
            - new_state: The state after the action
            - brightness: Current brightness level (for dimmers)
    
        """
        # Validate inputs
        try:
            params = ControlDeviceParams(
                device_identifier=device_identifier,
                action=action,  # type: ignore[arg-type]
                brightness=brightness,
            )
        except ValidationError as e:
            return {
                "error": ERR_INVALID_PARAMS,
                "validation_errors": [
                    {"field": err["loc"][0], "message": err["msg"], "input": err["input"]}
                    for err in e.errors()
                ],
                "success": False,
            }
    
        try:
            # Find device in memory cache, then reconnect from file cache if needed
            device = _device_cache.get(params.device_identifier)
            if not device:
                device = await _reconnect_device_from_cache(params.device_identifier)
    
            if not device:
                available_names = [
                    k for k in _device_cache if isinstance(k, str) and not k.replace(".", "").isdigit()
                ]
                if ctx is not None and available_names:
                    # Elicit: find closest matches first, fall back to first 5
                    partial_matches = [
                        n for n in available_names if params.device_identifier.lower() in n.lower()
                    ]
                    suggestions = partial_matches or available_names[:5]
                    elicit_result = await ctx.elicit(
                        f"Device '{params.device_identifier}' not found. "
                        f"Did you mean one of these: {', '.join(suggestions)}?",
                        schema=_DeviceChoiceSchema,
                    )
                    if elicit_result.action == "accept" and elicit_result.data:
                        chosen = elicit_result.data.device_name
                        device = _device_cache.get(chosen)
                        if device:
                            params = ControlDeviceParams(
                                device_identifier=chosen,
                                action=params.action,
                                brightness=params.brightness,
                            )
                if not device:
                    return {
                        "error": f"Device '{params.device_identifier}' not found in cache",
                        "suggestion": ERR_RUN_SCAN_FIRST,
                        "available_devices": available_names,
                        "success": False,
                    }
    
            # Check if device is a dimmer
            is_dimmer = hasattr(device, "set_brightness") and hasattr(device, "get_brightness")
    
            # Validate brightness action for non-dimmers
            if params.action == "brightness":
                if not is_dimmer:
                    return {
                        "error": f"Device '{device.name}' is not a dimmer and does not support brightness control",
                        "device_type": type(device).__name__,
                        "success": False,
                    }
                if params.brightness is None:
                    return {
                        "error": "Brightness value is required when action is 'brightness'",
                        "success": False,
                    }
    
            # Perform the action
            await _perform_device_action(device, params.action, params.brightness, is_dimmer)
    
            # Wait for device to respond
            await asyncio.sleep(0.5)
    
            # Build and return result
            result = await _build_control_result(device, params.action, is_dimmer)
    
            logger.info(
                f"Device '{device.name}' {params.action} successful. New state: {result['new_state']}"
                + (f" Brightness: {result.get('brightness')}" if is_dimmer else ""),
            )
            return result
    
        except Exception as e:
            logger.error(f"Error controlling device: {e}", exc_info=True)
            return build_error_response(
                e,
                "Control device",
                context={
                    "device_identifier": device_identifier,
                    "action": action,
                },
            )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/apiarya/wemo-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server