Skip to content

Commit fc40f58

Browse files
authored
Add viewing of lock devices, also correcting minor typos (#127)
* Add lock devices * adding lock devices
1 parent 6c6096e commit fc40f58

File tree

6 files changed

+105
-7
lines changed

6 files changed

+105
-7
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ async def main() -> None:
6060
devices = myq.lamps
6161
# >>> {"serial_number123": <Device>}
6262

63+
# Return only locks devices:
64+
devices = myq.locks
65+
# >>> {"serial_number123": <Device>}
66+
6367
# Return only gateway devices:
6468
devices = myq.gateways
6569
# >>> {"serial_number123": <Device>}
@@ -79,6 +83,7 @@ asyncio.get_event_loop().run_until_complete(main())
7983
- `devices`: dictionary with all devices (MyQDevice)
8084
- `gateways`: dictionary with all gateways (MyQDevice)
8185
- `lamps`: dictionary with all lamps (MyQLamp)
86+
- `locks`: dictionary with all locks (MyQLock)
8287
- `last_state_update`: datetime (in UTC) last state update was retrieved for all items
8388
- `password`: password used for authentication. Can only be set, not retrieved
8489
- `username`: username for authentication.
@@ -92,6 +97,7 @@ asyncio.get_event_loop().run_until_complete(main())
9297
- `devices`: dictionary with all devices for account (MyQDevice)
9398
- `gateways`: dictionary with all gateways for account (MyQDevice)
9499
- `lamps`: dictionary with all lamps for account (MyQLamp)
100+
- `locks`: dictionary with all locks for account (MyQLock)
95101
- `account_json`: Dictionary containing all account information as retrieved from MyQ
96102
- `last_state_update`: datetime (in UTC) last state update was retrieved for all devices within this account
97103

example.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,20 @@ async def print_lamps(account: MyQAccount):
144144
print(" ------------------------------")
145145

146146

147+
async def print_locks(account: MyQAccount):
148+
"""Print lock information - currently unable to control locks
149+
150+
Args:
151+
account (MyQAccount): Account for which to retrieve locks
152+
"""
153+
print(f" Locks: {len(account.locks)}")
154+
print(" ---------")
155+
if len(account.locks) != 0:
156+
for idx, device in enumerate(account.locks.values()):
157+
print_info(number=idx, device=device)
158+
print(" ------------------------------")
159+
160+
147161
async def print_gateways(account: MyQAccount):
148162
"""Print gateways for account
149163
@@ -193,8 +207,12 @@ async def main() -> None:
193207

194208
await print_lamps(account=account)
195209

210+
await print_locks(account=account)
211+
196212
await print_gateways(account=account)
197213

214+
await print_other(account=account)
215+
198216
except MyQError as err:
199217
_LOGGER.error("There was an error: %s", err)
200218

pymyq/account.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
from .const import (
99
DEVICE_FAMILY_GARAGEDOOR,
1010
DEVICE_FAMILY_GATEWAY,
11-
DEVICE_FAMLY_LAMP,
11+
DEVICE_FAMILY_LAMP,
12+
DEVICE_FAMILY_LOCK,
1213
DEVICES_ENDPOINT,
1314
)
1415
from .device import MyQDevice
1516
from .errors import MyQError
1617
from .garagedoor import MyQGaragedoor
1718
from .lamp import MyQLamp
19+
from .lock import MyQLock
1820

1921
if TYPE_CHECKING:
2022
from .api import API
@@ -82,9 +84,18 @@ def gateways(self) -> Dict[str, MyQDevice]:
8284
if device.device_json["device_family"] == DEVICE_FAMILY_GATEWAY
8385
}
8486

87+
@property
88+
def locks(self) -> Dict[str, MyQDevice]:
89+
"""Return only those devices that are locks."""
90+
return {
91+
device_id: device
92+
for device_id, device in self.devices.items()
93+
if device.device_json["device_family"] == DEVICE_FAMILY_LOCK
94+
}
95+
8596
@property
8697
def other(self) -> Dict[str, MyQDevice]:
87-
"""Return only those devices that are covers."""
98+
"""Return only those devices that are others."""
8899
return {
89100
device_id: device
90101
for device_id, device in self.devices.items()
@@ -137,7 +148,7 @@ async def _get_devices(self) -> None:
137148
device_json=device,
138149
state_update=state_update_timestmp,
139150
)
140-
elif device.get("device_family") == DEVICE_FAMLY_LAMP:
151+
elif device.get("device_family") == DEVICE_FAMILY_LAMP:
141152
_LOGGER.debug(
142153
"Adding new lamp with serial number %s", serial_number
143154
)
@@ -146,6 +157,15 @@ async def _get_devices(self) -> None:
146157
device_json=device,
147158
state_update=state_update_timestmp,
148159
)
160+
elif device.get("device_family") == DEVICE_FAMILY_LOCK:
161+
_LOGGER.debug(
162+
"Adding new lock with serial number %s", serial_number
163+
)
164+
new_device = MyQLock(
165+
account=self,
166+
device_json=device,
167+
state_update=state_update_timestmp,
168+
)
149169
else:
150170
if device.get("device_family") == DEVICE_FAMILY_GATEWAY:
151171
_LOGGER.debug(

pymyq/api.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from .errors import AuthenticationError, InvalidCredentialsError, MyQError, RequestError
2626
from .garagedoor import MyQGaragedoor
2727
from .lamp import MyQLamp
28+
from .lock import MyQLock
2829
from .request import REQUEST_METHODS, MyQRequest
2930

3031
_LOGGER = logging.getLogger(__name__)
@@ -60,7 +61,7 @@ def __init__(
6061
self.last_state_update = None # type: Optional[datetime]
6162

6263
@property
63-
def devices(self) -> Dict[str, Union[MyQDevice, MyQGaragedoor, MyQLamp]]:
64+
def devices(self) -> Dict[str, Union[MyQDevice, MyQGaragedoor, MyQLamp, MyQLock]]:
6465
"""Return all devices."""
6566
devices = {}
6667
for account in self.accounts.values():
@@ -77,15 +78,23 @@ def covers(self) -> Dict[str, MyQGaragedoor]:
7778

7879
@property
7980
def lamps(self) -> Dict[str, MyQLamp]:
80-
"""Return only those devices that are covers."""
81+
"""Return only those devices that are lamps."""
8182
lamps = {}
8283
for account in self.accounts.values():
8384
lamps.update(account.lamps)
8485
return lamps
8586

87+
@property
88+
def locks(self) -> Dict[str, MyQLock]:
89+
"""Return only those devices that are locks."""
90+
locks = {}
91+
for account in self.accounts.values():
92+
locks.update(account.locks)
93+
return locks
94+
8695
@property
8796
def gateways(self) -> Dict[str, MyQDevice]:
88-
"""Return only those devices that are covers."""
97+
"""Return only those devices that are gateways."""
8998
gateways = {}
9099
for account in self.accounts.values():
91100
gateways.update(account.gateways)

pymyq/const.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
DEVICE_FAMILY = "device_family"
2020
DEVICE_FAMILY_GATEWAY = "gateway"
2121
DEVICE_FAMILY_GARAGEDOOR = "garagedoor"
22-
DEVICE_FAMLY_LAMP = "lamp"
22+
DEVICE_FAMILY_LAMP = "lamp"
23+
DEVICE_FAMILY_LOCK = "locks"
2324
DEVICE_STATE = "state"
2425
DEVICE_STATE_ONLINE = "online"
2526

pymyq/lock.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"""Define MyQ devices."""
2+
import asyncio
3+
from datetime import datetime
4+
import logging
5+
from typing import TYPE_CHECKING, Optional, Union
6+
7+
from .device import MyQDevice
8+
9+
if TYPE_CHECKING:
10+
from .account import MyQAccount
11+
12+
_LOGGER = logging.getLogger(__name__)
13+
14+
COMMAND_URI = (
15+
"https://account-devices-lock.myq-cloud.com/api/v5.2/Accounts/{account_id}"
16+
"/locks/{device_serial}/{command}"
17+
)
18+
19+
20+
class MyQLock(MyQDevice):
21+
"""Define a generic device."""
22+
23+
def __init__(
24+
self,
25+
device_json: dict,
26+
account: "MyQAccount",
27+
state_update: datetime,
28+
) -> None:
29+
"""Initialize.
30+
:type account: str
31+
"""
32+
super().__init__(
33+
account=account, device_json=device_json, state_update=state_update
34+
)
35+
36+
@property
37+
def device_state(self) -> Optional[str]:
38+
"""Return the current state of the device."""
39+
return (
40+
self.device_json["state"].get("lock_state")
41+
if self.device_json.get("state") is not None
42+
else None
43+
)
44+

0 commit comments

Comments
 (0)