Skip to content

Commit

Permalink
Rework event listener logic
Browse files Browse the repository at this point in the history
  • Loading branch information
tetienne committed Feb 14, 2023
1 parent cc895fc commit b632423
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 17 deletions.
19 changes: 7 additions & 12 deletions pyoverkiz/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ class OverkizClient:
setup: Setup | None
devices: list[Device]
gateways: list[Gateway]
event_listener_id: str | None
session: ClientSession

_refresh_token: str | None = None
Expand Down Expand Up @@ -86,7 +85,6 @@ def __init__(
self.setup: Setup | None = None
self.devices: list[Device] = []
self.gateways: list[Gateway] = []
self.event_listener_id: str | None = None

async def __aenter__(self) -> OverkizClient:
return self
Expand All @@ -101,8 +99,8 @@ async def __aexit__(

async def close(self) -> None:
"""Close the session."""
if self.event_listener_id:
await self.unregister_event_listener()
if self.server.event_listener_id:
await self.server.unregister_event_listener()

await self.server.session.close()

Expand Down Expand Up @@ -286,11 +284,7 @@ async def register_event_listener(self) -> str:
timeout : listening sessions are expected to call the /events/{listenerId}/fetch
API on a regular basis.
"""
response = await self.server.post("events/register")
listener_id = cast(str, response.get("id"))
self.event_listener_id = listener_id

return listener_id
return await self.server.register_event_listener()

@backoff.on_exception(backoff.expo, TooManyConcurrentRequestsException, max_tries=5)
@backoff.on_exception(
Expand All @@ -309,7 +303,9 @@ async def fetch_events(self) -> list[Event]:
Per-session rate-limit : 1 calls per 1 SECONDS period for this particular
operation (polling)
"""
response = await self.server.post(f"events/{self.event_listener_id}/fetch")
response = await self.server.post(
f"events/{self.server.event_listener_id}/fetch"
)
events = [Event(**e) for e in humps.decamelize(response)]

return events
Expand All @@ -319,8 +315,7 @@ async def unregister_event_listener(self) -> None:
Unregister an event listener.
API response status is always 200, even on unknown listener ids.
"""
await self.server.post(f"events/{self.event_listener_id}/unregister")
self.event_listener_id = None
return await self.server.unregister_event_listener()

@backoff.on_exception(
backoff.expo, NotAuthenticatedException, max_tries=2, on_backoff=relogin
Expand Down
29 changes: 27 additions & 2 deletions pyoverkiz/servers/overkiz_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

from abc import ABC, abstractmethod
from json import JSONDecodeError
from typing import Any
from typing import Any, cast

from aiohttp import ClientResponse, ClientSession
from attr import define
from attrs import field

from pyoverkiz.exceptions import (
AccessDeniedToGatewayException,
Expand Down Expand Up @@ -37,8 +38,8 @@ class OverkizServer(ABC):
endpoint: str
manufacturer: str
session: ClientSession

configuration_url: str | None
event_listener_id: str | None = field(default=None, init=False)

@abstractmethod
async def login(self, username: str, password: str) -> bool:
Expand Down Expand Up @@ -167,3 +168,27 @@ async def check_response(response: ClientResponse) -> None:
raise AccessDeniedToGatewayException(message)

raise Exception(message if message else result)

async def register_event_listener(self) -> str:
"""
Register a new setup event listener on the current session and return a new
listener id.
Only one listener may be registered on a given session.
Registering an new listener will invalidate the previous one if any.
Note that registering an event listener drastically reduces the session
timeout : listening sessions are expected to call the /events/{listenerId}/fetch
API on a regular basis.
"""
response = await self.post("events/register")
listener_id = cast(str, response.get("id"))
self.event_listener_id = listener_id

return listener_id

async def unregister_event_listener(self) -> None:
"""
Unregister an event listener.
API response status is always 200, even on unknown listener ids.
"""
await self.post(f"events/{self.event_listener_id}/unregister")
self.event_listener_id = None
5 changes: 2 additions & 3 deletions pyoverkiz/servers/somfy.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,5 @@ async def _refresh_token_if_expired(self) -> None:
):
await self.refresh_token()

# TODO
# if self.event_listener_id:
# await self.register_event_listener()
if self.event_listener_id:
await self.register_event_listener()

0 comments on commit b632423

Please sign in to comment.