aioshelly
raw JSON → 13.25.0 verified Fri May 01 auth: no python
Asynchronous library to control Shelly smart home devices (WiFi relays, sensors, etc.). Current version: 13.25.0. Requires Python >=3.11. Released regularly; follows Shelly firmware updates.
pip install aioshelly Common errors
error AttributeError: 'NoneType' object has no attribute 'state' ↓
cause Called device.channels[0].state before device.async_setup() was awaited.
fix
Add 'await device.async_setup()' after get_device().
error ModuleNotFoundError: No module named 'aioshelly.device' ↓
cause Installed version <10.0.0 where submodules didn't exist or different package.
fix
Upgrade to latest version: pip install --upgrade aioshelly
error ImportError: cannot import name 'async_get_device' from 'aioshelly' ↓
cause async_get_device was removed in v13; use get_device instead.
fix
Change import to: from aioshelly.factory import get_device
error KeyError: 'ip_address' ↓
cause Options dict missing required key for local device.
fix
Ensure options include 'ip_address' and 'auth' for gen1, or 'auth_key' for gen2+.
Warnings
breaking In v10, top-level imports (from aioshelly import X) were removed. All classes/functions must be imported from their submodules (e.g., aioshelly.device, aioshelly.coap, aioshelly.factory). ↓
fix Replace 'from aioshelly import ShellyDevice' with 'from aioshelly.device import ShellyDevice' or use factory.
deprecated The async_get_device() function was deprecated in v12 and removed in v13. Use get_device() from aioshelly.factory instead. ↓
fix Replace async_get_device() with get_device() from aioshelly.factory.
gotcha Device initialization must be awaited with device.async_setup() after get_device(). Forgetting this leads to AttributeError on device.channels. ↓
fix Always call await device.async_setup() before accessing device properties.
gotcha CoAP devices (gen1) require the local IP and auth credentials. If auth is wrong, device.update() may fail silently. For gen2/3 devices, use Cloud or local HTTP API with auth key. ↓
fix Verify auth credentials and use correct options dict with 'ip_address' and 'auth' for gen1, or 'auth_key' for gen2+.
breaking In v11, the 'channels' attribute changed from a dict to a list. Iterating over channels now yields indexes instead of channel numbers. ↓
fix Access channels by index: device.channels[0].state instead of device.channels[0].state (or use dict-style if still needed, but prefer indexing).
Imports
- ShellyDevice wrong
from aioshelly import ShellyDevicecorrectfrom aioshelly.device import ShellyDevice - ShellyCoAP wrong
from aioshelly import ShellyCoAPcorrectfrom aioshelly.coap import ShellyCoAP - get_device wrong
from aioshelly import get_devicecorrectfrom aioshelly.factory import get_device
Quickstart
import asyncio
import aiohttp
from aioshelly.factory import get_device
async def main():
async with aiohttp.ClientSession() as session:
# For local CoAP (gen1) device:
options = {
'ip_address': '192.168.1.100',
'auth': {'username': 'admin', 'password': ''}
}
device = await get_device(session, 'shellyplug-s-XXXX', options)
await device.async_setup()
print('Device name:', device.name)
print('Is on:', device.channels[0].state)
await device.channels[0].turn_on()
await device.async_update()
asyncio.run(main())