Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,10 @@ repos:
name: 🆎 Static type checking using mypy
language: system
types: [python]
entry: poetry run mypy
entry: poetry run mypy --namespace-packages
require_serial: true
pass_filenames: false
args: [src]
- id: no-commit-to-branch
name: 🛑 Don't commit to main branch
language: system
Expand All @@ -107,7 +109,8 @@ repos:
name: 🌟 Starring code with pylint
language: system
types: [python]
entry: poetry run pylint
entry: poetry run pylint src
pass_filenames: false
- id: pytest
name: 🧪 Running tests and test coverage with pytest
language: system
Expand Down
2 changes: 1 addition & 1 deletion .yamllint
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ rules:
level: error
new-lines:
level: error
type: unix
type: platform
trailing-spaces:
level: error
truthy:
Expand Down
2 changes: 1 addition & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@ good-names=id,i,j,k,ex,Run,_,fp
# locally-disabled - it spams too much
# duplicate-code - unavoidable
# cyclic-import - doesn't test if both import on load
# abstract-class-little-used - prevents from setting right foundation
# unused-argument - generic callbacks and setup methods create a lot of warnings
# global-statement - used for the on-demand requirement installation
# redefined-variable-type - this is Python, we're duck typing!
# too-many-* - are not enforced for the sake of readability
# too-few-* - same as too-many-*
# abstract-method - with intro of async there are always methods missing
Expand All @@ -28,7 +26,6 @@ good-names=id,i,j,k,ex,Run,_,fp
# wrong-import-order - isort guards this
disable=
format,
abstract-class-little-used,
abstract-method,
cyclic-import,
duplicate-code,
Expand All @@ -37,7 +34,6 @@ disable=
inconsistent-return-statements,
locally-disabled,
not-context-manager,
redefined-variable-type,
too-few-public-methods,
too-many-ancestors,
too-many-arguments,
Expand Down Expand Up @@ -66,4 +62,4 @@ ignored-classes=_CountingAttr
expected-line-ending-format=LF

[EXCEPTIONS]
overgeneral-exceptions=BaseException,Exception
overgeneral-exceptions=builtins.BaseException,builtins.Exception
69 changes: 29 additions & 40 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,32 +1,44 @@
[tool.poetry]
[project]
name = "python-melcloud"
version = "0.1.1"
authors = ["Erwin Douna <[email protected]>"]
description = "Asynchronous Python client for controlling Melcloud devices."
authors = [{ name = "Erwin Douna", email = "[email protected]" }]
maintainers = [{ name = "Erwin Douna", email = "[email protected]" }]
license = { text = "MIT" }
readme = "README.md"
keywords = ["melcloud", "homeassistant", "api", "async", "client"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Framework :: AsyncIO",
"Intended Audience :: Developers",
"Natural Language :: English",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Software Development :: Libraries :: Python Modules",
]
description = "Asynchronous Python client for controlling Melcloud devices."
documentation = "https://github.com/erwindouna/python-melcloud"
homepage = "https://github.com/erwindouna/python-melcloud"
keywords = ["melcloud", "homeassistant", "api", "async", "client"]
license = "MIT"
maintainers = ["Erwin Douna <[email protected]>"]
requires-python = ">=3.12"
dependencies = [
"aiohttp>=3.0.0",
]

[project.urls]
Homepage = "https://github.com/erwindouna/python-melcloud"
Repository = "https://github.com/erwindouna/python-melcloud"
Documentation = "https://github.com/erwindouna/python-melcloud"
"Bug Tracker" = "https://github.com/erwindouna/python-melcloud/issues"
Changelog = "https://github.com/erwindouna/python-melcloud/releases"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.poetry]
packages = [{ include = "pymelcloud", from = "src" }]
readme = "README.md"
repository = "https://github.com/erwindouna/python-melcloud"

[tool.poetry.dependencies]
aiohttp = ">=3.0.0"
python = "^3.12"
aiohttp = ">=3.0.0"

[tool.poetry.urls]
"Bug Tracker" = "https://github.com/erwindouna/python-melcloud/issues"
Changelog = "https://github.com/erwindouna/python-melcloud/releases"

[tool.poetry.group.dev.dependencies]
aresponses = "3.0.0"
Expand Down Expand Up @@ -103,30 +115,10 @@ max-line-length = 88
[tool.pytest.ini_options]
addopts = "--cov --cov-fail-under=55" # Fice for now, since this is how the project was inherited
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"

[tool.ruff]
ignore = [
"ANN401", # Opinionated warning on disallowing dynamically typed expressions
"D203", # Conflicts with other rules
"ARG002", # Conflicts with other rules
"D213", # Conflicts with other rules
"D417", # False positives in some occasions
"PLR2004", # Just annoying, not really useful
"SLOT000", # Has a bug with enums: https://github.com/astral-sh/ruff/issues/5748
"TRY003", # Avoid specifying long messages outside the exception class
"EM101", # Exception must not use a string literal, assign to variable first
"EM102", # Exception must not use an f-string literal, assign to variable first
"PLR0913", # Too many arguments in function definition
"N815", # Scope should not be mixedCase
"PLR0912", # Too many branches
"PLR0915", # Too many statements
"C901", # Too complex

# Conflicts with the Ruff formatter
"COM812",
"ISC001",
]
select = ["ALL"]
target-version = "py312"

[tool.ruff.lint]
ignore = [
Expand All @@ -145,6 +137,7 @@ ignore = [
"PLR0912", # Too many branches
"PLR0915", # Too many statements
"C901", # Too complex
"S101", # Use of assert detected (allow in tests)

# Conflicts with the Ruff formatter
"COM812",
Expand All @@ -161,7 +154,3 @@ known-first-party = ["pymelcloud"]

[tool.ruff.lint.mccabe]
max-complexity = 25

[build-system]
build-backend = "poetry.core.masonry.api"
requires = ["poetry-core>=1.5,<2.0"]
21 changes: 12 additions & 9 deletions src/pymelcloud/__init__.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,48 @@
"""MELCloud client library."""

from datetime import timedelta
from typing import Dict, List, Optional

from aiohttp import ClientSession

from pymelcloud.ata_device import AtaDevice
from pymelcloud.atw_device import AtwDevice
from pymelcloud.erv_device import ErvDevice
from pymelcloud.client import Client as _Client
from pymelcloud.client import login as _login
from pymelcloud.const import DEVICE_TYPE_ATA, DEVICE_TYPE_ATW, DEVICE_TYPE_ERV
from pymelcloud.device import Device
from pymelcloud.erv_device import ErvDevice


async def login(
email: str, password: str, session: Optional[ClientSession] = None,
email: str,
password: str,
session: ClientSession | None = None,
) -> str:
"""Log in to MELCloud with given credentials.

Returns access token.
"""
_client = await _login(email, password, session,)
_client = await _login(email, password, session)
return _client.token


async def get_devices(
token: str,
session: Optional[ClientSession] = None,
session: ClientSession | None = None,
*,
conf_update_interval=timedelta(minutes=5),
device_set_debounce=timedelta(seconds=1),
) -> Dict[str, List[Device]]:
conf_update_interval: timedelta = timedelta(minutes=5),
device_set_debounce: timedelta = timedelta(seconds=1),
) -> dict[str, list[Device]]:
"""Initialize Devices available with the token.

The devices share a the same Client instance and pool config fetches. The devices
should be fetched only once during application life cycle to leverage the request
pooling and rate limits.

Keyword arguments:
Keyword Arguments:
conf_update_interval -- rate limit for fetching device confs. (default = 5 min)
device_set_debounce -- debounce time for writing device state. (default = 1 s)

"""
_client = _Client(
token,
Expand Down
Loading