Skip to content

Commit a8acba1

Browse files
author
Jan Thunqvist
committed
Add more tests. More CodeRabbit suggestions.
1 parent f9b286d commit a8acba1

File tree

6 files changed

+1375
-33
lines changed

6 files changed

+1375
-33
lines changed

custom_components/ocpp/chargepoint.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -409,9 +409,11 @@ async def unlock(self, connector_id: int = 1) -> bool:
409409
return False
410410

411411
async def update_firmware(self, firmware_url: str, wait_time: int = 0):
412-
"""Update charger with new firmware if available."""
413-
"""where firmware_url is the http or https url of the new firmware"""
414-
"""and wait_time is hours from now to wait before install"""
412+
"""Update charger with new firmware if available.
413+
414+
- firmware_url is the http or https url of the new firmware
415+
- wait_time is hours from now to wait before install
416+
"""
415417
pass
416418

417419
async def get_diagnostics(self, upload_url: str):

custom_components/ocpp/ocppv16.py

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -283,17 +283,10 @@ async def clear_profile(
283283
purpose: ChargingProfilePurposeType | None = None,
284284
) -> bool:
285285
"""Clear charging profiles (per connector and/or purpose)."""
286-
criteria = {}
287-
if purpose is not None:
288-
criteria["charging_profile_purpose"] = purpose.value
289-
290-
target_connector = None
291-
if conn_id is not None:
292-
target_connector = int(conn_id)
293-
286+
target_connector = int(conn_id) if conn_id is not None else None
294287
req = call.ClearChargingProfile(
295288
connector_id=target_connector,
296-
charging_profile_purpose=criteria if criteria else None,
289+
charging_profile_purpose=purpose.value if purpose is not None else None,
297290
)
298291
resp = await self.call(req)
299292
if resp.status in (
@@ -492,40 +485,58 @@ async def unlock(self, connector_id: int = 1):
492485
return False
493486

494487
async def update_firmware(self, firmware_url: str, wait_time: int = 0):
495-
"""Update charger with new firmware if available."""
496-
"""where firmware_url is the http or https url of the new firmware"""
497-
"""and wait_time is hours from now to wait before install"""
498-
if prof.FW in self._attr_supported_features:
499-
schema = vol.Schema(vol.Url())
500-
try:
501-
url = schema(firmware_url)
502-
except vol.MultipleInvalid as e:
503-
_LOGGER.debug("Failed to parse url: %s", e)
504-
update_time = (datetime.now(tz=UTC) + timedelta(hours=wait_time)).strftime(
505-
"%Y-%m-%dT%H:%M:%SZ"
506-
)
507-
req = call.UpdateFirmware(location=url, retrieve_date=update_time)
488+
"""Update charger with new firmware if available.
489+
490+
- firmware_url: http/https URL of the new firmware
491+
- wait_time: hours from now to wait before install
492+
"""
493+
features = int(self._attr_supported_features or 0)
494+
if not (features & prof.FW):
495+
_LOGGER.warning("Charger does not support OCPP firmware updating")
496+
return False
497+
498+
schema = vol.Schema(vol.Url())
499+
try:
500+
url = schema(firmware_url)
501+
except vol.MultipleInvalid as e:
502+
_LOGGER.warning("Failed to parse url: %s", e)
503+
return False
504+
505+
try:
506+
retrieve_time = (
507+
datetime.now(tz=UTC) + timedelta(hours=max(0, int(wait_time or 0)))
508+
).strftime("%Y-%m-%dT%H:%M:%SZ")
509+
except Exception:
510+
retrieve_time = datetime.now(tz=UTC).strftime("%Y-%m-%dT%H:%M:%SZ")
511+
512+
try:
513+
req = call.UpdateFirmware(location=str(url), retrieve_date=retrieve_time)
508514
resp = await self.call(req)
509-
_LOGGER.info("Response: %s", resp)
515+
_LOGGER.info("UpdateFirmware response: %s", resp)
510516
return True
511-
else:
512-
_LOGGER.warning("Charger does not support ocpp firmware updating")
517+
except Exception as e:
518+
_LOGGER.error("UpdateFirmware failed: %s", e)
513519
return False
514520

515521
async def get_diagnostics(self, upload_url: str):
516522
"""Upload diagnostic data to server from charger."""
517-
if prof.FW in self._attr_supported_features:
523+
features = int(self._attr_supported_features or 0)
524+
if features & prof.FW:
518525
schema = vol.Schema(vol.Url())
519526
try:
520527
url = schema(upload_url)
521528
except vol.MultipleInvalid as e:
522529
_LOGGER.warning("Failed to parse url: %s", e)
523-
req = call.GetDiagnostics(location=url)
530+
return
531+
req = call.GetDiagnostics(location=str(url))
524532
resp = await self.call(req)
525533
_LOGGER.info("Response: %s", resp)
526534
return True
527535
else:
528-
_LOGGER.warning("Charger does not support ocpp diagnostics uploading")
536+
_LOGGER.debug(
537+
"Charger %s does not support ocpp diagnostics uploading",
538+
self.id,
539+
)
529540
return False
530541

531542
async def data_transfer(self, vendor_id: str, message_id: str = "", data: str = ""):

custom_components/ocpp/ocppv201.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class ChargePoint(cp):
8080

8181
_inventory: InventoryReport | None = None
8282
_wait_inventory: asyncio.Event | None = None
83-
_connector_status: list[list[ConnectorStatusEnumType | None]] = []
83+
_connector_status: list[list[ConnectorStatusEnumType | None]]
8484
_tx_start_time: dict[int, datetime]
8585
_global_to_evse: dict[int, tuple[int, int]] # global_idx -> (evse_id, connector_id)
8686
_evse_to_global: dict[tuple[int, int], int] # (evse_id, connector_id) -> global_idx
@@ -112,6 +112,7 @@ def __init__(
112112
self._global_to_evse: dict[int, tuple[int, int]] = {}
113113
self._evse_to_global: dict[tuple[int, int], int] = {}
114114
self._pending_status_notifications: list[tuple[str, str, int, int]] = []
115+
self._connector_status = []
115116

116117
# --- Connector mapping helpers (EVSE <-> global index) ---
117118
def _build_connector_map(self) -> bool:

custom_components/ocpp/switch.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ def is_on(self) -> bool:
165165
)
166166
if self.entity_description.metric_condition is not None:
167167
self._state = resp in self.entity_description.metric_condition
168+
else:
169+
self._state = bool(resp)
168170
return self._state
169171

170172
async def async_turn_on(self, **kwargs):

0 commit comments

Comments
 (0)