From 5bd31f7d839f3d0b4e5e25793f3e774ecd0332a2 Mon Sep 17 00:00:00 2001 From: lbbrhzn <8673442+lbbrhzn@users.noreply.github.com> Date: Sun, 8 Sep 2024 21:43:47 +0200 Subject: [PATCH] use ruff in pre-commit for linting and formatting (#1314) * ruff fixes * fix linting SIM105 * update ruff taget verdion to py312 * enable ruff in vs code * remove black/flake/etc --- .github/workflows/constraints.txt | 5 -- .pre-commit-config.yaml | 43 +++------------- .ruff.toml | 13 ++--- .vscode/settings.json | 5 +- custom_components/ocpp/api.py | 48 ++++++++--------- custom_components/ocpp/button.py | 1 + custom_components/ocpp/config_flow.py | 1 + custom_components/ocpp/const.py | 1 + custom_components/ocpp/enums.py | 1 + custom_components/ocpp/exception.py | 2 +- custom_components/ocpp/number.py | 1 + custom_components/ocpp/sensor.py | 3 +- custom_components/ocpp/switch.py | 1 + docs/conf.py | 2 +- manage/update_manifest.py | 1 + tests/conftest.py | 17 +++--- tests/const.py | 1 + tests/test_charge_point.py | 74 ++++++++++----------------- tests/test_config_flow.py | 16 +++--- tests/test_init.py | 3 +- 20 files changed, 102 insertions(+), 137 deletions(-) diff --git a/.github/workflows/constraints.txt b/.github/workflows/constraints.txt index ac5c64bf..646c8a93 100644 --- a/.github/workflows/constraints.txt +++ b/.github/workflows/constraints.txt @@ -1,11 +1,6 @@ # home assistant pip>=21.0,<24.3 pre-commit==3.8.0 -bandit==1.7.9 -black==24.8.0 -flake8==7.1.1 -isort==5.13.2 pre-comit-hooks==4.1.0 pyupgrade==3.17.0 -reorder-python-imports==3.13.0 sqlalchemy>=1.4.23 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a81bd6c5..e658f46a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,44 +4,13 @@ repos: hooks: - id: pyupgrade args: [--py37-plus] - - repo: https://github.com/psf/black - rev: 23.11.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.6.4 hooks: - - id: black - args: - - --safe - - --quiet - files: ^((custom_components|homeassistant|script|tests)/.+)?[^/]+\.py$ - - repo: https://github.com/codespell-project/codespell - rev: v2.2.6 - hooks: - - id: codespell - args: - - --ignore-words-list=hass,alot,datas,dof,dur,farenheit,hist,iff,ines,ist,lightsensor,mut,nd,pres,referer,ser,serie,te,technik,ue,uint,visability,wan,wanna,withing - - --skip="./.*,*.csv,*.json" - - --quiet-level=2 - exclude_types: [csv, json] - - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 - hooks: - - id: flake8 - additional_dependencies: - - flake8-docstrings==1.5.0 - - pydocstyle==5.0.2 - files: ^(custom_components|homeassistant|script|tests)/.+\.py$ - - repo: https://github.com/PyCQA/bandit - rev: 1.7.5 - hooks: - - id: bandit - args: - - --quiet - - --format=custom - - --configfile=bandit.yaml - files: ^(custom_components|homeassistant|script|tests|)/.+\.py$ - - repo: https://github.com/PyCQA/isort - rev: 5.12.0 - hooks: - - id: isort + # Run the linter. + - id: ruff + # Run the formatter. + - id: ruff-format - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 hooks: diff --git a/.ruff.toml b/.ruff.toml index 7a8331a3..3f7141ff 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -1,8 +1,8 @@ # The contents of this file is based on https://github.com/home-assistant/core/blob/dev/pyproject.toml -target-version = "py310" +target-version = "py312" -select = [ +lint.select = [ "B007", # Loop control variable {name} not used within loop body "B014", # Exception handler with duplicate exception "C", # complexity @@ -26,7 +26,8 @@ select = [ "W", # pycodestyle ] -ignore = [ +lint.ignore = [ + "C901", # function too complex "D202", # No blank lines allowed after function docstring "D203", # 1 blank line required before class docstring "D213", # Multi-line docstring summary should start at the second line @@ -38,11 +39,11 @@ ignore = [ "E731", # do not assign a lambda expression, use a def ] -[flake8-pytest-style] +[lint.flake8-pytest-style] fixture-parentheses = false -[pyupgrade] +[lint.pyupgrade] keep-runtime-typing = true -[mccabe] +[lint.mccabe] max-complexity = 25 \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 531dc634..fbfb5bf6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,9 @@ { - "python.linting.pylintEnabled": true, "python.linting.enabled": true, + "python.linting.enabledWithoutWorkspace": true, + "python.linting.lintOnSave": true, + "python.linting.pylintEnabled": true, + "python.linting.ruffEnabled": true, "python.pythonPath": "/usr/local/bin/python", "python.analysis.extraPaths": [ "/usr/local/lib/python3.9/site-packages" diff --git a/custom_components/ocpp/api.py b/custom_components/ocpp/api.py index 60b026e8..91d953c5 100644 --- a/custom_components/ocpp/api.py +++ b/custom_components/ocpp/api.py @@ -1,9 +1,10 @@ """Representation of a OCCP Entities.""" + from __future__ import annotations import asyncio from collections import defaultdict -from datetime import datetime, timedelta, timezone +from datetime import datetime, timedelta, UTC import json import logging from math import sqrt @@ -784,8 +785,7 @@ async def start_transaction(self): return False async def stop_transaction(self): - """ - Request remote stop of current transaction. + """Request remote stop of current transaction. Leaves charger in finishing state until unplugged. Use reset() to make the charger available again for remote start @@ -836,9 +836,9 @@ async def update_firmware(self, firmware_url: str, wait_time: int = 0): url = schema(firmware_url) except vol.MultipleInvalid as e: _LOGGER.debug("Failed to parse url: %s", e) - update_time = ( - datetime.now(tz=timezone.utc) + timedelta(hours=wait_time) - ).strftime("%Y-%m-%dT%H:%M:%SZ") + update_time = (datetime.now(tz=UTC) + timedelta(hours=wait_time)).strftime( + "%Y-%m-%dT%H:%M:%SZ" + ) req = call.UpdateFirmware(location=url, retrieve_date=update_time) resp = await self.call(req) _LOGGER.info("Response: %s", resp) @@ -875,9 +875,7 @@ async def data_transfer(self, vendor_id: str, message_id: str = "", data: str = data, resp.data, ) - self._metrics[cdet.data_response.value].value = datetime.now( - tz=timezone.utc - ) + self._metrics[cdet.data_response.value].value = datetime.now(tz=UTC) self._metrics[cdet.data_response.value].extra_attr = {message_id: resp.data} return True else: @@ -897,9 +895,7 @@ async def get_configuration(self, key: str = ""): if resp.configuration_key: value = resp.configuration_key[0][om.value.value] _LOGGER.debug("Get Configuration for %s: %s", key, value) - self._metrics[cdet.config_response.value].value = datetime.now( - tz=timezone.utc - ) + self._metrics[cdet.config_response.value].value = datetime.now(tz=UTC) self._metrics[cdet.config_response.value].extra_attr = {key: value} return value if resp.unknown_key: @@ -994,7 +990,7 @@ async def monitor_connection(self): self._metrics[cstat.latency_ping.value].value = latency_ping self._metrics[cstat.latency_pong.value].value = latency_pong - except asyncio.TimeoutError as timeout_exception: + except TimeoutError as timeout_exception: _LOGGER.debug( f"Connection latency from '{self.central.csid}' to '{self.id}': ping={latency_ping} ms, pong={latency_pong} ms", ) @@ -1027,7 +1023,7 @@ async def run(self, tasks): self.tasks = [asyncio.ensure_future(task) for task in tasks] try: await asyncio.gather(*self.tasks) - except asyncio.TimeoutError: + except TimeoutError: pass except websockets.exceptions.WebSocketException as websocket_exception: _LOGGER.debug(f"Connection closed to '{self.id}': {websocket_exception}") @@ -1258,9 +1254,9 @@ def on_meter_values(self, connector_id: int, meter_value: dict, **kwargs): self._metrics[measurand].value = float(value) self._metrics[measurand].unit = unit if location is not None: - self._metrics[measurand].extra_attr[ - om.location.value - ] = location + self._metrics[measurand].extra_attr[om.location.value] = ( + location + ) if context is not None: self._metrics[measurand].extra_attr[om.context.value] = context processed_keys.append(idx) @@ -1295,7 +1291,7 @@ def on_meter_values(self, connector_id: int, meter_value: dict, **kwargs): def on_boot_notification(self, **kwargs): """Handle a boot notification.""" resp = call_result.BootNotification( - current_time=datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), + current_time=datetime.now(tz=UTC).strftime("%Y-%m-%dT%H:%M:%SZ"), interval=3600, status=RegistrationStatus.accepted.value, ) @@ -1333,12 +1329,12 @@ def on_status_notification(self, connector_id, error_code, status, **kwargs): self._metrics[cstat.status_connector.value].value = status self._metrics[cstat.error_code_connector.value].value = error_code if connector_id >= 1: - self._metrics[cstat.status_connector.value].extra_attr[ - connector_id - ] = status - self._metrics[cstat.error_code_connector.value].extra_attr[ - connector_id - ] = error_code + self._metrics[cstat.status_connector.value].extra_attr[connector_id] = ( + status + ) + self._metrics[cstat.error_code_connector.value].extra_attr[connector_id] = ( + error_code + ) if ( status == ChargePointStatus.suspended_ev.value or status == ChargePointStatus.suspended_evse.value @@ -1489,14 +1485,14 @@ def on_stop_transaction(self, meter_stop, timestamp, transaction_id, **kwargs): def on_data_transfer(self, vendor_id, **kwargs): """Handle a Data transfer request.""" _LOGGER.debug("Data transfer received from %s: %s", self.id, kwargs) - self._metrics[cdet.data_transfer.value].value = datetime.now(tz=timezone.utc) + self._metrics[cdet.data_transfer.value].value = datetime.now(tz=UTC) self._metrics[cdet.data_transfer.value].extra_attr = {vendor_id: kwargs} return call_result.DataTransfer(status=DataTransferStatus.accepted.value) @on(Action.heartbeat) def on_heartbeat(self, **kwargs): """Handle a Heartbeat.""" - now = datetime.now(tz=timezone.utc) + now = datetime.now(tz=UTC) self._metrics[cstat.heartbeat.value].value = now self.hass.async_create_task(self.central.update(self.central.cpid)) return call_result.Heartbeat(current_time=now.strftime("%Y-%m-%dT%H:%M:%SZ")) diff --git a/custom_components/ocpp/button.py b/custom_components/ocpp/button.py index 043e4d85..cc60bd71 100644 --- a/custom_components/ocpp/button.py +++ b/custom_components/ocpp/button.py @@ -1,4 +1,5 @@ """Button platform for ocpp.""" + from __future__ import annotations from dataclasses import dataclass diff --git a/custom_components/ocpp/config_flow.py b/custom_components/ocpp/config_flow.py index 07c421b7..65b13bb0 100644 --- a/custom_components/ocpp/config_flow.py +++ b/custom_components/ocpp/config_flow.py @@ -1,4 +1,5 @@ """Adds config flow for ocpp.""" + from homeassistant import config_entries import voluptuous as vol diff --git a/custom_components/ocpp/const.py b/custom_components/ocpp/const.py index 1b066464..d8dce89f 100644 --- a/custom_components/ocpp/const.py +++ b/custom_components/ocpp/const.py @@ -1,4 +1,5 @@ """Define constants for OCPP integration.""" + import pathlib import homeassistant.components.input_number as input_number diff --git a/custom_components/ocpp/enums.py b/custom_components/ocpp/enums.py index 67f625f9..bc3b5ccb 100644 --- a/custom_components/ocpp/enums.py +++ b/custom_components/ocpp/enums.py @@ -1,4 +1,5 @@ """Additional enumerated values to use in home assistant.""" + from enum import Enum, Flag, auto diff --git a/custom_components/ocpp/exception.py b/custom_components/ocpp/exception.py index fe2cb5d8..f98426b6 100644 --- a/custom_components/ocpp/exception.py +++ b/custom_components/ocpp/exception.py @@ -1 +1 @@ -""" This file is imported by home assistant, and can be used to define custom exceptions.""" +"""This file is imported by home assistant, and can be used to define custom exceptions.""" diff --git a/custom_components/ocpp/number.py b/custom_components/ocpp/number.py index 0c60a526..d2aa6ef5 100644 --- a/custom_components/ocpp/number.py +++ b/custom_components/ocpp/number.py @@ -1,4 +1,5 @@ """Number platform for ocpp.""" + from __future__ import annotations from dataclasses import dataclass diff --git a/custom_components/ocpp/sensor.py b/custom_components/ocpp/sensor.py index 4571fa37..536f2b0a 100644 --- a/custom_components/ocpp/sensor.py +++ b/custom_components/ocpp/sensor.py @@ -1,4 +1,5 @@ """Sensor platform for ocpp.""" + from __future__ import annotations from dataclasses import dataclass @@ -162,7 +163,7 @@ def device_class(self): Measurand.rpm, ] or self.metric.lower().startswith("frequency"): device_class = SensorDeviceClass.FREQUENCY - elif self.metric.lower().startswith(tuple(["power.a", "power.o", "power.r"])): + elif self.metric.lower().startswith(("power.a", "power.o", "power.r")): device_class = SensorDeviceClass.POWER elif self.metric.lower().startswith("temperature."): device_class = SensorDeviceClass.TEMPERATURE diff --git a/custom_components/ocpp/switch.py b/custom_components/ocpp/switch.py index 7f613946..f46f6adc 100644 --- a/custom_components/ocpp/switch.py +++ b/custom_components/ocpp/switch.py @@ -1,4 +1,5 @@ """Switch platform for ocpp.""" + from __future__ import annotations from dataclasses import dataclass diff --git a/docs/conf.py b/docs/conf.py index 02224c43..fb30111d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,4 +1,4 @@ -# Configuration file for the Sphinx documentation builder. +"""Configuration file for the Sphinx documentation builder.""" # -- Project information diff --git a/manage/update_manifest.py b/manage/update_manifest.py index 55208c3d..f52f7761 100644 --- a/manage/update_manifest.py +++ b/manage/update_manifest.py @@ -1,4 +1,5 @@ """Update the manifest file.""" + # https://github.com/hacs/integration/blob/main/manage/update_manifest.py import json import os diff --git a/tests/conftest.py b/tests/conftest.py index c9153a46..390bc87b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,5 @@ """Global fixtures for ocpp integration.""" + import asyncio from unittest.mock import patch @@ -20,9 +21,11 @@ def auto_enable_custom_integrations(enable_custom_integrations): @pytest.fixture(name="skip_notifications", autouse=True) def skip_notifications_fixture(): """Skip notification calls.""" - with patch("homeassistant.components.persistent_notification.async_create"), patch( - "homeassistant.components.persistent_notification.async_dismiss" - ), patch("custom_components.ocpp.api.ChargePoint.notify_ha"): + with ( + patch("homeassistant.components.persistent_notification.async_create"), + patch("homeassistant.components.persistent_notification.async_dismiss"), + patch("custom_components.ocpp.api.ChargePoint.notify_ha"), + ): yield @@ -33,9 +36,11 @@ def bypass_get_data_fixture(): """Skip calls to get data from API.""" future = asyncio.Future() future.set_result(websockets.WebSocketServer) - with patch("websockets.server.serve", return_value=future), patch( - "websockets.server.WebSocketServer.close" - ), patch("websockets.server.WebSocketServer.wait_closed"): + with ( + patch("websockets.server.serve", return_value=future), + patch("websockets.server.WebSocketServer.close"), + patch("websockets.server.WebSocketServer.wait_closed"), + ): yield diff --git a/tests/const.py b/tests/const.py index a5c52024..7acb1d5d 100644 --- a/tests/const.py +++ b/tests/const.py @@ -1,4 +1,5 @@ """Constants for ocpp tests.""" + from custom_components.ocpp.const import ( CONF_CPID, CONF_CSID, diff --git a/tests/test_charge_point.py b/tests/test_charge_point.py index f67df6f3..52a2ff2a 100644 --- a/tests/test_charge_point.py +++ b/tests/test_charge_point.py @@ -1,6 +1,7 @@ """Implement a test by a simulating a chargepoint.""" + import asyncio -from datetime import datetime, timezone # timedelta, +from datetime import datetime, UTC # timedelta, from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN from homeassistant.components.button.const import SERVICE_PRESS @@ -42,6 +43,7 @@ ) from .const import MOCK_CONFIG_DATA, MOCK_CONFIG_DATA_2 +import contextlib @pytest.mark.timeout(90) # Set timeout for this test @@ -167,7 +169,7 @@ async def test_services(hass, socket_enabled): ) as ws2: # use a different id for debugging cp2 = ChargePoint("CP_1_no_subprotocol", ws2) - try: + with contextlib.suppress(asyncio.TimeoutError): await asyncio.wait_for( asyncio.gather( cp2.start(), @@ -183,8 +185,6 @@ async def test_services(hass, socket_enabled): ), timeout=5, ) - except asyncio.TimeoutError: - pass await ws2.close() await asyncio.sleep(1) if entry := hass.config_entries.async_get_entry(config_entry2.entry_id): @@ -207,7 +207,7 @@ async def test_services(hass, socket_enabled): ) as ws: # use a different id for debugging cp = ChargePoint("CP_1_no_subprotocol", ws) - try: + with contextlib.suppress(websockets.exceptions.ConnectionClosedOK): await asyncio.wait_for( asyncio.gather( cp.start(), @@ -223,8 +223,6 @@ async def test_services(hass, socket_enabled): ), timeout=5, ) - except websockets.exceptions.ConnectionClosedOK: - pass await ws.close() await asyncio.sleep(1) @@ -236,7 +234,7 @@ async def test_services(hass, socket_enabled): ) as ws: # use a different id for debugging cp = ChargePoint("CP_1_unsupported_subprotocol", ws) - try: + with contextlib.suppress(websockets.exceptions.ConnectionClosedOK): await asyncio.wait_for( asyncio.gather( cp.start(), @@ -252,8 +250,6 @@ async def test_services(hass, socket_enabled): ), timeout=5, ) - except websockets.exceptions.ConnectionClosedOK: - pass await ws.close() await asyncio.sleep(1) @@ -267,7 +263,7 @@ async def test_services(hass, socket_enabled): cp = ChargePoint("CP_1_restore_values", ws) cp.active_transactionId = None # send None values - try: + with contextlib.suppress(asyncio.TimeoutError): await asyncio.wait_for( asyncio.gather( cp.start(), @@ -275,13 +271,11 @@ async def test_services(hass, socket_enabled): ), timeout=5, ) - except asyncio.TimeoutError: - pass # check if None assert cs.get_metric("test_cpid", "Energy.Meter.Start") is None assert cs.get_metric("test_cpid", "Transaction.Id") is None # send new data - try: + with contextlib.suppress(asyncio.TimeoutError): await asyncio.wait_for( asyncio.gather( cp.send_start_transaction(12344), @@ -289,8 +283,6 @@ async def test_services(hass, socket_enabled): ), timeout=5, ) - except asyncio.TimeoutError: - pass # save for reference the values for meter_start and transaction_id saved_meter_start = int(cs.get_metric("test_cpid", "Energy.Meter.Start")) saved_transactionId = int(cs.get_metric("test_cpid", "Transaction.Id")) @@ -298,15 +290,13 @@ async def test_services(hass, socket_enabled): cs.del_metric("test_cpid", "Energy.Meter.Start") cs.del_metric("test_cpid", "Transaction.Id") # send new data - try: + with contextlib.suppress(asyncio.TimeoutError): await asyncio.wait_for( asyncio.gather( cp.send_meter_periodic_data(), ), timeout=5, ) - except asyncio.TimeoutError: - pass await ws.close() # check if restored old values from HA when api have lost the values, i.e. simulated reboot of HA @@ -322,7 +312,7 @@ async def test_services(hass, socket_enabled): ) as ws: # use a different id for debugging cp = ChargePoint("CP_1_normal", ws) - try: + with contextlib.suppress(asyncio.TimeoutError): await asyncio.wait_for( asyncio.gather( cp.start(), @@ -342,8 +332,6 @@ async def test_services(hass, socket_enabled): ), timeout=5, ) - except asyncio.TimeoutError: - pass await ws.close() assert int(cs.get_metric("test_cpid", "Energy.Active.Import.Register")) == int( 1305570 / 1000 @@ -351,13 +339,13 @@ async def test_services(hass, socket_enabled): assert int(cs.get_metric("test_cpid", "Energy.Session")) == int( (54321 - 12345) / 1000 ) - assert int(cs.get_metric("test_cpid", "Current.Import")) == int(0) - assert int(cs.get_metric("test_cpid", "Voltage")) == int(228) + assert int(cs.get_metric("test_cpid", "Current.Import")) == 0 + assert int(cs.get_metric("test_cpid", "Voltage")) == 228 assert cs.get_unit("test_cpid", "Energy.Active.Import.Register") == "kWh" assert cs.get_metric("unknown_cpid", "Energy.Active.Import.Register") is None assert cs.get_unit("unknown_cpid", "Energy.Active.Import.Register") is None assert cs.get_extra_attr("unknown_cpid", "Energy.Active.Import.Register") is None - assert int(cs.get_supported_features("unknown_cpid")) == int(0) + assert int(cs.get_supported_features("unknown_cpid")) == 0 assert ( await asyncio.wait_for( cs.set_max_charge_rate_amps("unknown_cpid", 0), timeout=1 @@ -381,7 +369,7 @@ async def test_services(hass, socket_enabled): subprotocols=["ocpp1.6"], ) as ws: cp = ChargePoint("CP_1_services", ws) - try: + with contextlib.suppress(asyncio.TimeoutError): await asyncio.wait_for( asyncio.gather( cp.start(), @@ -394,12 +382,10 @@ async def test_services(hass, socket_enabled): ), timeout=5, ) - except asyncio.TimeoutError: - pass await ws.close() - assert int(cs.get_metric("test_cpid", "Frequency")) == int(50) - assert float(cs.get_metric("test_cpid", "Energy.Active.Import.Register")) == float( - 1101.452 + assert int(cs.get_metric("test_cpid", "Frequency")) == 50 + assert ( + float(cs.get_metric("test_cpid", "Energy.Active.Import.Register")) == 1101.452 ) await asyncio.sleep(1) @@ -413,7 +399,7 @@ async def test_services(hass, socket_enabled): ) as ws: # use a different id for debugging cp = ChargePoint("CP_1_non_errata_3.9", ws) - try: + with contextlib.suppress(asyncio.TimeoutError): await asyncio.wait_for( asyncio.gather( cp.start(), @@ -425,8 +411,6 @@ async def test_services(hass, socket_enabled): ), timeout=5, ) - except asyncio.TimeoutError: - pass await ws.close() # Last sent "Energy.Active.Import.Register" value without transaction id should be here. @@ -448,7 +432,7 @@ async def test_services(hass, socket_enabled): ) as ws: # use a different id for debugging cp = ChargePoint("CP_1_non_errata_3.9", ws) - try: + with contextlib.suppress(asyncio.TimeoutError): await asyncio.wait_for( asyncio.gather( cp.start(), @@ -460,12 +444,10 @@ async def test_services(hass, socket_enabled): ), timeout=5, ) - except asyncio.TimeoutError: - pass await ws.close() - assert int(cs.get_metric("test_cpid", "Energy.Active.Import.Register")) == int(1101) - assert int(cs.get_metric("test_cpid", "Energy.Session")) == int(11) + assert int(cs.get_metric("test_cpid", "Energy.Active.Import.Register")) == 1101 + assert int(cs.get_metric("test_cpid", "Energy.Session")) == 11 assert cs.get_unit("test_cpid", "Energy.Active.Import.Register") == "kWh" # test ocpp rejection messages sent from charger to cms @@ -489,7 +471,7 @@ async def test_services(hass, socket_enabled): ), timeout=3, ) - except asyncio.TimeoutError: + except TimeoutError: pass except websockets.exceptions.ConnectionClosedOK: pass @@ -647,7 +629,7 @@ def on_reset(self, **kwargs): def on_remote_start_transaction(self, **kwargs): """Handle remote start request.""" if self.accept is True: - asyncio.create_task(self.send_start_transaction()) + self.task = asyncio.create_task(self.send_start_transaction()) return call_result.RemoteStartTransaction(RemoteStartStopStatus.accepted) else: return call_result.RemoteStopTransaction(RemoteStartStopStatus.rejected) @@ -750,7 +732,7 @@ async def send_start_transaction(self, meter_start: int = 12345): connector_id=1, id_tag="test_cp", meter_start=meter_start, - timestamp=datetime.now(tz=timezone.utc).isoformat(), + timestamp=datetime.now(tz=UTC).isoformat(), ) resp = await self.call(request) self.active_transactionId = resp.transaction_id @@ -762,7 +744,7 @@ async def send_status_notification(self): connector_id=0, error_code=ChargePointErrorCode.no_error, status=ChargePointStatus.suspended_ev, - timestamp=datetime.now(tz=timezone.utc).isoformat(), + timestamp=datetime.now(tz=UTC).isoformat(), info="Test info", vendor_id="The Mobility House", vendor_error_code="Test error", @@ -772,7 +754,7 @@ async def send_status_notification(self): connector_id=1, error_code=ChargePointErrorCode.no_error, status=ChargePointStatus.charging, - timestamp=datetime.now(tz=timezone.utc).isoformat(), + timestamp=datetime.now(tz=UTC).isoformat(), info="Test info", vendor_id="The Mobility House", vendor_error_code="Test error", @@ -782,7 +764,7 @@ async def send_status_notification(self): connector_id=2, error_code=ChargePointErrorCode.no_error, status=ChargePointStatus.available, - timestamp=datetime.now(tz=timezone.utc).isoformat(), + timestamp=datetime.now(tz=UTC).isoformat(), info="Test info", vendor_id="The Mobility House", vendor_error_code="Available", @@ -1118,7 +1100,7 @@ async def send_stop_transaction(self, delay: int = 0): n += 1 request = call.StopTransaction( meter_stop=54321, - timestamp=datetime.now(tz=timezone.utc).isoformat(), + timestamp=datetime.now(tz=UTC).isoformat(), transaction_id=self.active_transactionId, reason="EVDisconnected", id_tag="test_cp", diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index 1e0af0fa..e2350dd6 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -1,4 +1,5 @@ """Test ocpp config flow.""" + from unittest.mock import patch from homeassistant import config_entries, data_entry_flow @@ -19,12 +20,15 @@ @pytest.fixture(autouse=True) def bypass_setup_fixture(): """Prevent setup.""" - with patch( - "custom_components.ocpp.async_setup", - return_value=True, - ), patch( - "custom_components.ocpp.async_setup_entry", - return_value=True, + with ( + patch( + "custom_components.ocpp.async_setup", + return_value=True, + ), + patch( + "custom_components.ocpp.async_setup_entry", + return_value=True, + ), ): yield diff --git a/tests/test_init.py b/tests/test_init.py index 6753bd9b..0c6dd6c0 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -1,7 +1,8 @@ """Test ocpp setup process.""" + # from homeassistant.exceptions import ConfigEntryNotReady # import pytest -from typing import AsyncGenerator +from collections.abc import AsyncGenerator from homeassistant.core import HomeAssistant from pytest_homeassistant_custom_component.common import MockConfigEntry