Skip to content

Repository files navigation

MiService

中文 | English

PyPILicense

XiaoMi Cloud Service for mi.com — 小米云服务 Python 库与命令行工具。

支持小米账号登录(含 OTP 两步验证)、MiIO/MIoT 设备控制、MiNA 小爱音箱 TTS 播报等功能。

功能

  • 小米账号登录与服务令牌管理(支持 SMS/Email OTP 两步验证)
  • MiIO 协议设备控制(属性读取/设置、动作调用)
  • MIoT Spec 接口文档查询(miot-spec.com,支持 text/python 格式化输出(不指定时返回原始 dict))
  • MiNA 小爱音箱控制:TTS 语音播报、音量、播放控制、状态查询、AI 应答获取
  • 局域网本地直连设备(MiIOLocalService),无需云端账号
  • 命令行工具 miservice,一行命令操作设备;亦支持 python -m miservice
  • 零硬依赖:aiohttp 未安装时自动回退到内置 biohttppycryptodome 未安装时 AES 自动回退到内置纯 Python 实现

安装

pip3 install miservice
# 可选:安装 aiohttp 以获得更好的异步 HTTP 性能
pip3 install aiohttp
# 可选:安装 pycryptodome 以获得更快的 AES 实现(用于 MiIOLocalService,不装则自动使用内置纯 Python 实现)
pip3 install pycryptodome

要求 Python 3.8+。

库结构

MiService:XiaoMi Cloud Service
|
|-- MiAccount:账号登录与令牌管理
| |-- 用户名密码登录
| |-- OTP 两步验证(SMS/Email)
| |-- 服务令牌持久化(~/.mi.token)
|
|-- MiIOService:MiIO 服务 (sid=xiaomiio)
| |-- MiIO 协议请求(签名/加密)
| |-- MIoT 属性获取/设置/动作调用
| |-- 设备列表查询
| |-- 家庭/房间层级查询
| |-- MIoT Spec 接口文档查询
| |-- MIoT 数据解密
|
|-- MiNAService:MiAI 服务 (sid=micoapi)
| |-- 小爱音箱设备列表
| |-- TTS 语音播报 / 音量控制
| |-- 播放控制(暂停/停止/继续/URL 播放/单曲循环)
| |-- 播放状态查询
| |-- 最新 AI 应答获取
| |-- 设备型号自动适配(部分机型使用 play_music API)
|
|-- miio_command:MiIO 命令风格接口
|
|-- MiIOLocalService:局域网本地直连设备(无需云端账号)
| |-- 属性获取/设置
| |-- 原始 miIO 方法调用
|
|-- aes:内置 AES-128-CBC 纯 Python 实现(pycryptodome 未安装时的回退,供 miiolocal 使用)
|
|-- local_command:本地设备命令风格接口

环境变量

变量必填说明
MI_USER小米账号用户名
MI_PASS小米账号密码
MI_DID设备 ID 或设备名称(操作设备时必填;MiNA 设备级命令亦用它定位目标音箱)
MI_LOCAL<IP>:<Token>,设置后走局域网本地直连,无需 MI_USER/MI_PASS/MI_DID

命令行用法

MiService 3.0.2 - XiaoMi Cloud Service
Usage: The following variables must be set:
export MI_USER=<Username>
export MI_PASS=<Password>
export MI_DID=<Device ID|Name>
Get Props: miservice <siid[-piid]>[,...]
miservice 1,1-2,1-3,1-4,2-1,2-2,3
Set Props: miservice <siid[-piid]=[#]value>[,...]
miservice 2=60,2-1=#60,2-2=false,2-3="null",3=test
Do Action: miservice <siid[-piid]> <arg1|[]> [...]
miservice 2 []
miservice 5 Hello
miservice 5-4 Hello 1
Call MIoT: miservice <cmd=prop/get|/prop/set|action> <params>
miservice action '{"did":"267090026","siid":5,"aiid":1,"in":["Hello"]}'
Call MiIO: miservice /<uri> <data>
miservice /home/device_list '{"getVirtualModel":false,"getHuamiDevices":1}'
Devs List: miservice list [name_keyword|full] [getVirtualModel=false|true] [getHuamiDevices=0|1]
miservice list Light true 0
miservice list full
Home List: miservice home [name_keyword|full]
miservice home
miservice home full
miservice home 我的家
MIoT Spec: miservice spec [model_keyword|type_urn] [text|python]
miservice spec
miservice spec speaker
miservice spec xiaomi.wifispeaker.lx04
miservice spec xiaomi.wifispeaker.lx04 text
miservice spec urn:miot-spec-v2:device:speaker:0000A015:xiaomi-lx04:1
MIoT Decode: miservice decode <ssecurity> <nonce> <data> [gzip]
MiNA Commands:
miservice mina # List MiNA devices
miservice mina <text> # TTS broadcast to all devices
miservice mina pause # Pause playback
miservice mina stop # Stop playback
miservice mina play # Resume playback
miservice mina play <url> # Play audio from URL
miservice mina loop <url> # Play URL on single-track loop
miservice mina volume <n> # Set volume (0-100)
miservice mina status # Get playback status
miservice mina ask # Get latest AI response
Local Device (no cloud account, direct LAN control):
export MI_LOCAL=<IP>:<Token>
Get Props: miservice <prop>[,...]
miservice power,brightness
Set Props: miservice <prop=value>[,...]
miservice power=on,brightness=80
Call Method: miservice /<method> [params_json]
miservice /miIO.info
miservice /set_power '["on"]'

也可通过 python -m miservice 运行,参数与 miservice 命令完全一致。

调试日志

通过 -v 参数控制日志级别(0-5):

miservice -v5 list # DEBUG 级别
miservice -v2 list # ERROR 级别
miservice -v3 list # WARN 级别
miservice list # 默认 WARNING 级别

示例

1. 设置账号

export MI_USER=<Username>export MI_PASS=<Password>

2. 查询设备列表

miservice list

显示账号下的设备列表,包含名称、型号、DID、Token 等信息。

3. 设置 DID

export MI_DID=<Device ID|Name>

DID 来自设备列表的查询结果,也可以直接使用设备名称。

4. 查询设备接口文档

miservice spec xiaomi.wifispeaker.lx04 text

查询设备的 MIoT 接口能力描述,分为属性获取、属性设置、动作调用三种。不加 text/python 时返回原始 spec dict,不做格式化。

5. 查询音量属性

miservice 2-1

2siid1piid(如果 piid 为 1 则可以省略),可从 spec 接口描述中查得。

6. 设置音量属性

miservice 2=#60

参数类型根据接口描述文档确定:

  • # 是强制文本类型,还可以用单引号 ' 和双引号 " 来强制文本类型(可单个引号,也可以两个)
  • 如果不强制文本类型,默认将自动检测类型;可能的检测结果是 JSON 的 nullfalsetrue、整数、浮点数或文本

7. 动作调用:TTS 播报和执行文本

以下命令执行后小爱音箱会播报"您好":

miservice 5 您好

其中 5siid,此处省略了 aiid(默认为 1)。

以下命令执行后相当于直接对音箱说"小爱同学,查询天气":

miservice 5-4 查询天气 1

其中 1 表示设备语音回应。如果要执行默默关灯(不要音箱回应):

miservice 5-4 关灯 0

如果没有参数,请传入 [] 保留占位。

8. 小爱音箱控制(MiNA)

miservice mina 提供小爱音箱的 TTS 播报与播放控制。不带参数时列出账号下的 MiNA 设备:

miservice mina # 列出 MiNA 设备

向所有小爱音箱发送 TTS 播报:

miservice mina 你好世界

设备级命令(暂停/停止/继续/URL 播放/单曲循环/音量/状态/AI 应答)需要通过 MI_DID 定位目标音箱(MI_DID 对应设备列表中的 miotDID):

export MI_DID=<miotDID>
miservice mina pause # 暂停
miservice mina stop # 停止
miservice mina play # 继续播放
miservice mina play <url># 播放指定 URL(列表循环)
miservice mina loop <url># 单曲循环播放 URL
miservice mina volume 50 # 设置音量 0-100
miservice mina status # 查询播放状态
miservice mina ask # 获取最近一次 AI 应答

注:mina <text> 形式中,若文本恰好为子命令名(如 pause),会被视为子命令;如需播报此类文本,请加引号或前缀文字,如 miservice mina "暂停一下"

9. 局域网本地直连(无需云端账号)

设置 MI_LOCAL=<设备IP>:<设备Token> 后,命令行不再走云端,直接通过 UDP 与设备通信(Token 可从 miservice list 的云端查询结果中获取,或用 APP 抓取):

export MI_LOCAL=192.168.1.10:0123456789abcdef0123456789abcdef
miservice power,brightness # 读取属性
miservice power=on,brightness=80 # 设置属性
miservice /miIO.info # 调用原始 miIO 方法

作为库使用

importasynciofrommiserviceimportMiAccount, MiIOService, MiNAServiceasyncdefmain():
account=MiAccount(None, 'username', 'password', '~/.mi.token')
# 查询设备列表io_service=MiIOService(account)
devices=awaitio_service.device_list()
print(devices)
# 获取设备属性value=awaitio_service.miot_get_prop('device_id', (2, 1))
print(value)
# 设置设备属性code=awaitio_service.miot_set_prop('device_id', (2, 1), 60)
print(code)
# 小爱音箱 TTSna_service=MiNAService(account)
devices=awaitna_service.device_list()
ifdevices:
device_id=devices[0]['deviceID']
awaitna_service.text_to_speech(device_id, '你好')
# 播放控制awaitna_service.player_set_volume(device_id, 50) # 设置音量awaitna_service.player_pause(device_id) # 暂停awaitna_service.player_play(device_id) # 继续awaitna_service.play_by_url(device_id, 'http://.../music.mp3') # 播放 URL(自动适配机型)awaitna_service.player_set_loop(device_id, 0) # 0=单曲循环, 1=列表循环# 播放状态与 AI 应答status=awaitna_service.player_get_status(device_id)
messages=awaitna_service.get_latest_ask(device_id)
# 局域网本地直连(无需云端账号,仅需设备 IP 和 Token)frommiserviceimportMiIOLocalServicelocal_service=MiIOLocalService('192.168.1.10', '0123456789abcdef0123456789abcdef')
power=awaitlocal_service.get_prop('power')
awaitlocal_service.set_prop('power', 'on')
asyncio.run(main())

About

XiaoMi Cloud Service for mi.com

Resources

Contributing

Stars

835 stars

Watchers

7 watching

Forks

Releases

Packages

Used by

Contributors

Languages