Skip to content

Commit 8ab2d05

Browse files
committed
Move request and class to sep. files
1 parent 5f661d4 commit 8ab2d05

2 files changed

Lines changed: 111 additions & 72 deletions

File tree

dingz/__init__.py

Lines changed: 53 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,58 @@
1-
"""A Python Client to interact with Dingz devices."""
1+
"""Base details for the dingz Python bindings."""
22
import asyncio
3-
import logging
3+
import json
4+
import socket
5+
from typing import Any, Mapping, Optional
46

57
import aiohttp
68
import async_timeout
79

8-
from . import exceptions
9-
from .constants import TEMPERATURE, MOTION, LIGHT, PUCK, INFO
10-
11-
_LOGGER = logging.getLogger(__name__)
12-
13-
14-
class Dingz:
15-
"""A class for handling the communication with a Dingz device."""
16-
17-
def __init__(self, device, loop, session):
18-
"""Initialize the connection."""
19-
self._loop = loop
20-
self._session = session
21-
self.token = None
22-
self.device = device
23-
self.data = None
24-
25-
async def get_data(self, endpoint):
26-
"""Retrieve the data from a given endpoint."""
27-
try:
28-
with async_timeout.timeout(5, loop=self._loop):
29-
response = await self._session.get(f"{endpoint}")
30-
31-
_LOGGER.debug("Response from Dingz device: %s", response.status)
32-
self.data = await response.json()
33-
_LOGGER.debug(self.data)
34-
except (asyncio.TimeoutError, aiohttp.ClientError):
35-
_LOGGER.error("Can not load data from Dingz device")
36-
self.data = None
37-
raise exceptions.DingzConnectionError()
38-
39-
@property
40-
def info(self):
41-
"""Get the state of the motion sensor."""
42-
data = await self.get_data(INFO)
43-
return data['motion']
44-
45-
@property
46-
def puck(self):
47-
"""Get the state of the hardware."""
48-
data = await self.get_data(PUCK)
49-
if self.data is not None:
50-
return {'firmware': data['fw']['version'], 'hardware': data['hw']['version']}
51-
52-
@property
53-
def temperature(self):
54-
"""Get the temperature."""
55-
data = await self.get_data(TEMPERATURE)
56-
return round(data['temperature'], 2)
57-
58-
@property
59-
def light(self):
60-
"""Get the brightness."""
61-
data = await self.get_data(LIGHT)
62-
return round(data['intensity'], 2)
63-
64-
@property
65-
def day(self):
66-
"""Get the state if daytime or not."""
67-
data = await self.get_data(LIGHT)
68-
return data['day']
69-
70-
@property
71-
def motion(self):
72-
"""Get the state of the motion sensor."""
73-
data = await self.get_data(MOTION)
74-
return data['motion']
75-
76-
77-
10+
from .constants import TIMEOUT, USER_AGENT
11+
from .exceptions import DingzConnectionError, DingzError
12+
13+
14+
async def _request(
15+
self,
16+
uri: str,
17+
method: str = "GET",
18+
data: Optional[Any] = None,
19+
json_data: Optional[dict] = None,
20+
params: Optional[Mapping[str, str]] = None,
21+
) -> Any:
22+
"""Handle a request to the dingz unit."""
23+
headers = {
24+
"User-Agent": USER_AGENT,
25+
"Accept": "application/json, text/plain, */*",
26+
}
27+
28+
if self._session is None:
29+
self._session = aiohttp.ClientSession()
30+
self._close_session = True
31+
32+
try:
33+
with async_timeout.timeout(TIMEOUT):
34+
response = await self._session.request(
35+
method, uri, data=data, json=json_data, params=params, headers=headers,
36+
)
37+
except asyncio.TimeoutError as exception:
38+
raise DingzConnectionError(
39+
"Timeout occurred while connecting to dingz unit."
40+
) from exception
41+
except (aiohttp.ClientError, socket.gaierror) as exception:
42+
raise DingzConnectionError(
43+
"Error occurred while communicating with dingz."
44+
) from exception
45+
46+
content_type = response.headers.get("Content-Type", "")
47+
if (response.status // 100) in [4, 5]:
48+
contents = await response.read()
49+
response.close()
50+
51+
if content_type == "application/json":
52+
raise DingzError(response.status, json.loads(contents.decode("utf8")))
53+
raise DingzError(response.status, {"message": contents.decode("utf8")})
54+
if "application/json" in content_type:
55+
response_json = await response.json()
56+
return response_json
57+
58+
return response.text

dingz/dingz.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
"""A Python Client to interact with Dingz devices."""
2+
import logging
3+
4+
import aiohttp
5+
from yarl import URL
6+
7+
from . import _request as request
8+
from .constants import API, DEVICE_INFO, TEMPERATURE
9+
10+
_LOGGER = logging.getLogger(__name__)
11+
12+
13+
class Dingz:
14+
"""A class for handling the communication with a dingz device."""
15+
16+
def __init__(self, host: str, session: aiohttp.client.ClientSession = None) -> None:
17+
"""Initialize the dingz."""
18+
self._close_session = False
19+
self._host = host
20+
self._session = session
21+
self._device_details = None
22+
self._temperature = None
23+
self.uri = URL.build(scheme="http", host=self._host).join(URL(API))
24+
25+
async def get_device_info(self) -> None:
26+
"""Get the details from the switch."""
27+
url = URL(self.uri).join(URL(DEVICE_INFO))
28+
response = await request(self, uri=url)
29+
self._device_details = response
30+
31+
async def get_temperature(self) -> None:
32+
"""Get the details from the switch."""
33+
url = URL(self.uri).join(URL(TEMPERATURE))
34+
response = await request(self, uri=url)
35+
self._temperature = response["temperature"]
36+
37+
@property
38+
def device_details(self) -> float:
39+
"""Return the current device details."""
40+
return self._device_details
41+
42+
@property
43+
def temperature(self) -> float:
44+
"""Return the current temperature in celsius."""
45+
return round(self._temperature, 1)
46+
47+
async def close(self) -> None:
48+
"""Close an open client session."""
49+
if self._session and self._close_session:
50+
await self._session.close()
51+
52+
async def __aenter__(self) -> "Dingz":
53+
"""Async enter."""
54+
return self
55+
56+
async def __aexit__(self, *exc_info) -> None:
57+
"""Async exit."""
58+
await self.close()

0 commit comments

Comments
 (0)