米家智能家居Python控制终极指南:3步实现全屋自动化编程
【免费下载链接】mijia-api米家API,使用Python控制米家设备项目地址: https://gitcode.com/gh_mirrors/mi/mijia-api
米家API(mijiaAPI)是一个功能强大的Python库,专为开发者提供控制小米智能家居设备的完整解决方案。无论您是Python开发者、智能家居爱好者还是自动化系统集成者,这个开源项目都能帮助您快速构建专业的智能家居控制应用,实现真正的全屋自动化编程。
🤔 传统APP限制 vs Python编程控制的优势
传统控制方式的痛点分析
使用小米米家APP进行设备控制虽然方便,但在实际应用中存在诸多限制:
- 批量操作困难- 无法同时对多个设备执行复杂操作
- 自动化逻辑单一- 只能实现简单的定时和场景联动
- 数据收集不足- 缺乏设备使用数据的长期记录和分析
- 集成能力有限- 难以与其他智能系统无缝对接
- 自定义程度低- 无法根据特定需求定制控制逻辑
Python编程控制的解决方案
米家API通过Python编程接口,完美解决了上述痛点:
# 示例:批量控制多个设备 from mijiaAPI import mijiaAPI api = mijiaAPI() api.login() # 同时控制客厅所有灯光设备 living_room_lights = ["客厅主灯", "电视背景灯", "落地灯"] for light_name in living_room_lights: device = mijiaDevice(api, dev_name=light_name) device.on = True # 一键开启所有灯光 device.brightness = 70 # 统一设置亮度🚀 核心功能模块化展示
认证与连接模块
米家API认证流程示意图 - 简洁的二维码扫描认证系统
认证是使用米家API的第一步,系统提供了多种灵活的认证方式:
# 标准认证流程 api = mijiaAPI() # 自动使用默认认证文件路径 api.login() # 扫码登录,认证数据自动保存 # 自定义认证文件路径 import os from pathlib import Path # 项目内认证存储 project_auth = Path(__file__).parent / ".mijia_auth" / "config.json" api = mijiaAPI(str(project_auth)) # 环境变量配置 env_auth = os.getenv('MIJIA_AUTH_PATH', '~/.config/mijia-api/auth.json') api = mijiaAPI(env_auth)设备发现与管理模块
米家API提供了完整的设备发现和管理功能:
# 获取家庭和设备信息 homes = api.get_homes_list() print(f"发现 {len(homes)} 个家庭") # 获取所有设备(排除共享设备) all_devices = api.get_devices_list() for device in all_devices: print(f"📱 设备名称: {device['name']}") print(f" 型号: {device['model']}") print(f" 设备ID: {device['did']}") # 获取特定家庭设备 if homes: home_id = homes[0]['id'] home_devices = api.get_devices_list(home_id=home_id) # 获取共享设备 shared_devices = api.get_shared_devices_list()设备控制模块
设备控制是米家API的核心功能,支持属性式操作:
# 初始化设备对象 lamp = mijiaDevice(api, dev_name='智能台灯') # 属性式操作 - 直观易用 lamp.on = True # 开启设备 lamp.brightness = 75 # 设置亮度75% lamp.color_temperature = 4500 # 设置4500K色温 # 状态查询 current_status = { 'power': lamp.on, 'brightness': lamp.brightness, 'color_temp': lamp.color_temperature } print(f"设备状态: {current_status}")💡 实际应用场景深度解析
家庭自动化场景实现
基于时间和环境条件的自动化控制:
import time from datetime import datetime class HomeAutomation: def __init__(self, api): self.api = api self.api.login() def morning_routine(self): """早晨自动化场景""" # 6:30 AM - 缓慢调亮卧室灯光 bedroom_light = mijiaDevice(self.api, dev_name='卧室主灯') for brightness in range(10, 70, 5): bedroom_light.brightness = brightness time.sleep(0.5) # 打开窗帘和空调 curtain = mijiaDevice(self.api, dev_name='电动窗帘') curtain.set('open', True) air_conditioner = mijiaDevice(self.api, dev_name='空调') air_conditioner.set('power', True) air_conditioner.set('temperature', 24) def evening_routine(self): """晚上自动化场景""" # 10:00 PM - 关闭所有非必要设备 devices = self.api.get_devices_list() for device_info in devices: device = mijiaDevice(self.api, did=device_info['did']) if device_info['name'] not in ['路由器', '安防摄像头']: device.on = False # 开启夜灯模式 night_light = mijiaDevice(self.api, dev_name='夜灯') night_light.on = True night_light.brightness = 20能耗监控与优化系统
class EnergyMonitor: def __init__(self, api): self.api = api def get_monthly_consumption(self, device_did, months=6): """获取设备月度能耗数据""" end_time = int(time.time()) start_time = int(time.time() - months*30*24*3600) consumption_data = self.api.get_statistics({ "did": device_did, "key": "7.1", # 能耗属性 "data_type": "stat_month_v3", "limit": months, "time_start": start_time, "time_end": end_time, }) total = sum(item['value'] for item in consumption_data) average = total / len(consumption_data) if consumption_data else 0 return { 'total_kwh': total, 'average_kwh': average, 'data_points': consumption_data } def optimize_energy_usage(self): """智能能耗优化""" devices = self.api.get_devices_list() for device_info in devices: # 分析高能耗设备 monthly_data = self.get_monthly_consumption(device_info['did']) if monthly_data['average_kwh'] > 50: # 高能耗阈值 print(f"⚠️ 高能耗设备: {device_info['name']}") print(f" 月均能耗: {monthly_data['average_kwh']:.2f} kWh") # 建议优化措施 self.suggest_optimizations(device_info['name'])安防监控与报警系统
class SecuritySystem: def __init__(self, api): self.api = api self.alert_devices = [] def setup_security_mode(self): """设置安防模式""" # 获取所有传感器设备 sensors = self.get_sensors() for sensor in sensors: if sensor['type'] == 'motion': self.setup_motion_alerts(sensor) elif sensor['type'] == 'door_window': self.setup_door_alerts(sensor) def get_sensors(self): """获取所有传感器设备""" devices = self.api.get_devices_list() sensors = [] for device in devices: if any(keyword in device['model'].lower() for keyword in ['sensor', 'detector']): sensors.append({ 'name': device['name'], 'did': device['did'], 'type': self.detect_sensor_type(device['model']) }) return sensors def send_alert(self, sensor_name, alert_type): """发送安防警报""" # 通过小爱音箱播放警报 wifispeaker = mijiaDevice(self.api, dev_name='客厅小爱') alert_message = f"注意!{sensor_name}检测到{alert_type}异常" wifispeaker.run_action('play_text', {'text': alert_message}) # 闪烁灯光提醒 self.flash_lights()⚙️ 性能调优与扩展指南
批量操作性能优化
对于需要控制多个设备的场景,批量操作能显著提升性能:
class BatchController: def __init__(self, api, max_workers=10): self.api = api self.max_workers = max_workers def batch_get_properties(self, device_list, property_name): """批量获取设备属性""" properties = [] for device_info in device_list: properties.append({ "did": device_info['did'], "siid": 2, # 服务ID "piid": 2 # 属性ID }) return self.api.get_devices_prop(properties) def batch_set_properties(self, device_list, property_name, value): """批量设置设备属性""" operations = [] for device_info in device_list: operations.append({ "did": device_info['did'], "siid": 2, "piid": 2, "value": value }) return self.api.set_devices_prop(operations)错误处理与重试机制
import time from mijiaAPI import ( DeviceNotFoundError, DeviceGetError, DeviceSetError, APIError ) class RobustDeviceController: def __init__(self, api, max_retries=3, retry_delay=1): self.api = api self.max_retries = max_retries self.retry_delay = retry_delay def safe_device_operation(self, operation_func, *args, **kwargs): """安全的设备操作包装器""" for attempt in range(self.max_retries): try: return operation_func(*args, **kwargs) except (DeviceGetError, DeviceSetError, APIError) as e: if attempt == self.max_retries - 1: raise print(f"操作失败,{self.retry_delay}秒后重试...") time.sleep(self.retry_delay) def get_device_with_retry(self, dev_name): """带重试的设备获取""" return self.safe_device_operation( mijiaDevice, self.api, dev_name=dev_name )自定义设备扩展
from mijiaAPI import mijiaDevice class CustomSmartLamp(mijiaDevice): """自定义智能台灯类""" def __init__(self, api, dev_name=None, did=None, sleep_time=0.5): super().__init__(api, dev_name, did, sleep_time) def sunrise_mode(self, duration=300): """日出模式:缓慢调亮灯光""" steps = duration // 5 # 每5秒调整一次 for i in range(steps): brightness = int((i / steps) * 100) self.brightness = brightness time.sleep(5) def reading_mode(self): """阅读模式:适合阅读的灯光设置""" self.on = True self.brightness = 80 self.color_temperature = 4000 # 中性白光 def night_mode(self): """夜间模式:柔和的夜灯""" self.on = True self.brightness = 10 self.color_temperature = 2700 # 暖黄光 def get_energy_usage(self): """获取能耗统计""" return self.api.get_statistics({ "did": self.did, "key": "7.1", "data_type": "stat_day_v3", "limit": 7 # 最近7天 })📊 数据收集与分析系统
设备使用数据收集
import json from datetime import datetime, timedelta class DeviceDataCollector: def __init__(self, api, storage_path='device_data.json'): self.api = api self.storage_path = storage_path def collect_daily_data(self): """收集每日设备使用数据""" devices = self.api.get_devices_list() daily_data = { 'date': datetime.now().strftime('%Y-%m-%d'), 'devices': [] } for device_info in devices: device = mijiaDevice(self.api, did=device_info['did']) device_data = { 'name': device_info['name'], 'model': device_info['model'], 'status': device.get('on', False), 'timestamp': datetime.now().isoformat() } # 收集特定设备的额外数据 if 'light' in device_info['model'].lower(): device_data.update({ 'brightness': device.get('brightness', 0), 'color_temp': device.get('color_temperature', 0) }) daily_data['devices'].append(device_data) self.save_data(daily_data) return daily_data def save_data(self, data): """保存数据到文件""" try: with open(self.storage_path, 'r') as f: existing_data = json.load(f) except (FileNotFoundError, json.JSONDecodeError): existing_data = [] existing_data.append(data) with open(self.storage_path, 'w') as f: json.dump(existing_data, f, indent=2) def analyze_usage_patterns(self, days=30): """分析设备使用模式""" with open(self.storage_path, 'r') as f: all_data = json.load(f) # 分析最近N天的数据 recent_data = all_data[-days:] if len(all_data) > days else all_data analysis_results = {} for device_type in ['light', 'sensor', 'switch']: device_data = [ d for d in recent_data if any(device_type in device['model'].lower() for device in d['devices']) ] if device_data: analysis_results[device_type] = { 'total_usage_hours': self.calculate_usage_hours(device_data), 'peak_usage_time': self.find_peak_usage(device_data), 'average_daily_usage': self.calculate_average_daily(device_data) } return analysis_results🔧 命令行工具高效使用
快速设备控制命令
米家API提供了强大的命令行工具,无需编写Python代码即可完成常见操作:
# 列出所有设备 mijiaAPI --list_devices # 查询设备属性 mijiaAPI get --dev_name "卧室台灯" --prop_name "brightness" # 设置设备属性 mijiaAPI set --dev_name "卧室台灯" --prop_name "on" --value True # 批量操作示例 mijiaAPI set --dev_name "客厅灯,餐厅灯,走廊灯" --prop_name "brightness" --value 50 # 语音控制集成 mijiaAPI --run "打开客厅所有灯光" mijiaAPI --run "播放轻音乐" --wifispeaker_name "客厅小爱" mijiaAPI --run "关闭所有灯" --quiet # 静默执行自动化脚本创建
# automation_script.py #!/usr/bin/env python3 """ 自动化脚本示例:根据时间自动调节家居环境 """ import sys import time from datetime import datetime from mijiaAPI import mijiaAPI, mijiaDevice def main(): api = mijiaAPI() # 检查当前时间 current_hour = datetime.now().hour if 6 <= current_hour < 9: # 早晨模式 setup_morning_mode(api) elif 18 <= current_hour < 22: # 晚上模式 setup_evening_mode(api) elif current_hour >= 22 or current_hour < 6: # 夜间模式 setup_night_mode(api) def setup_morning_mode(api): """设置早晨家居模式""" print("🌅 启动早晨模式") # 缓慢开启卧室灯光 bedroom_light = mijiaDevice(api, dev_name='卧室主灯') for brightness in range(10, 80, 5): bedroom_light.brightness = brightness time.sleep(1) # 打开窗帘 curtain = mijiaDevice(api, dev_name='电动窗帘') curtain.set('open', True) # 启动咖啡机(如果有) try: coffee_maker = mijiaDevice(api, dev_name='咖啡机') coffee_maker.on = True except Exception: pass # 设备不存在则跳过 def setup_evening_mode(api): """设置晚上家居模式""" print("🌙 启动晚上模式") # 调暗灯光,开启氛围灯 main_lights = ['客厅主灯', '餐厅灯'] for light_name in main_lights: try: light = mijiaDevice(api, dev_name=light_name) light.brightness = 40 light.color_temperature = 3000 except Exception: continue # 开启电视和音响 try: tv = mijiaDevice(api, dev_name='电视') tv.on = True except Exception: pass def setup_night_mode(api): """设置夜间模式""" print("🌌 启动夜间模式") # 关闭所有主要灯光 all_devices = api.get_devices_list() for device_info in all_devices: if 'light' in device_info['model'].lower(): try: light = mijiaDevice(api, did=device_info['did']) light.on = False except Exception: continue # 开启夜灯 try: night_light = mijiaDevice(api, dev_name='夜灯') night_light.on = True night_light.brightness = 5 except Exception: pass if __name__ == '__main__': main()🛡️ 安全与最佳实践
认证数据安全存储
import json import os from pathlib import Path from cryptography.fernet import Fernet class SecureAuthManager: """安全的认证数据管理器""" def __init__(self, key_path='secret.key', auth_path='auth.enc'): self.key_path = key_path self.auth_path = auth_path self.cipher = self._get_cipher() def _get_cipher(self): """获取加密器""" if not os.path.exists(self.key_path): key = Fernet.generate_key() with open(self.key_path, 'wb') as f: f.write(key) else: with open(self.key_path, 'rb') as f: key = f.read() return Fernet(key) def save_auth_data(self, auth_data): """加密保存认证数据""" encrypted_data = self.cipher.encrypt( json.dumps(auth_data).encode() ) with open(self.auth_path, 'wb') as f: f.write(encrypted_data) def load_auth_data(self): """解密加载认证数据""" if not os.path.exists(self.auth_path): return None with open(self.auth_path, 'rb') as f: encrypted_data = f.read() decrypted_data = self.cipher.decrypt(encrypted_data) return json.loads(decrypted_data.decode())网络请求优化
import requests import time from functools import lru_cache class OptimizedAPIClient: """优化的API客户端""" def __init__(self, base_url, timeout=10, retries=3): self.base_url = base_url self.timeout = timeout self.retries = retries self.session = requests.Session() # 配置会话 self.session.headers.update({ 'User-Agent': 'MijiaAPI/1.0', 'Accept': 'application/json' }) @lru_cache(maxsize=100) def get_device_info_cached(self, device_id): """缓存设备信息请求""" return self._make_request(f'/devices/{device_id}') def _make_request(self, endpoint, method='GET', data=None): """带重试的请求方法""" url = f"{self.base_url}{endpoint}" for attempt in range(self.retries): try: if method == 'GET': response = self.session.get(url, timeout=self.timeout) else: response = self.session.post( url, json=data, timeout=self.timeout ) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: if attempt == self.retries - 1: raise time.sleep(2 ** attempt) # 指数退避 def batch_request(self, requests_list): """批量请求优化""" results = [] for req in requests_list: try: result = self._make_request(**req) results.append(result) except Exception as e: results.append({'error': str(e)}) return results🔮 社区生态与未来展望
项目架构与模块解析
米家API采用模块化设计,便于扩展和维护:
- 核心API模块:mijiaAPI/apis.py - 提供基础API接口
- 设备控制模块:mijiaAPI/devices.py - 设备类封装和高级控制
- 错误处理模块:mijiaAPI/errors.py - 异常类型定义和处理
- 工具函数模块:mijiaAPI/miutils.py - 通用工具函数
- 示例代码:demos/ - 丰富的使用示例
常见问题解决方案
Q: 登录失败或二维码不显示?A: 确保网络连接正常,尝试使用api.login(force=True)强制重新登录
Q: 设备控制无响应?A: 检查设备是否在线,确认设备名称是否正确,查看网络连接状态
Q: 如何提高控制响应速度?A: 减少不必要的API调用,使用批量操作,适当调整设备的sleep_time参数
Q: 如何处理设备离线情况?A: 实现重试机制和错误处理,使用try-except捕获DeviceNotFoundError
扩展开发建议
- 插件系统开发- 创建可插拔的设备控制插件
- Web界面集成- 开发基于Flask或FastAPI的Web控制面板
- 移动端应用- 使用Kivy或BeeWare开发跨平台移动应用
- 语音助手集成- 集成更多语音助手平台
- 数据分析平台- 构建设备使用数据分析平台
社区贡献指南
米家API作为开源项目,欢迎社区贡献:
- 问题反馈- 在项目仓库提交详细的Issue报告
- 代码贡献- 提交Pull Request改进功能或修复bug
- 文档完善- 帮助改进文档和示例代码
- 用例分享- 分享您的智能家居自动化方案
通过Python控制米家设备,您将获得前所未有的灵活性和控制力。无论是简单的定时开关,还是复杂的场景联动,米家API都能为您提供强大的技术支持。开始您的智能家居编程之旅,打造真正个性化的智能生活体验!
【免费下载链接】mijia-api米家API,使用Python控制米家设备项目地址: https://gitcode.com/gh_mirrors/mi/mijia-api
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考