# Python Wyze SDK
A modern Python client for controlling Wyze devices.
[![PyPI version][pypi-image]][pypi-url]
[![Python Version][python-version]][pypi-url]
[![Read the Docs][support-docs]][docs-url]
Whether you're building a custom app, or integrating into a third-party service like Home Assistant, Wyze Developer Kit for Python allows you to leverage the flexibility of Python to get your project up and running as quickly as possible.
The **Python Wyze SDK** allows interaction with:
- `wyze_sdk.client.bulbs`: for controlling Wyze Bulb, Wyze Bulb Color, Wyze Bulb White, and Wyze Light Strip
- `wyze_sdk.client.entry_sensors`: for interacting with Wyze Entry Sensor
- `wyze_sdk.client.cameras`: for interacting with Wyze Cameras
- `wyze_sdk.client.events`: for managing Wyze alarm events
- `wyze_sdk.client.locks`: for interacting with Wyze Lock and Wyze Lock Keypad
- `wyze_sdk.client.motion_sensors`: for interacting with Wyze Motion Sensor
- `wyze_sdk.client.plugs`: for controlling Wyze Plug and Wyze Plug Outdoor
- `wyze_sdk.client.scales`: for controlling Wyze Scale
- `wyze_sdk.client.switches`: for controlling Wyze Switch
- `wyze_sdk.client.thermostats`: for controlling Wyze Thermostat and Wyze Room Sensor
- `wyze_sdk.client.vacuums`: for controlling Wyze Robot Vacuum
**Disclaimer: This repository is for non-destructive use only. WyzeLabs is a wonderful company providing excellent devices at a reasonable price. I ask that you do no harm and be civilized.**
**As this repository is entirely reverse-engineered, it may break at any time. If it does, I will fix it to the best of my ability, but feel free to file a GitHub issue or patch yourself and submit a pull request.**
### Requirements
---
This library requires Python 3.8 and above. If you're unsure how to check what version of Python you're on, you can check it using the following:
> **Note:** You may need to use `python3` before your commands to ensure you use the correct Python path. e.g. `python3 --version`
```bash
python --version
-- or --
python3 --version
```
### Installation
We recommend using [PyPI][pypi] to install the Wyze Developer Kit for Python.
```bash
$ pip install wyze-sdk
```
### Basic Usage of the Web Client
---
Wyze does not provide a Web API that gives you the ability to build applications that interact with Wyze devices. This Development Kit is a reverse-engineered, module-based wrapper that makes interaction with that API possible. We have a few basic examples here with some of the more common uses but you are encouraged to [explore the full range of methods](https://wyze-sdk.readthedocs.io/en/latest/wyze_sdk.api.devices.html) available to you.
#### Authenticating
When performing user "authentication" with an email and password in the Wyze app, the credentials are exchanged for an access token and a refrsh token. These are long strings of the form `lvtx.XXXX`. When using this library, be aware that there are two method for handling authentiation:
##### Obtaining the Token and Storing it for Later Use (Preferred)
It is preferred that users first create an empty `Client` object and use the `login()` method to perform the token exchange.
```python
import os
from wyze_sdk import Client
response = Client().login(email=os.environ['WYZE_EMAIL'], password=os.environ['WYZE_PASSWORD'])
print(f"access token: {response['access_token']}")
print(f"refresh token: {response['refresh_token']}")
```
The returned values can be stored on disk or as environment variables for use in subsequent calls.
```python
import os
from wyze_sdk import Client
client = Client(token=os.environ['WYZE_ACCESS_TOKEN'])
...
```
##### (Deprecated) Automatically Authenticate Every New Client
This method has been deprecated due to issues with authentication rate limiting. While it is still a perfectly usable approach for testing or performing infrequent client actions, it **is not recommended** if you are scripting with this client library.
```python
import os
from wyze_sdk import Client
from wyze_sdk.errors import WyzeApiError
client = Client(email=os.environ['WYZE_EMAIL'], password=os.environ['WYZE_PASSWORD'])
...
```
##### Multi-Factor Authentication (2FA) Support
If your Wyze account has multi-factor authentication (2FA) enabled, you may be prompted for your 2FA code when authenticating via either supported method described above. If you wish to automate the MFA interaction, both the `Client` constructor and the `login()` method accept `totp_key` as input. If the TOTP key is provided, the MFA prompt should not appear.
```python
import os
from wyze_sdk import Client
response = Client().login(
email=os.environ['WYZE_EMAIL'],
password=os.environ['WYZE_PASSWORD'],
totp_key=os.environ['WYZE_TOTP_KEY']
)
OR
client = Client(
email=os.environ['WYZE_EMAIL'],
password=os.environ['WYZE_PASSWORD'],
totp_key=os.environ['WYZE_TOTP_KEY']
)
...
```
**Note: This does not work with SMS or email-based MFA.**
#### Listing devices in your Wyze account
One of the most common use-cases is querying device state from Wyze. If you want to access devices you own, or devices shared to you, this method will do both.
```python
import os
from wyze_sdk import Client
from wyze_sdk.errors import WyzeApiError
client = Client(token=os.environ['WYZE_ACCESS_TOKEN'])
try:
response = client.devices_list()
for device in client.devices_list():
print(f"mac: {device.mac}")
print(f"nickname: {device.nickname}")
print(f"is_online: {device.is_online}")
print(f"product model: {device.product.model}")
except WyzeApiError as e:
# You will get a WyzeApiError if the request failed
print(f"Got an error: {e}")
```
#### Turning off a switch
Some devices - like cameras, bulbs, and plugs - can be switched on and off. This is done with a simple command and even supports delayed actions via timers.
```python
import os
from datetime import timedelta
from wyze_sdk import Client
from wyze_sdk.errors import WyzeApiError
client = Client(token=os.environ['WYZE_ACCESS_TOKEN'])
try:
plug = client.plugs.info(device_mac='ABCDEF1234567890')
print(f"power: {plug.is_on}")
print(f"online: {plug.is_online}")
if plug.is_on:
client.plugs.turn_off(device_mac=plug.mac, device_model=plug.product.model, after=timedelta(hours=3))
else:
client.plugs.turn_on(device_mac=plug.mac, device_model=plug.product.model)
plug = client.plugs.info(device_mac=plug.mac)
assert plug.is_on is True
except WyzeApiError as e:
# You will get a WyzeApiError if the request failed
print(f"Got an error: {e}")
```
#### Setting device properties
Every Wyze device has myriad properties and attributes that can be set in a common, intuitive way.
```python
import os
from wyze_sdk import Client
from wyze_sdk.errors import WyzeApiError
client = Client(token=os.environ['WYZE_ACCESS_TOKEN'])
try:
bulb = client.bulbs.info(device_mac='ABCDEF1234567890')
print(f"power: {bulb.is_on}")
print(f"online: {bulb.is_online}")
print(f"brightness: {bulb.brightness}")
print(f"temp: {bulb.color_temp}")
print(f"color: {bulb.color}")
client.bulbs.set_brightness(device_mac=bulb.mac, device_model=bulb.product.model, brightness=100)
client.bulbs.set_color(device_mac=bulb.mac, device_model=bulb.product.model, color='ff00ff')
client.bulbs.set_color_temp(device_mac=bulb.mac, device_model=bulb.product.model, color_temp=3800)
bulb = client.bulbs.info(device_mac='ABCDEF1234567890')
assert bulb.brightness == 100
assert bulb.color == 'ff00ff'
assert bulb.color_temp == 3800
client.bulbs.set_away_mode(device_mac=bulb.mac, device_model=bulb.product.model, away_mode=True)
except WyzeApiError as e:
# You will get a WyzeApiError if the request failed
print(f"Got an error: {e}")
```
#### Taking actions on devices
Want to unlock your lock, or tell your vacuum to clean certain rooms? Yeah, we got that.
```python
import os
import wyze_sdk
from wyze_sdk import Client
from wyze_sdk.errors import WyzeApiError
client = Client(token=os.environ['WYZE_ACCESS_TOKEN'])
try:
lock = client.locks.info(device_mac='YD.LO1.abcdefg0123456789abcdefg0123456789')
if lock is not None:
print(f"is open: {lock.is_open}")
print(f"is locked: {lock.is_locked}")
if not lock.is_locked:
## let's try to figure out when it was unlocked
for record in client.locks.get_records(device_mac='YD.LO1.abcdefg0123456789abcdefg0123456789', since=datetime.now() - timedelta(hours=12)):
print(f"lock record time: {record.time}")
print(f"lock record type: {record.type}")
print(f"lock record source: {record.details.source}")
## lock up
client.locks.lock(device_mac='YD.LO1.abcdefg0123456789abcdefg0123456789')
except WyzeApiError as e:
# You will get a WyzeApiError if the request failed
print(f"Got an error: {e}")
try:
vacuum = client.vacuums.info(device_mac='JA_RO2_ABCDEF123456')
from wyze_sdk.models.devices import VacuumMode
# if our vacuum is out sweeping, let's find out where he is and tell him to go home
if vacuum.mode == VacuumMode.SWEEPING:
print(f"current position: {vacuum.current_position}")
client.vacuums.dock(device_mac='JA_RO2_ABCDEF123456', device_model=vacuum.product.model)
# idle hands are the devil's playground - go clean the kitchen
elif vacuum.mode == VacuumMode.IDLE:
# want to see what's going on behind the scenes?
wyze_sdk.set_stream_logger('wyze_sdk', level=logging.DEBUG)
client.vacuums.sweep_rooms(device_mac='JA_RO2_ABCDEF123456', room_ids=[room.id for room in vacuum.current_map.rooms if room.name == 'Kitchen'])
except WyzeApiError as e:
# You will get a WyzeApiError if the request failed
print(f"Got an error: {e}")
```
<!-- Markdown links -->
[pypi-image]: https://badge.fury.io/py/wyze-sdk.svg
[pypi-url]: https://pypi.org/project/wyze-sdk/
[python-version]: https://img.shields.io/pypi/pyversions/wyze-sdk.svg
[pypi]: https://pypi.org/
[gh-issues]: https://github.com/shauntarves/wyze-sdk/issues
[support-docs]: https://img.shields.io/badge/support-docs-brightgreen
[docs-url]: https://wyze-sdk.readthedocs.io
Raw data
{
"_id": null,
"home_page": "https://github.com/shauntarves/wyze-sdk",
"name": "wyze-sdk",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8.0",
"maintainer_email": "",
"keywords": "wyze,wyze-labs,wyze-sdk,wyze-api,wyzeapy,wyze-apy,smart home,home automation",
"author": "Shaun Tarves",
"author_email": "shaun@tarves.net",
"download_url": "",
"platform": null,
"description": "# Python Wyze SDK\nA modern Python client for controlling Wyze devices.\n\n[![PyPI version][pypi-image]][pypi-url]\n[![Python Version][python-version]][pypi-url]\n[![Read the Docs][support-docs]][docs-url]\n\n\nWhether you're building a custom app, or integrating into a third-party service like Home Assistant, Wyze Developer Kit for Python allows you to leverage the flexibility of Python to get your project up and running as quickly as possible.\n\nThe **Python Wyze SDK** allows interaction with:\n\n- `wyze_sdk.client.bulbs`: for controlling Wyze Bulb, Wyze Bulb Color, Wyze Bulb White, and Wyze Light Strip\n- `wyze_sdk.client.entry_sensors`: for interacting with Wyze Entry Sensor\n- `wyze_sdk.client.cameras`: for interacting with Wyze Cameras\n- `wyze_sdk.client.events`: for managing Wyze alarm events\n- `wyze_sdk.client.locks`: for interacting with Wyze Lock and Wyze Lock Keypad\n- `wyze_sdk.client.motion_sensors`: for interacting with Wyze Motion Sensor\n- `wyze_sdk.client.plugs`: for controlling Wyze Plug and Wyze Plug Outdoor\n- `wyze_sdk.client.scales`: for controlling Wyze Scale\n- `wyze_sdk.client.switches`: for controlling Wyze Switch\n- `wyze_sdk.client.thermostats`: for controlling Wyze Thermostat and Wyze Room Sensor\n- `wyze_sdk.client.vacuums`: for controlling Wyze Robot Vacuum\n\n**Disclaimer: This repository is for non-destructive use only. WyzeLabs is a wonderful company providing excellent devices at a reasonable price. I ask that you do no harm and be civilized.**\n\n**As this repository is entirely reverse-engineered, it may break at any time. If it does, I will fix it to the best of my ability, but feel free to file a GitHub issue or patch yourself and submit a pull request.**\n\n### Requirements\n\n---\n\nThis library requires Python 3.8 and above. If you're unsure how to check what version of Python you're on, you can check it using the following:\n\n> **Note:** You may need to use `python3` before your commands to ensure you use the correct Python path. e.g. `python3 --version`\n\n```bash\npython --version\n\n-- or --\n\npython3 --version\n```\n\n### Installation\n\nWe recommend using [PyPI][pypi] to install the Wyze Developer Kit for Python.\n\n```bash\n$ pip install wyze-sdk\n```\n\n### Basic Usage of the Web Client\n\n---\n\nWyze does not provide a Web API that gives you the ability to build applications that interact with Wyze devices. This Development Kit is a reverse-engineered, module-based wrapper that makes interaction with that API possible. We have a few basic examples here with some of the more common uses but you are encouraged to [explore the full range of methods](https://wyze-sdk.readthedocs.io/en/latest/wyze_sdk.api.devices.html) available to you.\n\n#### Authenticating\n\nWhen performing user \"authentication\" with an email and password in the Wyze app, the credentials are exchanged for an access token and a refrsh token. These are long strings of the form `lvtx.XXXX`. When using this library, be aware that there are two method for handling authentiation:\n\n##### Obtaining the Token and Storing it for Later Use (Preferred)\n\nIt is preferred that users first create an empty `Client` object and use the `login()` method to perform the token exchange.\n\n```python\nimport os\nfrom wyze_sdk import Client\n\nresponse = Client().login(email=os.environ['WYZE_EMAIL'], password=os.environ['WYZE_PASSWORD'])\nprint(f\"access token: {response['access_token']}\")\nprint(f\"refresh token: {response['refresh_token']}\")\n```\n\nThe returned values can be stored on disk or as environment variables for use in subsequent calls.\n\n```python\nimport os\nfrom wyze_sdk import Client\n\nclient = Client(token=os.environ['WYZE_ACCESS_TOKEN'])\n...\n```\n\n##### (Deprecated) Automatically Authenticate Every New Client\n\nThis method has been deprecated due to issues with authentication rate limiting. While it is still a perfectly usable approach for testing or performing infrequent client actions, it **is not recommended** if you are scripting with this client library.\n\n```python\nimport os\nfrom wyze_sdk import Client\nfrom wyze_sdk.errors import WyzeApiError\n\nclient = Client(email=os.environ['WYZE_EMAIL'], password=os.environ['WYZE_PASSWORD'])\n...\n```\n\n##### Multi-Factor Authentication (2FA) Support\n\nIf your Wyze account has multi-factor authentication (2FA) enabled, you may be prompted for your 2FA code when authenticating via either supported method described above. If you wish to automate the MFA interaction, both the `Client` constructor and the `login()` method accept `totp_key` as input. If the TOTP key is provided, the MFA prompt should not appear.\n\n```python\nimport os\nfrom wyze_sdk import Client\n\nresponse = Client().login(\n email=os.environ['WYZE_EMAIL'],\n password=os.environ['WYZE_PASSWORD'],\n totp_key=os.environ['WYZE_TOTP_KEY']\n)\n\nOR\n\nclient = Client(\n email=os.environ['WYZE_EMAIL'],\n password=os.environ['WYZE_PASSWORD'],\n totp_key=os.environ['WYZE_TOTP_KEY']\n)\n...\n```\n\n**Note: This does not work with SMS or email-based MFA.**\n\n#### Listing devices in your Wyze account\n\nOne of the most common use-cases is querying device state from Wyze. If you want to access devices you own, or devices shared to you, this method will do both.\n\n```python\nimport os\nfrom wyze_sdk import Client\nfrom wyze_sdk.errors import WyzeApiError\n\nclient = Client(token=os.environ['WYZE_ACCESS_TOKEN'])\n\ntry:\n response = client.devices_list()\n for device in client.devices_list():\n print(f\"mac: {device.mac}\")\n print(f\"nickname: {device.nickname}\")\n print(f\"is_online: {device.is_online}\")\n print(f\"product model: {device.product.model}\")\nexcept WyzeApiError as e:\n # You will get a WyzeApiError if the request failed\n print(f\"Got an error: {e}\")\n```\n\n#### Turning off a switch\n\nSome devices - like cameras, bulbs, and plugs - can be switched on and off. This is done with a simple command and even supports delayed actions via timers.\n\n```python\nimport os\nfrom datetime import timedelta\nfrom wyze_sdk import Client\nfrom wyze_sdk.errors import WyzeApiError\n\nclient = Client(token=os.environ['WYZE_ACCESS_TOKEN'])\n\ntry:\n plug = client.plugs.info(device_mac='ABCDEF1234567890')\n print(f\"power: {plug.is_on}\")\n print(f\"online: {plug.is_online}\")\n\n if plug.is_on:\n client.plugs.turn_off(device_mac=plug.mac, device_model=plug.product.model, after=timedelta(hours=3))\n else:\n client.plugs.turn_on(device_mac=plug.mac, device_model=plug.product.model)\n\n plug = client.plugs.info(device_mac=plug.mac)\n assert plug.is_on is True\nexcept WyzeApiError as e:\n # You will get a WyzeApiError if the request failed\n print(f\"Got an error: {e}\")\n```\n\n#### Setting device properties\n\nEvery Wyze device has myriad properties and attributes that can be set in a common, intuitive way.\n\n```python\nimport os\nfrom wyze_sdk import Client\nfrom wyze_sdk.errors import WyzeApiError\n\nclient = Client(token=os.environ['WYZE_ACCESS_TOKEN'])\n\ntry:\n bulb = client.bulbs.info(device_mac='ABCDEF1234567890')\n print(f\"power: {bulb.is_on}\")\n print(f\"online: {bulb.is_online}\")\n print(f\"brightness: {bulb.brightness}\")\n print(f\"temp: {bulb.color_temp}\")\n print(f\"color: {bulb.color}\")\n\n client.bulbs.set_brightness(device_mac=bulb.mac, device_model=bulb.product.model, brightness=100)\n client.bulbs.set_color(device_mac=bulb.mac, device_model=bulb.product.model, color='ff00ff')\n client.bulbs.set_color_temp(device_mac=bulb.mac, device_model=bulb.product.model, color_temp=3800)\n \n bulb = client.bulbs.info(device_mac='ABCDEF1234567890')\n assert bulb.brightness == 100\n assert bulb.color == 'ff00ff'\n assert bulb.color_temp == 3800\n\n client.bulbs.set_away_mode(device_mac=bulb.mac, device_model=bulb.product.model, away_mode=True)\n\nexcept WyzeApiError as e:\n # You will get a WyzeApiError if the request failed\n print(f\"Got an error: {e}\")\n```\n\n#### Taking actions on devices\n\nWant to unlock your lock, or tell your vacuum to clean certain rooms? Yeah, we got that.\n\n```python\nimport os\nimport wyze_sdk\nfrom wyze_sdk import Client\nfrom wyze_sdk.errors import WyzeApiError\n\nclient = Client(token=os.environ['WYZE_ACCESS_TOKEN'])\n\ntry:\n lock = client.locks.info(device_mac='YD.LO1.abcdefg0123456789abcdefg0123456789')\n if lock is not None:\n print(f\"is open: {lock.is_open}\")\n print(f\"is locked: {lock.is_locked}\")\n\n if not lock.is_locked:\n ## let's try to figure out when it was unlocked\n for record in client.locks.get_records(device_mac='YD.LO1.abcdefg0123456789abcdefg0123456789', since=datetime.now() - timedelta(hours=12)):\n print(f\"lock record time: {record.time}\")\n print(f\"lock record type: {record.type}\")\n print(f\"lock record source: {record.details.source}\")\n\n ## lock up\n client.locks.lock(device_mac='YD.LO1.abcdefg0123456789abcdefg0123456789')\n\nexcept WyzeApiError as e:\n # You will get a WyzeApiError if the request failed\n print(f\"Got an error: {e}\")\n\n\ntry:\n vacuum = client.vacuums.info(device_mac='JA_RO2_ABCDEF123456')\n\n from wyze_sdk.models.devices import VacuumMode\n\n # if our vacuum is out sweeping, let's find out where he is and tell him to go home\n if vacuum.mode == VacuumMode.SWEEPING:\n print(f\"current position: {vacuum.current_position}\")\n\n client.vacuums.dock(device_mac='JA_RO2_ABCDEF123456', device_model=vacuum.product.model)\n\n # idle hands are the devil's playground - go clean the kitchen\n elif vacuum.mode == VacuumMode.IDLE:\n # want to see what's going on behind the scenes?\n wyze_sdk.set_stream_logger('wyze_sdk', level=logging.DEBUG)\n\n client.vacuums.sweep_rooms(device_mac='JA_RO2_ABCDEF123456', room_ids=[room.id for room in vacuum.current_map.rooms if room.name == 'Kitchen'])\n\nexcept WyzeApiError as e:\n # You will get a WyzeApiError if the request failed\n print(f\"Got an error: {e}\")\n```\n\n<!-- Markdown links -->\n\n[pypi-image]: https://badge.fury.io/py/wyze-sdk.svg\n[pypi-url]: https://pypi.org/project/wyze-sdk/\n[python-version]: https://img.shields.io/pypi/pyversions/wyze-sdk.svg\n[pypi]: https://pypi.org/\n[gh-issues]: https://github.com/shauntarves/wyze-sdk/issues\n[support-docs]: https://img.shields.io/badge/support-docs-brightgreen\n[docs-url]: https://wyze-sdk.readthedocs.io\n",
"bugtrack_url": null,
"license": "The Unlicense",
"summary": "The Wyze Labs API Platform SDK for Python.",
"version": "1.10.1",
"project_urls": {
"Homepage": "https://github.com/shauntarves/wyze-sdk"
},
"split_keywords": [
"wyze",
"wyze-labs",
"wyze-sdk",
"wyze-api",
"wyzeapy",
"wyze-apy",
"smart home",
"home automation"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "2829b4daf7f68697976781203e26710dc4c73fedb9581499bf016c719e43f0f3",
"md5": "fa3dba9d9bb80939b06be5275d50675e",
"sha256": "a8542454ef0a3ef6ce3f5569e3861f3cd8816859e81b3865a59574a7197073e2"
},
"downloads": -1,
"filename": "wyze_sdk-1.10.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "fa3dba9d9bb80939b06be5275d50675e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8.0",
"size": 97916,
"upload_time": "2023-05-06T21:50:50",
"upload_time_iso_8601": "2023-05-06T21:50:50.271606Z",
"url": "https://files.pythonhosted.org/packages/28/29/b4daf7f68697976781203e26710dc4c73fedb9581499bf016c719e43f0f3/wyze_sdk-1.10.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-05-06 21:50:50",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "shauntarves",
"github_project": "wyze-sdk",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "wyze-sdk"
}