Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
edenhaus committed Oct 28, 2023
2 parents 642e696 + 8e1b7aa commit af739a3
Show file tree
Hide file tree
Showing 132 changed files with 3,447 additions and 1,753 deletions.
5 changes: 5 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ source = deebot_client

omit =
tests/*

[report]
exclude_lines =
pragma: no cover
if TYPE_CHECKING:
3 changes: 2 additions & 1 deletion .devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Configure properties specific to VS Code.
"vscode": {
"extensions": [
"eamodio.gitlens",
"github.vscode-pull-request-github",
"ms-python.python",
"ms-python.vscode-pylance",
Expand Down Expand Up @@ -61,7 +62,7 @@
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "pip install -r requirements-dev.txt && pre-commit install && pip install -e .",
"postStartCommand": "pip install -r requirements-dev.txt && pre-commit install && pip install -e .",
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode",
"runArgs": ["-e", "GIT_EDITOR=code --wait"]
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ body:
validations:
required: true
attributes:
label: On which deebot vacuum you have the issue?
label: On which deebot device (vacuum) you have the issue?
placeholder: Deebot Ozmo 950
- type: input
id: version
Expand Down
11 changes: 5 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ on:
push:
branches:
- main
- dev
pull_request:
branches:
- main

env:
DEFAULT_PYTHON: "3.11"
Expand All @@ -16,10 +15,10 @@ jobs:
runs-on: "ubuntu-latest"
name: Check code quality
steps:
- uses: "actions/checkout@v3"
- uses: "actions/checkout@v4"
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/[email protected].0
uses: actions/[email protected].1
with:
python-version: ${{ env.DEFAULT_PYTHON }}
cache: "pip"
Expand All @@ -40,10 +39,10 @@ jobs:
runs-on: "ubuntu-latest"
name: Run tests
steps:
- uses: "actions/checkout@v3"
- uses: "actions/checkout@v4"
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/[email protected].0
uses: actions/[email protected].1
with:
python-version: ${{ env.DEFAULT_PYTHON }}
cache: "pip"
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@ on:
push:
branches:
- main
- dev
pull_request:
# The branches below must be a subset of the branches above
branches:
- main
schedule:
- cron: "20 10 * * 0"

Expand All @@ -41,7 +39,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
Expand Down
16 changes: 4 additions & 12 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,20 @@ jobs:
id-token: write
steps:
- name: 📥 Checkout the repository
uses: actions/checkout@v3

- name: 🔢 Get release version
id: version
uses: home-assistant/actions/helpers/version@master

- name: 🖊️ Set version number
run: |
sed -i '/version=/c\ version="${{ steps.version.outputs.version }}",' "${{ github.workspace }}/setup.py"
uses: actions/checkout@v4

- name: Set up Python
uses: actions/[email protected].0
uses: actions/[email protected].1
with:
python-version: "3.11"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel
pip install -q build
- name: 📦 Build package
run: python setup.py sdist bdist_wheel
run: python -m build

- name: 📤 Publish package
uses: pypa/gh-action-pypi-publish@release/v1
42 changes: 15 additions & 27 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,26 @@ default_language_version:
python: python3.11

repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.1
hooks:
- id: ruff
args:
- --fix
- repo: https://github.com/asottile/pyupgrade
rev: v3.9.0
rev: v3.15.0
hooks:
- id: pyupgrade
args:
- --py311-plus
- repo: https://github.com/psf/black
rev: 23.7.0
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 23.10.0
hooks:
- id: black
args:
- --quiet
- repo: https://github.com/codespell-project/codespell
rev: v2.2.5
rev: v2.2.6
hooks:
- id: codespell
args:
Expand All @@ -32,40 +38,22 @@ repos:
exclude_types:
- csv
- json
- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
hooks:
- id: flake8
additional_dependencies:
- flake8-docstrings==1.6.0
- pydocstyle==6.1.1
- repo: https://github.com/PyCQA/bandit
rev: 1.7.5
hooks:
- id: bandit
args:
- --quiet
- --format=custom
- --configfile=bandit.yaml
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.5.0
hooks:
- id: check-executables-have-shebangs
- id: check-merge-conflict
- id: detect-private-key
- id: no-commit-to-branch
args: [--branch, main, --branch, dev]
- id: requirements-txt-fixer
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.0.0
rev: v3.0.3
hooks:
- id: prettier
additional_dependencies:
- prettier@2.8.8
- prettier-plugin-sort-json@1.0.0
- prettier@3.0.3
- prettier-plugin-sort-json@3.0.1
exclude_types:
- python
- repo: https://github.com/adrienverge/yamllint.git
Expand Down
3 changes: 0 additions & 3 deletions .prettierrc

This file was deleted.

5 changes: 5 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @type {import("prettier").Config} */
module.exports = {
plugins: [require.resolve("prettier-plugin-sort-json")],
jsonRecursiveSort: true,
};
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Client Library for Deebot Vacuums
# Client Library for Deebot devices (Vacuums)

[![PyPI - Downloads](https://img.shields.io/pypi/dw/deebot-client?style=for-the-badge)](https://pypi.org/project/deebot-client)
<a href="https://www.buymeacoffee.com/edenhaus" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-black.png" width="150px" height="35px" alt="Buy Me A Coffee" style="height: 35px !important;width: 150px !important;" ></a>
Expand Down Expand Up @@ -31,7 +31,7 @@ from deebot_client.events import BatteryEvent
from deebot_client.models import Configuration
from deebot_client.mqtt_client import MqttClient, MqttConfiguration
from deebot_client.util import md5
from deebot_client.vacuum_bot import VacuumBot
from deebot_client.device import Device

device_id = md5(str(time.time()))
account_id = "your email or phonenumber (cn)"
Expand All @@ -52,7 +52,7 @@ async def main():

devices_ = await api_client.get_devices()

bot = VacuumBot(devices_[0], authenticator)
bot = Device(devices_[0], authenticator)

mqtt_config = MqttConfiguration(config=config)
mqtt = MqttClient(mqtt_config, authenticator)
Expand Down
20 changes: 0 additions & 20 deletions bandit.yaml

This file was deleted.

8 changes: 6 additions & 2 deletions deebot_client/api_client.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
"""Api client module."""
from typing import Any

from deebot_client.hardware.deebot import get_static_device_info

from .authentication import Authenticator
from .const import PATH_API_APPSVR_APP, PATH_API_PIM_PRODUCT_IOT_MAP
from .exceptions import ApiError
from .logging_filter import get_logger
from .models import DeviceInfo
from .models import ApiDeviceInfo, DeviceInfo

_LOGGER = get_logger(__name__)

Expand All @@ -27,9 +29,11 @@ async def get_devices(self) -> list[DeviceInfo]:

if resp.get("code", None) == 0:
devices: list[DeviceInfo] = []
device: ApiDeviceInfo
for device in resp["devices"]:
if device.get("company") == "eco-ng":
devices.append(DeviceInfo(device))
static_device_info = get_static_device_info(device["class"])
devices.append(DeviceInfo(device, static_device_info))
else:
_LOGGER.debug("Skipping device as it is not supported: %s", device)
return devices
Expand Down
40 changes: 17 additions & 23 deletions deebot_client/authentication.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Authentication module."""
import asyncio
import time
from collections.abc import Callable, Coroutine, Mapping
from http import HTTPStatus
import time
from typing import Any
from urllib.parse import urljoin

Expand All @@ -16,9 +17,9 @@
_LOGGER = get_logger(__name__)

_CLIENT_KEY = "1520391301804"
_CLIENT_SECRET = "6c319b2a5cd3e66e39159c2e28f2fce9"
_CLIENT_SECRET = "6c319b2a5cd3e66e39159c2e28f2fce9" # noqa: S105
_AUTH_CLIENT_KEY = "1520391491841"
_AUTH_CLIENT_SECRET = "77ef58ce3afbe337da74aa8c5ab963a9"
_AUTH_CLIENT_SECRET = "77ef58ce3afbe337da74aa8c5ab963a9" # noqa: S105
_USER_LOGIN_URL_FORMAT = (
"https://gl-{country}-api.ecovacs.{tld}/v1/private/{country}/{lang}/{deviceId}/{appCode}/"
"{appVersion}/{channel}/{deviceType}/user/login"
Expand Down Expand Up @@ -252,7 +253,7 @@ async def post(
timeout=60,
ssl=self._config.verify_ssl,
) as res:
if res.status == 200:
if res.status == HTTPStatus.OK:
response_data: dict[str, Any] = await res.json()
_LOGGER.debug(
"Success calling api %s, response=%s",
Expand All @@ -271,14 +272,14 @@ async def post(
message=str(res.reason),
headers=res.headers,
)
except asyncio.TimeoutError as ex:
except TimeoutError as ex:
_LOGGER.warning(
"Timeout reached on api path: %s%s", path, json.get("cmdName", "")
)
raise ApiError("Timeout reached") from ex
except ClientResponseError as ex:
_LOGGER.debug("Error: %s", logger_requst_params, exc_info=True)
if ex.status == 502:
if ex.status == HTTPStatus.BAD_GATEWAY:
seconds_to_sleep = 10
_LOGGER.info(
"Retry calling API due 502: Unfortunately the ecovacs api is unreliable. Retrying in %d seconds",
Expand Down Expand Up @@ -319,23 +320,19 @@ def __init__(
async def authenticate(self, force: bool = False) -> Credentials:
"""Authenticate on ecovacs servers."""
async with self._lock:
should_login = False
if self._credentials is None or force:
_LOGGER.debug("No cached credentials, performing login")
should_login = True
elif self._credentials.expires_at < time.time():
_LOGGER.debug("Credentials have expired, performing login")
should_login = True

if should_login:
if (
self._credentials is None
or force
or self._credentials.expires_at < time.time()
):
_LOGGER.debug("Performing login")
self._credentials = await self._auth_client.login()
self._cancel_refresh_task()
self._create_refresh_task()
self._create_refresh_task(self._credentials)

for on_changed in self._on_credentials_changed:
create_task(self._tasks, on_changed(self._credentials))

assert self._credentials is not None
return self._credentials

def subscribe(
Expand Down Expand Up @@ -375,7 +372,7 @@ def _cancel_refresh_task(self) -> None:
if self._refresh_handle and not self._refresh_handle.cancelled():
self._refresh_handle.cancel()

def _create_refresh_task(self) -> None:
def _create_refresh_task(self, credentials: Credentials) -> None:
# refresh at 99% of validity
def refresh() -> None:
_LOGGER.debug("Refresh token")
Expand All @@ -384,14 +381,11 @@ async def async_refresh() -> None:
try:
await self.authenticate(True)
except Exception: # pylint: disable=broad-except
_LOGGER.error(
"An exception occurred during refreshing token", exc_info=True
)
_LOGGER.exception("An exception occurred during refreshing token")

create_task(self._tasks, async_refresh())
self._refresh_handle = None

assert self._credentials is not None
validity = (self._credentials.expires_at - time.time()) * 0.99
validity = (credentials.expires_at - time.time()) * 0.99

self._refresh_handle = asyncio.get_event_loop().call_later(validity, refresh)
Loading

0 comments on commit af739a3

Please sign in to comment.