feat: add refresh_slots action for lightweight express-slot polling#68
Open
MangelSpec wants to merge 2 commits into
Open
feat: add refresh_slots action for lightweight express-slot polling#68MangelSpec wants to merge 2 commits into
MangelSpec wants to merge 2 commits into
Conversation
- tests/test_order_store.py: re-indent the persistence and dedup asserts back inside the TemporaryDirectory block so the temp file still exists when written, and drop the redundant manual cleanup the context manager already handles (the test raised FileNotFoundError before) - rohlik_api.py: remove the duplicate login() call in search_product, which authenticated twice on every search - services.py: fix the doubled word in the "get get cart content" error message - hub.py: drop the unused cast and List typing imports - sensor.py: remove the dead, shadowed "import datetime" (the name is rebound by "from datetime import ... datetime") - errors.py: fix APIRequestFailedError docstring, which was copied verbatim from AddressNotSetError - todo.py: complete the truncated add-to-cart error log and lower the successful-delete log from error to debug level
- rohlik_api.py: add get_timeslots() that fetches only the timeslot endpoint, plus a reusable logged-in session (_ensure_session) that re-authenticates only on HTTP 401, so a slot check is a single request instead of login + GET + logout - rohlik_api.py: serialize access to the reused session with an asyncio.Lock and add close_session(); get_data() stays stateless to avoid sharing a Session across the slow full refresh and the fast poll - hub.py: add RohlikAccount.refresh_slots(), which merges into self.data (does not replace it) and publishes updates so the express binary sensor refreshes without a full data cycle; add async_close() to release the session - __init__.py: close the reused session on config-entry unload - const.py / services.py / services.yaml: register the rohlikcz.refresh_slots service (config_entry_id required, SupportsResponse.NONE) - automations/refresh_slots.yaml: example automation showing on-demand express polling with the new action
Owner
|
@MangelSpec Thanks for the PR, looks good. I will review and merge if no issues found. |
Owner
|
@claude review |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Express availability (the
IsExpressAvailablebinary sensor) only updates on the 600sSCAN_INTERVAL, so it can be up to ~10 minutes stale.The concrete motivation: in my Home Assistant setup I have a "notify when express available" toggle that pushes a notification to my phone the moment express becomes available, so I can grab a slot. Express slots go fast, and a refresh cadence of up to 10 minutes was far too slow; the notification often arrived after the slots were already gone.
The existing
update_dataservice can force a refresh, but it does a full login, ~10 endpoint GETs, the cart, and a logout (about 12 requests), so polling it every few seconds to catch express in time would hammer the server.This adds a dedicated
rohlikcz.refresh_slotsaction that fetches only the timeslot endpoint, cheap enough to poll every ~15s (in my case only while the alert is armed) so the notification fires within seconds instead of minutes. The included example automation shows exactly this pattern.What changed
Feature:
RohlikCZAPI.get_timeslots(): a single GET to the timeslots-api endpoint (the same URLget_dataalready builds fornext_delivery_slot).requests.Session, so a slot check is one request instead of login + GET + logout. It re-authenticates only on HTTP 401 and retries once on a transient connection reset (a stale keep-alive connection closed by the server between polls). Access is serialized with anasyncio.Lock, and the session is closed on unload.RohlikAccount.refresh_slots(): merges the result intoself.data["next_delivery_slot"](it does not replaceself.data) and publishes updates, so the express sensor refreshes while every other sensor keeps its value.config_entry_idrequired,SupportsResponse.NONE), aservices.yamlentry, and an example automation inautomations/refresh_slots.yaml.get_data()is left unchanged and stays stateless; onlyrefresh_slotsuses the persistent session. No DataUpdateCoordinator refactor; this is intentionally minimal and follows existing patterns.Small fixes found along the way (kept in a separate commit):
tests/test_order_store.py: asserts were indented outside theTemporaryDirectoryblock, so the test raisedFileNotFoundError; re-indented and dropped the redundant manual cleanup.rohlik_api.py:search_productcalledlogin()twice.services.py: "Failed to get get cart content" doubled-word typo.hub.py: removed unusedcastandListimports.sensor.py: removed a dead, shadowedimport datetime.errors.py:APIRequestFailedErrordocstring was copied verbatim fromAddressNotSetError.todo.py: completed a truncated add-to-cart error log and lowered a successful-delete log from error to debug.Test plan
rohlikcz.refresh_slotsappears in Developer Tools and runs with no error.urllib3.connectionpooldebug logging,refresh_slotsperforms a single GET totimeslots-api, versusupdate_datadoing the full login + endpoints + logout.refresh_slots, the express binary sensor reflects current availability while cart/premium/other sensors keep their values (confirms the data merge, not a replace).