Skip to content

Commit 7acdaed

Browse files
committed
Ruff format
1 parent 3a9ebc1 commit 7acdaed

File tree

4 files changed

+144
-103
lines changed

4 files changed

+144
-103
lines changed

recuair_cli/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""Command line interface for manipulation of Recuair devices."""
22

3-
__version__ = '0.0.0'
3+
__version__ = "0.0.0"

recuair_cli/main.py

Lines changed: 61 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@
2323
--version show program's version number and exit
2424
--debug print debug logs
2525
"""
26+
2627
import asyncio
2728
import logging
2829
import sys
30+
from collections.abc import Coroutine
2931
from http import HTTPStatus
30-
from typing import Any, Callable, Coroutine, Dict, List, NamedTuple, Optional, TypeVar, cast
32+
from typing import Any, Callable, NamedTuple, Optional, TypeVar, cast
3133

3234
import httpx
3335
from bs4 import BeautifulSoup, PageElement, Tag
@@ -73,13 +75,13 @@ class Status(NamedTuple):
7375

7476
def _strip_unit(value: str) -> str:
7577
"""Strip unit from quantity and return only a quantity value."""
76-
return value.strip().partition(' ')[0]
78+
return value.strip().partition(" ")[0]
7779

7880

7981
async def get_status(client: httpx.AsyncClient, device: str) -> Status:
8082
"""Return device status."""
8183
try:
82-
response = await client.get(f'http://{device}/', timeout=3)
84+
response = await client.get(f"http://{device}/", timeout=3)
8385
response.raise_for_status()
8486
except httpx.HTTPError as error:
8587
_LOGGER.debug("Error encountered: %s", error)
@@ -88,26 +90,35 @@ async def get_status(client: httpx.AsyncClient, device: str) -> Status:
8890

8991
try:
9092
content = BeautifulSoup(response.text, features="html.parser")
91-
container = cast(Tag, content.find(class_='container'))
92-
temperature_raw = cast(PageElement,
93-
cast(Tag, container.find_all(class_='col-12')[1]).find(class_='bigText')).text
94-
in_data, _, temp_out = temperature_raw.strip().partition('%')
95-
temp_in, _, humi_in = in_data.strip().partition('/')
96-
mode_raw = cast(PageElement, cast(Tag, container.find_all(class_='col-12')[3]).find('span')).text
97-
co2_raw = cast(PageElement, cast(Tag, container.find_all(class_='col-12')[4]).find('b')).text
98-
filter_raw = cast(
99-
str,
100-
cast(Tag, cast(Tag, container.find_all(class_='filterBox')[1]).div)['style'],
101-
).partition(':')[2].partition('%')[0]
102-
fan_raw = cast(
103-
str,
104-
cast(Tag, cast(Tag, container.find_all(class_='filterBox')[2]).div)['style'],
105-
).partition(':')[2].partition('%')[0]
106-
light_raw = cast(str, cast(Tag, container.find(id='myRange'))['value'])
93+
container = cast(Tag, content.find(class_="container"))
94+
temperature_raw = cast(
95+
PageElement, cast(Tag, container.find_all(class_="col-12")[1]).find(class_="bigText")
96+
).text
97+
in_data, _, temp_out = temperature_raw.strip().partition("%")
98+
temp_in, _, humi_in = in_data.strip().partition("/")
99+
mode_raw = cast(PageElement, cast(Tag, container.find_all(class_="col-12")[3]).find("span")).text
100+
co2_raw = cast(PageElement, cast(Tag, container.find_all(class_="col-12")[4]).find("b")).text
101+
filter_raw = (
102+
cast(
103+
str,
104+
cast(Tag, cast(Tag, container.find_all(class_="filterBox")[1]).div)["style"],
105+
)
106+
.partition(":")[2]
107+
.partition("%")[0]
108+
)
109+
fan_raw = (
110+
cast(
111+
str,
112+
cast(Tag, cast(Tag, container.find_all(class_="filterBox")[2]).div)["style"],
113+
)
114+
.partition(":")[2]
115+
.partition("%")[0]
116+
)
117+
light_raw = cast(str, cast(Tag, container.find(id="myRange"))["value"])
107118

108119
return Status(
109120
device=device,
110-
name=cast(Tag, content.find(class_='deviceName')).text,
121+
name=cast(Tag, content.find(class_="deviceName")).text,
111122
temperature_in=int(_strip_unit(temp_in)),
112123
humidity_in=int(_strip_unit(humi_in)),
113124
temperature_out=int(_strip_unit(temp_out)),
@@ -122,11 +133,11 @@ async def get_status(client: httpx.AsyncClient, device: str) -> Status:
122133
raise RecuairError(f"Invalid response returned from device {device}") from error
123134

124135

125-
async def post_request(client: httpx.AsyncClient, device: str, data: Dict[str, Any]) -> None:
136+
async def post_request(client: httpx.AsyncClient, device: str, data: dict[str, Any]) -> None:
126137
"""Send a POST request to the device."""
127138
try:
128139
# XXX: Disable redirects. Recuair returns 301 for POST requests.
129-
response = await client.post(f'http://{device}/', data=data, timeout=5, follow_redirects=False)
140+
response = await client.post(f"http://{device}/", data=data, timeout=5, follow_redirects=False)
130141
except httpx.HTTPError as error:
131142
_LOGGER.debug("Error encountered: %s", error)
132143
raise RecuairError(f"Error from device {device}: {error}") from error
@@ -136,38 +147,43 @@ async def post_request(client: httpx.AsyncClient, device: str, data: Dict[str, A
136147
_LOGGER.debug("Response [%s]: %s", response, response.text)
137148

138149

139-
X = TypeVar('X')
150+
X = TypeVar("X")
140151

141152

142153
# XXX: Add retry, recuair devices are often irresponsive.
143154
def _wrap_retry(func: Callable[..., X]) -> Callable[..., X]:
144155
return retry(reraise=True, stop=stop_after_attempt(10), wait=wait_exponential(max=30))(func)
145156

146157

147-
async def _run(options: Dict[str, str]) -> None:
158+
async def _run(options: dict[str, str]) -> None: # noqa: C901
148159
"""Actually run the command."""
149160
error_found = False
150161
async with httpx.AsyncClient() as client:
151-
coros: List[Coroutine] = []
152-
for device in options['<device>']:
153-
if options['start']:
162+
coros: list[Coroutine] = []
163+
for device in options["<device>"]:
164+
if options["start"]:
154165
# XXX: Start in auto mode. Recuair GUI starts on mode 1.
155-
coros.append(_wrap_retry(post_request)(client, device, {'mode': 'auto'}))
156-
elif options['stop']:
157-
coros.append(_wrap_retry(post_request)(client, device, {'mode': 'off'}))
158-
elif options['holiday']:
159-
coros.append(_wrap_retry(post_request)(client, device, {'mode': 'holiday'}))
160-
elif options['bypass']:
161-
coros.append(_wrap_retry(post_request)(client, device, {'mode': 'bypass'}))
162-
elif options['light']:
166+
coros.append(_wrap_retry(post_request)(client, device, {"mode": "auto"}))
167+
elif options["stop"]:
168+
coros.append(_wrap_retry(post_request)(client, device, {"mode": "off"}))
169+
elif options["holiday"]:
170+
coros.append(_wrap_retry(post_request)(client, device, {"mode": "holiday"}))
171+
elif options["bypass"]:
172+
coros.append(_wrap_retry(post_request)(client, device, {"mode": "bypass"}))
173+
elif options["light"]:
163174
# XXX: Recuair doesn't accept only change in light intensity.
164175
# Whole light setting has to be provided.
165-
if options['off']:
176+
if options["off"]:
166177
coros.append(
167-
_wrap_retry(post_request)(client, device, {'r': '0', 'g': '0', 'b': '0', 'intensity': '0'}))
178+
_wrap_retry(post_request)(client, device, {"r": "0", "g": "0", "b": "0", "intensity": "0"})
179+
)
168180
else:
169-
data = {'r': options['<red>'], 'g': options['<green>'], 'b': options['<blue>'],
170-
'intensity': options['<intensity>']}
181+
data = {
182+
"r": options["<red>"],
183+
"g": options["<green>"],
184+
"b": options["<blue>"],
185+
"intensity": options["<intensity>"],
186+
}
171187
coros.append(_wrap_retry(post_request)(client, device, data))
172188
else:
173189
coros.append(_wrap_retry(get_status)(client, device))
@@ -184,16 +200,17 @@ async def _run(options: Dict[str, str]) -> None:
184200
sys.exit(1)
185201

186202

187-
def main(argv: Optional[List[str]] = None) -> None:
203+
def main(argv: Optional[list[str]] = None) -> None:
188204
"""Run the CLI."""
189205
options = docopt(__doc__, version=__version__, argv=argv)
190206

191-
if options['--debug']: # pragma: no cover
192-
logging.basicConfig(level=logging.DEBUG,
193-
format='%(asctime)s %(levelname)-8s %(name)s:%(funcName)s: %(message)s')
207+
if options["--debug"]: # pragma: no cover
208+
logging.basicConfig(
209+
level=logging.DEBUG, format="%(asctime)s %(levelname)-8s %(name)s:%(funcName)s: %(message)s"
210+
)
194211

195212
asyncio.run(_run(options))
196213

197214

198-
if __name__ == '__main__': # pragma: no cover
215+
if __name__ == "__main__": # pragma: no cover
199216
main()

0 commit comments

Comments
 (0)