Skip to content

Commit 14e3450

Browse files
authored
Merge pull request #23 from bachya/api-rework
Update library to work with API version 5
2 parents ac8b71d + 0de7b7d commit 14e3450

File tree

7 files changed

+296
-535
lines changed

7 files changed

+296
-535
lines changed

.flake8

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[flake8]
2+
ignore = E203, E266, E501, W503
3+
max-line-length = 80
4+
max-complexity = 18
5+
select = B,C,E,F,W,T4,B9

README.md

+18-19
Original file line numberDiff line numberDiff line change
@@ -45,43 +45,42 @@ import pymyq
4545
async def main() -> None:
4646
"""Create the aiohttp session and run."""
4747
async with ClientSession() as websession:
48-
# Valid Brands: 'chamberlain', 'craftsman', 'liftmaster', 'merlin'
49-
myq = await pymyq.login('<EMAIL>', '<PASSWORD>', '<BRAND>', websession)
48+
myq = await pymyq.login('<EMAIL>', '<PASSWORD>', websession)
5049

5150
# Return only cover devices:
52-
devices = await myq.get_devices()
51+
devices = myq.covers
52+
# >>> {"serial_number123": <Device>}
5353

5454
# Return *all* devices:
55-
devices = await myq.get_devices(covers_only=False)
55+
devices = myq.devices
56+
# >>> {"serial_number123": <Device>, "serial_number456": <Device>}
5657

5758

5859
asyncio.get_event_loop().run_until_complete(main())
5960
```
6061

6162
## Device Properties
6263

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-
* `available`: if device is online
68-
* `serial`: the serial number of the device
69-
* `state`: the device's current state
70-
* `type`: the type of MyQ device
71-
* `open_allowed`: if device can be opened unattended
72-
* `close_allowed`: if device can be closed unattended
64+
`close_allowed`: Return whether the device can be closed unattended.
65+
`device_family`: Return the family in which this device lives.
66+
`device_id`: Return the device ID (serial number).
67+
`device_platform`: Return the device platform.
68+
`device_type`: Return the device type.
69+
`firmware_version`: Return the family in which this device lives.
70+
`name`: Return the device name.
71+
`online`: Return whether the device is online.
72+
`open_allowed`: Return whether the device can be opened unattended.
73+
`parent_device_id`: Return the device ID (serial number) of this device's parent.
74+
`state`: Return the current state of the device.
7375

7476
## Methods
7577

7678
All of the routines on the `MyQDevice` class are coroutines and need to be
77-
`await`ed.
79+
`await`ed – see `example.py` for examples.
7880

7981
* `close`: close the device
8082
* `open`: open the device
81-
* `update`: get the latest device state (which can then be accessed via the
82-
`state` property). Retrieval of state from cloud is will only be done if more then 5 seconds has elapsed since last
83-
request. State for all devices is retrieved through (1) request.
84-
* `close_connection`: close web session connection, will only close the web session if none was provided initially
83+
* `update`: get the latest device info (state, etc.)
8584

8685
# Disclaimer
8786

example.py

+37-83
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,54 @@
1-
"""Run an example script to quickly test any MyQ account."""
1+
"""Run an example script to quickly test."""
22
import asyncio
33
import logging
4-
import json
54

65
from aiohttp import ClientSession
76

8-
import pymyq
9-
from pymyq.device import STATE_CLOSED, STATE_OPEN
10-
from pymyq.errors import MyQError
7+
from pymyq import login
8+
from pymyq.errors import MyQError, RequestError
119

12-
# Provide your email and password account details for MyQ.
13-
MYQ_ACCOUNT_EMAIL = '<EMAIL>'
14-
MYQ_ACCOUNT_PASSWORD = '<PASSWORD>'
10+
_LOGGER = logging.getLogger()
1511

16-
# BRAND can be one of the following:
17-
# liftmaster
18-
# chamberlain
19-
# craftsmaster
20-
# merlin
21-
MYQ_BRAND = '<BRAND>'
22-
LOGLEVEL = 'ERROR'
23-
24-
# Set JSON_DUMP to True to dump all the device information retrieved,
25-
# this can be helpful to determine what else is available.
26-
# Set JSON_DUMP to False to open/close the doors instead. i.e.:
27-
# JSON_DUMP = False
28-
JSON_DUMP = True
12+
EMAIL = "<EMAIL>"
13+
PASSWORD = "<PASSWORD>"
2914

3015

3116
async def main() -> None:
3217
"""Create the aiohttp session and run the example."""
33-
34-
loglevels = dict((logging.getLevelName(level), level)
35-
for level in [10, 20, 30, 40, 50])
36-
37-
logging.basicConfig(
38-
level=loglevels[LOGLEVEL],
39-
format='%(asctime)s:%(levelname)s:\t%(name)s\t%(message)s')
40-
18+
logging.basicConfig(level=logging.INFO)
4119
async with ClientSession() as websession:
4220
try:
43-
myq = await pymyq.login(
44-
MYQ_ACCOUNT_EMAIL, MYQ_ACCOUNT_PASSWORD, MYQ_BRAND, websession)
45-
46-
devices = await myq.get_devices()
47-
for idx, device in enumerate(devices):
48-
print('Device #{0}: {1}'.format(idx + 1, device.name))
49-
print('--------')
50-
print('Brand: {0}'.format(device.brand))
51-
print('Type: {0}'.format(device.type))
52-
print('Serial: {0}'.format(device.serial))
53-
print('Device ID: {0}'.format(device.device_id))
54-
print('Parent ID: {0}'.format(device.parent_id))
55-
print('Online: {0}'.format(device.available))
56-
print('Unattended Open: {0}'.format(device.open_allowed))
57-
print('Unattended Close: {0}'.format(device.close_allowed))
58-
print()
59-
print('Current State: {0}'.format(device.state))
60-
if JSON_DUMP:
61-
print(json.dumps(device._device, indent=4))
62-
else:
63-
if device.state != STATE_OPEN:
64-
print('Opening the device...')
65-
await device.open()
66-
print(' 0 Current State: {0}'.format(device.state))
67-
for waited in range(1, 30):
68-
if device.state == STATE_OPEN:
69-
break
70-
await asyncio.sleep(1)
71-
await device.update()
72-
print(' {} Current State: {}'.format(
73-
waited, device.state))
74-
75-
await asyncio.sleep(10)
76-
await device.update()
77-
print()
78-
print('Current State: {0}'.format(device.state))
79-
80-
if device.state != STATE_CLOSED:
81-
print('Closing the device...')
82-
await device.close()
83-
print(' 0 Current State: {0}'.format(device.state))
84-
for waited in range(1, 30):
85-
if device.state == STATE_CLOSED:
86-
break
87-
await asyncio.sleep(1)
88-
await device.update()
89-
print(' {} Current State: {}'.format(
90-
waited, device.state))
91-
92-
await asyncio.sleep(10)
93-
await device.update()
94-
print()
95-
print('Current State: {0}'.format(device.state))
21+
# Create an API object:
22+
api = await login(EMAIL, PASSWORD, websession)
23+
24+
# Get the account ID:
25+
_LOGGER.info("Account ID: %s", api.account_id)
26+
27+
# Get all devices listed with this account – note that you can use
28+
# api.covers to only examine covers:
29+
for idx, device_id in enumerate(api.devices):
30+
device = api.devices[device_id]
31+
_LOGGER.info("---------")
32+
_LOGGER.info("Device %s: %s", idx + 1, device.name)
33+
_LOGGER.info("Device Online: %s", device.online)
34+
_LOGGER.info("Device ID: %s", device.device_id)
35+
_LOGGER.info("Parent Device ID: %s", device.parent_device_id)
36+
_LOGGER.info("Device Family: %s", device.device_family)
37+
_LOGGER.info("Device Platform: %s", device.device_platform)
38+
_LOGGER.info("Device Type: %s", device.device_type)
39+
_LOGGER.info("Firmware Version: %s", device.firmware_version)
40+
_LOGGER.info("Open Allowed: %s", device.open_allowed)
41+
_LOGGER.info("Close Allowed: %s", device.close_allowed)
42+
_LOGGER.info("Current State: %s", device.state)
43+
44+
try:
45+
await device.open()
46+
await asyncio.sleep(15)
47+
await device.close()
48+
except RequestError as err:
49+
_LOGGER.error(err)
9650
except MyQError as err:
97-
print(err)
51+
_LOGGER.error("There was an error: %s", err)
9852

9953

10054
asyncio.get_event_loop().run_until_complete(main())

pylintrc

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[MESSAGES CONTROL]
2+
# Reasons disabled:
3+
# bad-continuation - Invalid attack on black
4+
# unnecessary-pass - This can hurt readability
5+
disable=
6+
bad-continuation,
7+
unnecessary-pass
8+
9+
[REPORTS]
10+
reports=no
11+
12+
[FORMAT]
13+
expected-line-ending-format=LF
14+

0 commit comments

Comments
 (0)