Skip to content

Commit 0ace49e

Browse files
authored
Merge pull request #11 from bachya/dev-update
Update library to Python 3.5+ and asyncio
2 parents 7b16884 + 346670f commit 0ace49e

13 files changed

+623
-284
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.mypy_cache
2+
Pipfile.lock
3+
pymyq.egg-info

Makefile

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
init:
2+
pip install pip pipenv
3+
pipenv lock
4+
pipenv install --dev
5+
lint:
6+
pipenv run flake8 pymyq
7+
pipenv run pydocstyle pymyq
8+
pipenv run pylint pymyq
9+
publish:
10+
pipenv run python setup.py sdist bdist_wheel
11+
pipenv run twine upload dist/*
12+
rm -rf dist/ build/ .egg simplisafe_python.egg-info/
13+
typing:
14+
pipenv run mypy --ignore-missing-imports pymyq

Pipfile

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[[source]]
2+
url = "https://pypi.python.org/simple"
3+
verify_ssl = true
4+
5+
[dev-packages]
6+
"flake8" = "*"
7+
mypy = "*"
8+
pydocstyle = "*"
9+
pylint = "*"
10+
twine = "*"
11+
12+
[packages]
13+
aiodns = "*"
14+
aiohttp = "*"
15+
async-timeout = "*"

README.md

+66-26
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,86 @@
11
# Introduction
22

3-
This is a python module aiming to interact with the Chamberlain MyQ API.
3+
This is a Python 3.5+ module aiming to interact with the Chamberlain MyQ API.
44

55
Code is licensed under the MIT license.
66

7-
Getting Started
8-
===============
7+
# Getting Started
98

10-
# Usage
9+
## Installation
1110

1211
```python
13-
from pymyq import MyQAPI as pymyq
12+
pip install pymyq
13+
```
14+
15+
## Usage
16+
17+
`pymyq` starts within an [aiohttp](https://aiohttp.readthedocs.io/en/stable/)
18+
`ClientSession`:
19+
20+
```python
21+
import asyncio
22+
23+
from aiohttp import ClientSession
24+
25+
26+
async def main() -> None:
27+
"""Create the aiohttp session and run."""
28+
async with ClientSession() as websession:
29+
# YOUR CODE HERE
30+
1431

15-
myq = pymyq(username, password, brand)
32+
asyncio.get_event_loop().run_until_complete(main())
1633
```
1734

18-
# Methods
35+
To get all MyQ devices associated with an account:
1936

20-
def is_supported_brand(self):
21-
"""Return true/false based on supported brands list and input."""
37+
```python
38+
import asyncio
39+
40+
from aiohttp import ClientSession
41+
42+
import pymyq
43+
44+
45+
async def main() -> None:
46+
"""Create the aiohttp session and run."""
47+
async with ClientSession() as websession:
48+
# Valid Brands: 'chamberlain', 'craftsman', 'liftmaster', 'merlin'
49+
myq = await pymyq.login('<EMAIL>', '<PASSWORD>', '<BRAND>', websession)
2250

23-
def is_login_valid(self):
24-
"""Return true/false based on successful authentication."""
51+
# Return only cover devices:
52+
devices = await myq.get_devices()
53+
54+
# Return *all* devices:
55+
devices = await myq.get_devices(covers_only=False)
56+
57+
58+
asyncio.get_event_loop().run_until_complete(main())
59+
```
2560

26-
def get_devices(self):
27-
"""Return devices from API"""
61+
## Device Properties
2862

29-
def get_garage_doors(self):
30-
"""Parse devices data and extract garage doors. Return garage doors."""
31-
32-
def get_status(self, device_id):
33-
"""Return current door status(open/closed)"""
63+
* `brand`: the brand of the device
64+
* `device_id`: the device's MyQ ID
65+
* `parent_id`: the device's parent device's MyQ ID
66+
* `name`: the name of the device
67+
* `serial`: the serial number of the device
68+
* `state`: the device's current state
69+
* `type`: the type of MyQ device
3470

35-
def close_device(self, device_id):
36-
"""Send request to close the door."""
71+
## Methods
3772

38-
def open_device(self, device_id):
39-
"""Send request to open the door."""
73+
All of the routines on the `MyQDevice` class are coroutines and need to be
74+
`await`ed.
4075

41-
def set_state(self, device_id, state):
42-
"""Send request for request door state change."""
76+
* `close`: close the device
77+
* `open`: open the device
78+
* `update`: get the latest device state (which can then be accessed via the
79+
`state` property)
4380

44-
### Disclaimer
81+
# Disclaimer
4582

46-
The code here is based off of an unsupported API from [Chamberlain](http://www.chamberlain.com/) and is subject to change without notice. The authors claim no responsibility for damages to your garage door or property by use of the code within.
83+
The code here is based off of an unsupported API from
84+
[Chamberlain](http://www.chamberlain.com/) and is subject to change without
85+
notice. The authors claim no responsibility for damages to your garage door or
86+
property by use of the code within.

example.py

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"""Run an example script to quickly test any MyQ account."""
2+
import asyncio
3+
4+
from aiohttp import ClientSession
5+
6+
import pymyq
7+
from pymyq.errors import MyQError
8+
9+
10+
async def main() -> None:
11+
"""Create the aiohttp session and run the example."""
12+
async with ClientSession() as websession:
13+
try:
14+
myq = await pymyq.login(
15+
'<EMAIL>', '<PASSWORD>', '<BRAND>', websession)
16+
17+
devices = await myq.get_devices()
18+
for idx, device in enumerate(devices):
19+
print('Device #{0}: {1}'.format(idx + 1, device.name))
20+
print('--------')
21+
print('Brand: {0}'.format(device.brand))
22+
print('Type: {0}'.format(device.type))
23+
print('Serial: {0}'.format(device.serial))
24+
print('Device ID: {0}'.format(device.device_id))
25+
print('Parent ID: {0}'.format(device.parent_id))
26+
print('Current State: {0}'.format(device.state))
27+
print()
28+
print('Opening the device...')
29+
await device.open()
30+
print('Current State: {0}'.format(device.state))
31+
await asyncio.sleep(15)
32+
print('Closing the device...')
33+
await device.close()
34+
print('Current State: {0}'.format(device.state))
35+
except MyQError as err:
36+
print(err)
37+
38+
39+
asyncio.get_event_loop().run_until_complete(main())

0 commit comments

Comments
 (0)