基于AstrBot+米家实现自然语言控制夜灯设备
准备 我自己有一台接入米家的夜灯,型号是米家床头灯二代,官方已经给出了产品规格与各项控制参数 感谢Do1e开源的的mijiaAPI,这个仓库向调用者提供了傻瓜式的米家电器控制调用接口,只需要调用相应方法、传入对应于设备控制意图的参数,即可通过云端控制米家设备 AstrBot部署于阿里云服务器,已经接入微信的ClawBot。为了插件开发方便,也在本地部署了AstrBot 环境配置 首先在AstrBot的根目录下安装依赖,官方提供了uv依赖管理: cd AstrBot uv sync uv pip install mijiaAPI AstrBot为插件开发者提供了模板仓库,只需使用此模板,然后克隆到本地的AstrBot插件文件夹即可开始开发 cd AstrBot/data/plugins git clone <template-registry> 为了保证插件的正常运行,之后在插件开发调试中,Python环境都应使用外层目录的astrbot,而不应在插件目录新建环境 登录米家 mijiaAPI提供了便捷的登陆方式: import mijiaAPI from mijiaAPI api = mijiaAPI("auth.json") api.login() 执行login()时,程序会在终端打印登录二维码,使用登陆了米家账号的设备扫描后即可完成登录,此后程序不再阻塞,继续执行后面的脚本 不过,如果要将登录逻辑引入AstrBot机器人聊天环境存在一些问题: 登陆时的阻塞会导致机器人无法回复 登陆二维码在终端打印,需要某种方法将登陆手段以机器人回复的形式向用户呈现 在满足以上条件的基础上,还要维持原mijiaAPI中的轮询用户登录逻辑,并在用户扫码登录成功后使机器人回复“登陆成功”提示用户 关于阻塞问题的解决方案,我参考了已有的在AstrBot中调用mijiaAPI的仓库,由674537331开发,核心思路是创建一个独立的进程沙盒,在沙盒中运行login()从而避免主进程被阻塞 在超时时间内每隔0.1秒不断读取进程的输出,如果读取到了二维码URL,则立即向用户回复该URL,回复后不结束登录流程,而是继续循环读取输出,直到超时或读取到登陆成功或失败 在子进程中执行登录的脚本_login_worker.py: #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 登录工作脚本,在子进程中执行登录流程 """ import sys import os import time from pathlib import Path import logging # 配置日志 logging.basicConfig(level=logging.INFO, encoding='utf-8') logging.getLogger("mijiaAPI").setLevel(logging.INFO) # 强制设置 stdout 编码为 UTF-8 if sys.stdout.encoding != 'utf-8': sys.stdout.reconfigure(encoding='utf-8') if sys.stderr.encoding != 'utf-8': sys.stderr.reconfigure(encoding='utf-8') from mijiaAPI import mijiaAPI def main(): if len(sys.argv) != 2: print("Usage: python _login_worker.py <auth_path>", flush=True) sys.exit(1) auth_path = Path(sys.argv[1]) print("[WORKER] 开始初始化认证环境。", flush=True) try: # 确保目录存在 auth_path.parent.mkdir(parents=True, exist_ok=True) api = mijiaAPI(auth_path) print("[WORKER] API 实例已创建,正在请求小米服务器...", flush=True) # 执行登录 result = api.login() print("[WORKER] 登录成功", flush=True) print("[WORKER_SUCCESS] 授权完毕。", flush=True) sys.exit(0) except Exception as e: print(f"[WORKER_ERROR] 登录流程失败: {type(e).__name__}: {e}", flush=True) sys.exit(1) if __name__ == "__main__": main() 主文件: ...