run_action
Execute device actions such as starting a sweep or playing music. Specify device ID and action name to trigger commands on Xiaomi smart home.
Instructions
执行设备动作,例如扫地机开始清扫、播放音乐等。
Args:
did: 设备ID
action_name: 动作名称,如 start-sweep、stop-sweeping
value: 动作参数,可选Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| did | Yes | ||
| action_name | Yes | ||
| value | No |
Implementation Reference
- mcp_server/server.py:87-97 (handler)MCP tool handler for 'run_action'. Decorated with @mcp.tool(). Sends a POST request to /devices/{did}/actions/{action_name} with optional value body.
@mcp.tool() async def run_action(did: str, action_name: str, value: dict | None = None) -> dict: """执行设备动作,例如扫地机开始清扫、播放音乐等。 Args: did: 设备ID action_name: 动作名称,如 start-sweep、stop-sweeping value: 动作参数,可选 """ body = {"value": value} if value is not None else {} return await _request("POST", f"/devices/{quote(did)}/actions/{action_name}", json_data=body) - app/services/device_service.py:186-192 (handler)DeviceService.run_action - the core service logic that creates a mijiaDevice, calls device.run_action with timeout, emits an update event, and returns status.
def run_action(user_id: int, did: str, action_name: str, value=None, timeout=MIJIA_CALL_TIMEOUT) -> dict: api = api_pool.get_api(user_id) device = mijiaDevice(api, did=did) kwargs = {"value": value} if value is not None else {} _call_with_timeout(device.run_action, action_name, timeout=timeout, **kwargs) _emit_device_update(user_id, did, "action_executed", {"action_name": action_name, "status": "executed"}) return {"did": did, "action_name": action_name, "status": "executed"} - app/api/devices.py:287-333 (handler)Flask REST API handler for POST /devices/<did>/actions/<action_name>. Validates input via RunActionSchema, calls DeviceService.run_action, and returns success/error responses.
@devices_ns.route("/<did>/actions/<action_name>", methods=["POST"]) @auth_required @limiter.limit("30 per minute") def run_action(did, action_name): """执行设备动作 --- tags: - 设备 security: - cookieAuth: [] - bearerAuth: [] parameters: - in: path name: did type: string required: true - in: path name: action_name type: string required: true - in: body name: body schema: type: object properties: value: description: 动作参数(可选) responses: 200: description: 执行成功 400: description: 参数验证失败 """ try: data = run_action_schema.load(request.get_json(silent=True) or {}) except Exception as e: return error(f"输入验证失败: {e}", 400) try: result = DeviceService.run_action(get_current_user_id(), did, action_name, data.get("value")) return success(result) except DeviceActionError as e: return _mijia_error_response(e) except TimeoutError as e: return error(str(e), 504) except Exception as e: return error(str(e), 500) - app/schemas/device.py:8-9 (schema)RunActionSchema - Marshmallow schema defining input validation for run_action: optional 'value' field of any type.
class RunActionSchema(Schema): value = fields.Raw(load_default=None) - app/services/device_service.py:18-33 (helper)_call_with_timeout helper function used by DeviceService.run_action to execute mijiaDevice calls with a timeout and retry mechanism.
def _call_with_timeout(fn, *args, timeout=MIJIA_CALL_TIMEOUT, retries=MIJIA_CALL_RETRIES, **kwargs): last_exc = None for attempt in range(1 + retries): executor = ThreadPoolExecutor(max_workers=1) future = executor.submit(fn, *args, **kwargs) try: return future.result(timeout=timeout) except FuturesTimeoutError: last_exc = TimeoutError(f"小米云端响应超时 ({timeout}s)") executor.shutdown(wait=False, cancel_futures=True) except Exception: executor.shutdown(wait=False, cancel_futures=True) raise else: executor.shutdown(wait=False, cancel_futures=True) raise last_exc