{"id":6838,"library":"python-miio","title":"Python library for interfacing with Xiaomi smart appliances","description":"python-miio is a Python library and accompanying command-line tool (`miiocli`) designed to control Xiaomi smart home devices using their miIO and MIoT protocols. It provides an API to interact with a wide range of devices, including robot vacuums, air purifiers, humidifiers, lights, and smart plugs. The library is actively maintained with ongoing development towards a significant 0.6.0 release that introduces major architectural changes.","status":"active","version":"0.5.12","language":"en","source_language":"en","source_url":"https://github.com/rytilahti/python-miio","tags":["xiaomi","miio","miot","smart home","home automation","iot"],"install":[{"cmd":"pip install python-miio","lang":"bash","label":"Stable release"},{"cmd":"pip install --pre python-miio","lang":"bash","label":"Pre-release (0.6.0.dev0+)"},{"cmd":"pip install 'python-miio[micloud]'","lang":"bash","label":"With cloud token fetching support"}],"dependencies":[{"reason":"Command-Line Interface Creation Kit","package":"click","optional":false},{"reason":"Declarative parser for binary data","package":"construct","optional":false},{"reason":"Cryptographic primitives","package":"cryptography","optional":false},{"reason":"Network interface information","package":"netifaces","optional":false},{"reason":"mDNS/DNS-SD (Bonjour) implementation","package":"zeroconf","optional":false},{"reason":"Required for fetching device tokens from Xiaomi cloud via miiocli.","package":"micloud","optional":true}],"imports":[{"note":"Recommended for 0.6.0+ and modern MIoT devices for dynamic device instance creation. Handles model discovery automatically.","symbol":"DeviceFactory","correct":"from miio import DeviceFactory"},{"note":"For 0.5.x, direct import of specific device classes is common. In 0.6.0, integrations moved to `miio.integrations.*` and direct class import for older devices may change.","wrong":"from miio.vacuum import RoborockVacuum","symbol":"RoborockVacuum","correct":"from miio import RoborockVacuum"}],"quickstart":{"code":"import os\nfrom miio import DeviceFactory\nfrom miio.exceptions import DeviceException\n\nDEVICE_IP = os.environ.get('MIIO_DEVICE_IP', '192.168.1.100')\nDEVICE_TOKEN = os.environ.get('MIIO_DEVICE_TOKEN', 'YOUR_DEVICE_TOKEN') # 32-character hex token\n\nif DEVICE_TOKEN == 'YOUR_DEVICE_TOKEN':\n    print(\"WARNING: Replace 'YOUR_DEVICE_TOKEN' with your actual device token or set MIIO_DEVICE_TOKEN environment variable.\")\n    print(\"  You can obtain tokens using 'miiocli cloud' (requires micloud) or legacy methods outlined in the documentation.\")\n    exit(1)\n\nif __name__ == '__main__':\n    try:\n        # For modern MIoT devices or future-proof instantiation (requires python-miio 0.6.0.dev0+ for best results)\n        # For 0.5.x, direct class import like `from miio import RoborockVacuum` is more typical.\n        dev = DeviceFactory.create(DEVICE_IP, DEVICE_TOKEN)\n\n        print(f\"Connected to device: {dev.info.model} ({dev.info.firmware_version})\")\n        status = dev.status()\n        if hasattr(status, 'power'):\n            print(f\"Device power: {status.power}\")\n        elif hasattr(status, 'temperature'):\n            print(f\"Device temperature: {status.temperature}°C\")\n        else:\n            print(f\"Device status: {status.data}\")\n\n    except DeviceException as e:\n        print(f\"Error connecting to device: {e}\")\n        print(\"Ensure the IP address and token are correct and the device is on the same network or subnet.\")\n    except Exception as e:\n        print(f\"An unexpected error occurred: {e}\")\n","lang":"python","description":"This quickstart demonstrates how to connect to a Xiaomi smart appliance using `DeviceFactory`, which is the recommended approach for modern MIoT devices and future versions of the library (0.6.0+). It attempts to retrieve basic device information and status. Device IP and token are expected from environment variables for security and flexibility."},"warnings":[{"fix":"Migrate to `DeviceFactory.create(ip, token)` for device instantiation. If using a specific device class, verify its new import path under `miio.integrations`. Ensure your Python version is 3.8 or higher.","message":"Starting with 0.6.0, major breaking changes include moving device integrations into `miio.integrations` (e.g., `miio.vacuum` becomes `miio.integrations.vacuum.roborock`). Direct imports of device classes are discouraged in favor of `DeviceFactory.create()` for automatic discovery. Python 3.7 support will be dropped.","severity":"breaking","affected_versions":"0.6.0.dev0+"},{"fix":"Use the more generic device class or leverage `DeviceFactory.create()` which handles model-based discovery. For example, instead of `AirHumidifierCA1`, use `AirHumidifier`.","message":"Specific device classes (e.g., `AirFreshVA4`, `AirHumidifierCA1/CB1/CB2`, `Vacuum`) have been deprecated in favor of more generic classes (e.g., `AirFresh`, `AirHumidifier`) and model-based discovery. The `Vacuum` class itself is deprecated and will be reused as a common interface.","severity":"deprecated","affected_versions":"0.5.9, 0.5.11"},{"fix":"Refer to the official documentation's 'Obtaining tokens' section. The `miiocli cloud` command is often the easiest, but if it fails, 'Legacy methods for obtaining tokens' documentation provides alternatives.","message":"Obtaining device tokens can be challenging. While `miiocli cloud` (requires `micloud` package) can fetch tokens from your Xiaomi cloud account, many users still resort to legacy methods like inspecting Mi Home app logs or backups for older versions.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Place the `python-miio` client and the Xiaomi device on the same subnet. Alternatively, if dual-homing is an option, configure your client to be in both subnets. For firewall rules, use `REJECT` instead of `DROP` for outbound connections if you wish to keep the device isolated.","message":"Devices may not respond or exhibit intermittent connection issues if the client and the Xiaomi device are on different subnets. The device might reject requests if the source IP is not in its local subnet.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-15T00:00:00.000Z","next_check":"2026-07-14T00:00:00.000Z","problems":[]}