diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b2aaf22..dd9ad17 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,7 +5,7 @@ version: 2 updates: - - package-ecosystem: "github-actions" # See documentation for possible values - directory: "/" # Location of package manifests + - package-ecosystem: "github-actions" + directory: "/" schedule: interval: "daily" diff --git a/.github/workflows/hassfest.yaml b/.github/workflows/hassfest.yaml index 695b8c8..75144ef 100644 --- a/.github/workflows/hassfest.yaml +++ b/.github/workflows/hassfest.yaml @@ -12,4 +12,3 @@ jobs: steps: - uses: "actions/checkout@v4.1.1" - uses: home-assistant/actions/hassfest@master - diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000..320406d --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,2 @@ +default: true +MD013: false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..4065f45 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,82 @@ +# For pre-commit.ci +ci: + # Defer autoupdate to quarterly (there is no 'off' button) to have renovate pick up first + autoupdate_schedule: quarterly + submodules: true + +default_language_version: + # force all unspecified python hooks to run python3 + python: python3.12 + +repos: + # Run manually in CI skipping the branch checks + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.1.3 + hooks: + - id: ruff + name: "Ruff-ing code" + args: + - --fix + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-executables-have-shebangs + stages: [manual] + - id: no-commit-to-branch + name: "Verifying git branch exists" + args: + - --branch=main + - repo: https://github.com/asottile/pyupgrade + rev: v3.15.0 + hooks: + - id: pyupgrade + name: "Checking pyupgrade" + args: [--py311-plus] + - repo: https://github.com/psf/black + rev: 23.10.1 + hooks: + - id: black + name: "Verifying/updating code using black" + args: + - --safe + - --quiet + files: ^((custom_components|tests)/.+)?[^/]+\.py$ + - repo: https://github.com/codespell-project/codespell + rev: v2.2.6 + hooks: + - id: codespell + name: "Verifying/updating code for spelling issues" + args: + - --ignore-words-list=hass,alot,datas,dof,dur,ether,farenheit,hist,iff,iif,ines,ist,lightsensor,mut,nd,pres,referer,rime,ser,serie,te,technik,ue,uint,visability,wan,wanna,withing,iam,incomfort,ba,haa,pullrequests + - --skip="./.*,*.csv,*.json" + - --quiet-level=2 + exclude_types: [csv, json] + - repo: https://github.com/adrienverge/yamllint.git + rev: v1.32.0 + hooks: + - id: yamllint + name: "Linting yaml" + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v3.0.3 + hooks: + - id: prettier + name: "Verifying/updating code with prettier" + - repo: https://github.com/cdce8p/python-typing-update + rev: v0.6.0 + hooks: + # Run `python-typing-update` hook manually from time to time + # to update python typing syntax. + # Will require manual work, before submitting changes! + - id: python-typing-update + name: "Verifying code for typing-update" + stages: [manual] + args: + - --py311-plus + - --force + - --keep-updates + files: ^(custom_components|tests)/.+\.py$ + - repo: https://github.com/igorshubovych/markdownlint-cli + rev: v0.37.0 + hooks: + - id: markdownlint + name: "Linting Markdown" diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..f93caaf --- /dev/null +++ b/.yamllint @@ -0,0 +1,66 @@ +# Copy of github.com/home-assistant/core .yamllint +# Our addition to truthy +# truthy: +# allowed-values: ['true', 'false', 'on'] +ignore: | + azure-*.yml +rules: + braces: + level: error + min-spaces-inside: 0 + max-spaces-inside: 1 + min-spaces-inside-empty: -1 + max-spaces-inside-empty: -1 + brackets: + level: error + min-spaces-inside: 0 + max-spaces-inside: 0 + min-spaces-inside-empty: -1 + max-spaces-inside-empty: -1 + colons: + level: error + max-spaces-before: 0 + max-spaces-after: 1 + commas: + level: error + max-spaces-before: 0 + min-spaces-after: 1 + max-spaces-after: 1 + comments: + level: error + require-starting-space: true + min-spaces-from-content: 2 + comments-indentation: + level: error + document-end: + level: error + present: false + document-start: + level: error + present: false + empty-lines: + level: error + max: 1 + max-start: 0 + max-end: 1 + hyphens: + level: error + max-spaces-after: 1 + indentation: + level: error + spaces: 2 + indent-sequences: true + check-multi-line-strings: false + key-duplicates: + level: error + line-length: disable + new-line-at-end-of-file: + level: error + new-lines: + level: error + type: unix + trailing-spaces: + level: error + truthy: + allowed-values: ['true', 'false', 'on', 'False'] # 'on' for github actions, 'False' for our services.yaml + level: error diff --git a/README.md b/README.md index beb4dce..9cb86cd 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,21 @@ -**:warning::warning::warning:Read the [release notes]() before upgrading, in case there are BREAKING changes!:warning::warning::warning:** - # Stromer Custom Component for Home Assistant - [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/CoMPaTech/stomer/) - [![CodeFactor](https://www.codefactor.io/repository/github/CoMPaTech/stromer/badge)](https://www.codefactor.io/repository/github/CoMPaTech/stromer) - [![HASSfest](https://github.com/CoMPaTech/stromer/workflows/Validate%20with%20hassfest/badge.svg)](https://github.com/CoMPaTech/stromer/actions) - [![Generic badge](https://img.shields.io/github/v/release/CoMPaTech/stromer)](https://github.com/CoMPaTech/stromer) +**:warning::warning::warning:Read the [release notes](https://github.com/CoMPaTech/stromer/releases) before upgrading, in case there are BREAKING changes!:warning::warning::warning:** + +[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/CoMPaTech/stomer/) +[![CodeFactor](https://www.codefactor.io/repository/github/CoMPaTech/stromer/badge)](https://www.codefactor.io/repository/github/CoMPaTech/stromer) +[![HASSfest](https://github.com/CoMPaTech/stromer/workflows/Validate%20with%20hassfest/badge.svg)](https://github.com/CoMPaTech/stromer/actions) +[![Generic badge](https://img.shields.io/github/v/release/CoMPaTech/stromer)](https://github.com/CoMPaTech/stromer) - [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=CoMPaTech_stromer&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=CoMPaTech_stromer) - [![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=CoMPaTech_stromer&metric=sqale_index)](https://sonarcloud.io/summary/new_code?id=CoMPaTech_stromer) - [![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=CoMPaTech_stromer&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=CoMPaTech_stromer) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=CoMPaTech_stromer&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=CoMPaTech_stromer) +[![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=CoMPaTech_stromer&metric=sqale_index)](https://sonarcloud.io/summary/new_code?id=CoMPaTech_stromer) +[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=CoMPaTech_stromer&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=CoMPaTech_stromer) -[![Open your Home Assistant instance and show your integrations.](https://my.home-assistant.io/badges/integrations.svg)](https://my.home-assistant.io/redirect/integrations/) +[![Open your Home Assistant instance and show your integrations.](https://my.home-assistant.io/badges/integrations.svg)](https://my.home-assistant.io/redirect/integrations/) ## Configuration -Configure this integration the usual way, before starting you will need to retrieve your +Configure this integration the usual way, before starting you will need to retrieve your - [ ] Client ID - [ ] Client Secret @@ -38,7 +38,7 @@ Basically you'll have to trigger (through automations) the updates yourself. But - [![Open your automations.](https://my.home-assistant.io/badges/automations.svg)](https://my.home-assistant.io/redirect/automations/) - Create a new automation, click on the right-top three dots and select 'Edit as YAML'. Don't worry, most of it you will be able to use the visual editor for, it's just that pasting is much easier this way. Do note that you'll have to change the `stromer` part of the bike (or after pasting, select the three dots, go back to visual editor and pick the correct entity). -``` +```automation.yml alias: Stromer cancel updates when locked description: '' trigger: @@ -59,7 +59,7 @@ mode: single - Create another automation, same process as above -``` +```automation.yml alias: Stromer start updates when unlocked description: '' trigger: @@ -80,7 +80,7 @@ mode: single - And the final one, actually calling the updates (example every 30 seconds). We'll only point to speed, but it will update the other sensors -``` +```automation.yml alias: Stromer update sensors description: '' trigger: @@ -100,7 +100,7 @@ mode: single - Final step is adding a button to your dashboard if you want to trigger updates right now. Do note that your bike must be **unlocked** before triggering, otherwise it will 'cancel itself' :) In a dashboard, click the three buttons right top, and add a `button`-card, through `view code editor` paste, switch back to visual editor and customize the below to your taste. Again pointing at speed but it will refresh if the bike is unlocked and trigger the updates helper. -``` +```lovelace.yml show_name: true show_icon: true type: button @@ -122,50 +122,62 @@ show_state: false Even though available does not mean it's stable yet, the HA part is solid but the class used to interact with the API is in need of improvement (e.g. better overall handling). This might also warrant having the class available as a module from pypi. -# Changelog +## Changelog + +### NOV 2023 [0.2.7] + +- Fix to appropriate `device_class` from 0.2.5 + +### NOV 2023 [0.2.6] -## NOV 2023 [0.2.7] - - Fix to appropriate `device_class` from 0.2.5 +- Fix API recall (reverted maintenance approach from 0.2.5) tnx to @simonwolf83 -## NOV 2023 [0.2.6] - - Fix API recall (reverted maintenance approach from 0.2.5) tnx to @simonwolf83 +### NOV 2023 [0.2.5] -## NOV 2023 [0.2.5] - - Fix unit from W to Wh (thanks @Tinus78) via #46 +- Fix unit from W to Wh (thanks @Tinus78) via #46 ## OCT 2023 [0.2.4] - - Improve quality -## SEP 2023 [0.2.3] - - Conform to hacs and HA files - - Adding HACS validation +- Improve quality + +### SEP 2023 [0.2.3] + +- Conform to hacs and HA files +- Adding HACS validation + +### SEP 2023 [0.2.2] + +- Fix location (i.e. `device_tracker`) reporting + +### AUG 2023 [0.2.1] + +- Quickfix sensors lost due to some data not available + +### MAR 2023 [0.2.0] + +- Fix 2023.3 compliance + +### APR 2022 [0.1.0] -## SEP 2023 [0.2.2] - - Fix location (i.e. `device_tracker`) reporting +- Include last update sensors -## AUG 2023 [0.2.1] - - Quickfix sensors lost due to some data not available +### APR 2022 [0.0.8] -## MAR 2023 [0.2.0] - - Fix 2023.3 compliancy +- v4 API support +- Data handling and reconnection -## APR 2022 [0.1.0] - - Include last update sensors +### APR 2022 [0.0.7] -## APR 2022 [0.0.8] - - v4 API support - - Data handling and reconnection +- Fix sensory updates +- Potentially fix token expiration -## APR 2022 [0.0.7] - - Fix sensory updates - - Potentially fix token expiration +### MAR 2022 [0.0.4] -## MAR 2022 [0.0.4] - - Initial release - - Creates a device for your bike in Home Assistant - - Refreshed location and other information every 10 minutes +- Initial release +- Creates a device for your bike in Home Assistant +- Refreshed location and other information every 10 minutes -# What does it support? +## What does it support? - Location - It inherits zones, but you could also plot your location on a map @@ -174,26 +186,26 @@ Even though available does not mean it's stable yet, the HA part is solid but th - Binary Sensors - Light-status and Omni-lock status and theft status -# How to install? +## How to install? - Use [HACS](https://hacs.xyz) - Navigate to the `Integrations` page and use the three-dots icon on the top right to add a custom repository. - Use the link to this page as the URL and select 'Integrations' as the category. - Look for `Stromer` in `Integrations` and install it! -## How to add the integration to HA Core +### How to add the integration to HA Core For each bike (i.e. api-user) you will have to add it as an integration. Do note that you first have to retrieve your client ID and Secret using some tool like [mitmproxy](https://mitmproxy.org) to fetch these. If you don't know how to do this or what this implies; search from someone who can eloborate on this or do not use this integration. For more details and/or helpful users see [the Dutch Stromer forum](https://www.speedpedelecreview.com/forum/viewtopic.php?f=8&t=1445) -- [ ] In Home Assitant click on `Configuration` +- [ ] In Home Assistant click on `Configuration` - [ ] Click on `Integrations` - [ ] Hit the `+` button in the right lower corner - [ ] Search or browse for 'Stromer e-bike' and click it - [ ] Enter your e-mail address, password and the client ID and Secret -# Frequently Asked Questions (FAQ) +## Frequently Asked Questions (FAQ) -## I don't like the name of the sensor or the icon +### I don't like the name of the sensor or the icon You can adjust these in `Configuration`, `Integration` -> `Entities` (e.g. `https://{Your HA address}/config/entities`) @@ -201,11 +213,11 @@ Just click on the device and adjust accordingly! Please note that you can also click the cogwheel right top corner to rename all entities of a device at once. -## It doesn't work +### It doesn't work I'm on Discord and used to frequent the Dutch Stromer forum more often, but feel free to add a Bug through the Issues tab on [Github](https://github.com/CoMPaTech/stromer). -## Is it tested? +### Is it tested? It works on my bike and Home Assistant installation :) Let me know if it works on yours! diff --git a/custom_components/stromer/__init__.py b/custom_components/stromer/__init__.py index d4f73c1..b7ff1be 100644 --- a/custom_components/stromer/__init__.py +++ b/custom_components/stromer/__init__.py @@ -14,7 +14,11 @@ SCAN_INTERVAL = timedelta(minutes=10) -PLATFORMS: list[Platform] = [Platform.SENSOR, Platform.BINARY_SENSOR, Platform.DEVICE_TRACKER] +PLATFORMS: list[Platform] = [ + Platform.SENSOR, + Platform.BINARY_SENSOR, + Platform.DEVICE_TRACKER, +] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: @@ -34,7 +38,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: except ApiError as ex: raise ConfigEntryNotReady("Error while communicating to Stromer API") from ex - LOGGER.debug("Stromer entry: {}".format(entry)) + LOGGER.debug(f"Stromer entry: {entry}") # Use Bike ID as unique id if entry.unique_id is None: diff --git a/custom_components/stromer/binary_sensor.py b/custom_components/stromer/binary_sensor.py index 3461ef9..6c7c5a1 100644 --- a/custom_components/stromer/binary_sensor.py +++ b/custom_components/stromer/binary_sensor.py @@ -4,7 +4,9 @@ from dataclasses import dataclass from homeassistant.components.binary_sensor import ( - BinarySensorEntity, BinarySensorEntityDescription) + BinarySensorEntity, + BinarySensorEntityDescription, +) from homeassistant.helpers.entity import EntityCategory from custom_components.stromer.coordinator import StromerDataUpdateCoordinator diff --git a/custom_components/stromer/config_flow.py b/custom_components/stromer/config_flow.py index 114fc33..da55cc7 100644 --- a/custom_components/stromer/config_flow.py +++ b/custom_components/stromer/config_flow.py @@ -6,7 +6,6 @@ import voluptuous as vol from homeassistant import config_entries from homeassistant.const import CONF_PASSWORD, CONF_USERNAME -from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResult from homeassistant.exceptions import HomeAssistantError diff --git a/custom_components/stromer/coordinator.py b/custom_components/stromer/coordinator.py index 567afa3..81b06a3 100644 --- a/custom_components/stromer/coordinator.py +++ b/custom_components/stromer/coordinator.py @@ -3,8 +3,7 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed -from homeassistant.helpers.update_coordinator import (DataUpdateCoordinator, - UpdateFailed) +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import DOMAIN, LOGGER from .stromer import Stromer, ApiError @@ -42,8 +41,8 @@ async def _async_update_data(self) -> StromerData: data = [bike_data, self.stromer.bike_id, self.stromer.bike_name] LOGGER.debug("Stromer data %s updated", data) - except Exception as err: - raise ConfigEntryAuthFailed from err except ApiError as err: raise UpdateFailed(f"Error communicating with API: {err}") + except Exception as err: + raise ConfigEntryAuthFailed from err return StromerData(*data) diff --git a/custom_components/stromer/device_tracker.py b/custom_components/stromer/device_tracker.py index 4ceb5a9..d59ec99 100644 --- a/custom_components/stromer/device_tracker.py +++ b/custom_components/stromer/device_tracker.py @@ -43,9 +43,9 @@ def source_type(self) -> SourceType | str: @property def latitude(self) -> float | None: """Return latitude value of the device.""" - return self._coordinator.data.bikedata.get('latitude') + return self._coordinator.data.bikedata.get("latitude") @property def longitude(self) -> float | None: """Return longitude value of the device.""" - return self._coordinator.data.bikedata.get('longitude') + return self._coordinator.data.bikedata.get("longitude") diff --git a/custom_components/stromer/entity.py b/custom_components/stromer/entity.py index 10be940..4776a51 100644 --- a/custom_components/stromer/entity.py +++ b/custom_components/stromer/entity.py @@ -35,11 +35,11 @@ def __init__( name=data.get("nickname"), sw_version=data.get("suiversion"), hw_version=data.get("tntversion"), -# stromer_id=data.get("bike_id"), -# type=data.get("bikemodel"), -# frame_color=data.get("color"), -# frame_size=data.get("size"), -# hardware=data.get("hardware"), + # stromer_id=data.get("bike_id"), + # type=data.get("bikemodel"), + # frame_color=data.get("color"), + # frame_size=data.get("size"), + # hardware=data.get("hardware"), ) self._attr_device_info.update( diff --git a/custom_components/stromer/sensor.py b/custom_components/stromer/sensor.py index 2a8ea87..8a1e200 100644 --- a/custom_components/stromer/sensor.py +++ b/custom_components/stromer/sensor.py @@ -1,12 +1,21 @@ """Stromer Sensor component for Home Assistant.""" from __future__ import annotations -from homeassistant.components.sensor import (SensorDeviceClass, SensorEntity, - SensorEntityDescription, - SensorStateClass) -from homeassistant.const import (ENERGY_WATT_HOUR, LENGTH_KILOMETERS, PERCENTAGE, POWER_WATT, - PRESSURE_BAR, SPEED_KILOMETERS_PER_HOUR, - TEMP_CELSIUS, TIME_SECONDS) +from homeassistant.components.sensor import ( + SensorDeviceClass, + SensorEntity, + SensorEntityDescription, + SensorStateClass, +) +from homeassistant.const import ( + ENERGY_WATT_HOUR, + LENGTH_KILOMETERS, + PERCENTAGE, + PRESSURE_BAR, + SPEED_KILOMETERS_PER_HOUR, + TEMP_CELSIUS, + TIME_SECONDS, +) from homeassistant.helpers.entity import EntityCategory from custom_components.stromer.coordinator import StromerDataUpdateCoordinator @@ -211,6 +220,10 @@ def _ensure_timezone(timestamp: datetime | None) -> datetime | None: def native_value(self): """Return the state of the sensor.""" if self.entity_description.device_class == SensorDeviceClass.TIMESTAMP: - return self._ensure_timezone(datetime.fromtimestamp(int(self._coordinator.data.bikedata.get(self._ent)))) + return self._ensure_timezone( + datetime.fromtimestamp( + int(self._coordinator.data.bikedata.get(self._ent)) + ) + ) return self._coordinator.data.bikedata.get(self._ent) diff --git a/custom_components/stromer/strings.json b/custom_components/stromer/strings.json index baccae9..66b48fa 100644 --- a/custom_components/stromer/strings.json +++ b/custom_components/stromer/strings.json @@ -6,7 +6,7 @@ "description": "Provide your Stromer API details", "data": { "password": "Password", - "username" : "Username", + "username": "Username", "client_id": "Client ID", "client_secret": "Client Secret (optional, not needed if you client id starts with 4P" } diff --git a/custom_components/stromer/stromer.py b/custom_components/stromer/stromer.py index 569a63d..2eebd2d 100644 --- a/custom_components/stromer/stromer.py +++ b/custom_components/stromer/stromer.py @@ -19,10 +19,10 @@ def __init__(self, username, password, client_id, client_secret, timeout=60): self.bike = {} self.status = {} self.position = {} - - self._api_version = 'v4' + + self._api_version = "v4" if client_secret: - self._api_version = 'v3' + self._api_version = "v3" self.base_url = "https://api3.stromer-portal.ch" self._timeout = timeout @@ -44,16 +44,14 @@ async def stromer_connect(self): # Retrieve authorization token await self.stromer_get_code() - # LOGGER.debug("Stromer code: {}".format(self._code)) # Retrieve access token await self.stromer_get_access_token() - # LOGGER.debug("Stromer token: {}".format(self._token)) try: await self.stromer_update() except Exception as e: - LOGGER.error("Stromer unable to update: {}".format(e)) + LOGGER.error(f"Stromer unable to update: {e}") LOGGER.debug("Stromer connected!") @@ -67,35 +65,33 @@ async def stromer_update(self): await self.stromer_connect() attempts += 1 try: - LOGGER.debug("Stromer attempt: {}/10".format(attempts)) + LOGGER.debug(f"Stromer attempt: {attempts}/10") self.bike = await self.stromer_call_api(endpoint="bike/") - LOGGER.debug("Stromer bike: {}".format(self.bike)) + LOGGER.debug(f"Stromer bike: {self.bike}") self.bike_id = self.bike["bikeid"] self.bike_name = self.bike["nickname"] self.bike_model = self.bike["biketype"] endpoint = f"bike/{self.bike_id}/state/" - data = {"cached": "false"} - # LOGGER.debug("Stromer endpoint: {}".format(endpoint)) - self.status = await self.stromer_call_api(endpoint=endpoint, data=data) - LOGGER.debug("Stromer status: {}".format(self.status)) + self.status = await self.stromer_call_api(endpoint=endpoint) + LOGGER.debug(f"Stromer status: {self.status}") endpoint = f"bike/{self.bike_id}/position/" - self.position = await self.stromer_call_api(endpoint=endpoint, data=data) - LOGGER.debug("Stromer position: {}".format(self.position)) + self.position = await self.stromer_call_api(endpoint=endpoint) + LOGGER.debug(f"Stromer position: {self.position}") return except Exception as e: - LOGGER.error("Stromer error: api call failed: {}".format(e)) - LOGGER.debug("Stromer retry: {}/10".format(attempts)) + LOGGER.error(f"Stromer error: api call failed: {e}") + LOGGER.debug(f"Stromer retry: {attempts}/10") LOGGER.error("Stromer error: api call failed 10 times, cowardly failing") raise ApiError async def stromer_get_code(self): url = f"{self.base_url}/mobile/v4/login/" - if self._api_version == 'v3': + if self._api_version == "v3": url = f"{self.base_url}/users/login/" res = await self._websession.get(url) try: @@ -119,11 +115,11 @@ async def stromer_get_code(self): "password": self._password, "username": self._username, "csrfmiddlewaretoken": csrftoken, - "next": "/mobile/v4/o/authorize/?" + qs + "next": "/mobile/v4/o/authorize/?" + qs, } - if self._api_version == 'v3': - data["next"]= "/o/authorize/?" + qs + if self._api_version == "v3": + data["next"] = "/o/authorize/?" + qs res = await self._websession.post( url, data=data, headers=dict(Referer=url), allow_redirects=False @@ -143,7 +139,7 @@ async def stromer_get_access_token(self): "redirect_uri": "stromer://auth", } - if self._api_version == 'v3': + if self._api_version == "v3": url = f"{self.base_url}/o/token/" data["client_secret"] = self._client_secret data["redirect_uri"] = "stromerauth://auth" @@ -152,19 +148,18 @@ async def stromer_get_access_token(self): token = json.loads(await res.text()) self._token = token["access_token"] - async def stromer_call_api(self, endpoint, data={}): + async def stromer_call_api(self, endpoint): url = f"{self.base_url}/rapi/mobile/v4.1/{endpoint}" - if self._api_version == 'v3': + if self._api_version == "v3": url = f"{self.base_url}/rapi/mobile/v2/{endpoint}" headers = {"Authorization": f"Bearer {self._token}"} - # LOGGER.debug("token %s" % self._token) res = await self._websession.get(url, headers=headers, data={}) ret = json.loads(await res.text()) - # LOGGER.debug("ret %s" % ret) - # LOGGER.debug("res status %s" % res.status) + LOGGER.debug("API call status: %s" % res.status) + LOGGER.debug("API call returns: %s" % ret) return ret["data"][0] + class ApiError(Exception): """Error to indicate something wrong with the API.""" - diff --git a/custom_components/stromer/translations/en.json b/custom_components/stromer/translations/en.json index 8fc3aa2..f7d16bd 100644 --- a/custom_components/stromer/translations/en.json +++ b/custom_components/stromer/translations/en.json @@ -6,7 +6,7 @@ "description": "Provide your Stromer API details", "data": { "password": "Password", - "username" : "Username", + "username": "Username", "client_id": "Client ID", "client_secret": "Client Secret (optional, not needed if your Client ID starts with 4P" } diff --git a/custom_components/stromer/translations/nl.json b/custom_components/stromer/translations/nl.json index 7e0bc24..862ee06 100644 --- a/custom_components/stromer/translations/nl.json +++ b/custom_components/stromer/translations/nl.json @@ -6,7 +6,7 @@ "description": "Stromer API gegevens", "data": { "password": "Wachtwoord", - "username" : "Gebruikersnaam", + "username": "Gebruikersnaam", "client_id": "Client ID", "client_secret": "Client Secret (optioneel, niet nodig als je client id met 4P begint" } diff --git a/renovate.json b/renovate.json index ac3c9bf..7730d28 100644 --- a/renovate.json +++ b/renovate.json @@ -1,17 +1,13 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:base", - ":dependencyDashboard", - "schedule:weekly" - ], + "extends": ["config:base", ":dependencyDashboard", "schedule:weekly"], "packageRules": [ { "matchManagers": ["github-actions"], "automerge": true }, { - "matchManagers": ["pip_requirements","poetry","setup-cfg"], + "matchManagers": ["pip_requirements", "poetry", "setup-cfg"], "automerge": true }, { @@ -20,4 +16,3 @@ } ] } -