Skip to content

Support Knuspr.de, Gurkerl.at, Kifli.hu and Sezamo.ro - #92

Merged
dvejsada merged 2 commits into
masterfrom
claude/ha-integration-open-issues-1hg1fx
Sep 27, 2026
Merged

dvejsada merged 2 commits into
masterfrom
claude/ha-integration-open-issues-1hg1fx

Conversation

@dvejsada

Copy link
Copy Markdown
Owner

Fixes #91.

Why

All Rohlík Group shops run the same backend. Older versions could be pointed at Knuspr.de by editing BASE_URL in the in-tree client. That file went away when the integration moved to the rohlik-api package (db61166), so every entry was stuck on Rohlík.cz and CZK. rohlik-api already accepts a base_url; the integration just never passed one. No library change is needed.

I checked the login, first-delivery and cart endpoints on all five shops: each answers the same requests with the same response shape (for the login check I sent a made-up e-mail and got the usual 401 login.invalid_credentials back). I have not logged into a real non-Czech account.

Changes

  • Picking the shop: when adding the integration you pick the shop (Rohlík.cz, Knuspr.de, Gurkerl.at, Kifli.hu or Sezamo.ro). The choice is stored on the entry and sent to RohlikAPI as base_url. Entries without one stay on Rohlík.cz, and re-authentication keeps the entry's shop.
  • Reconfigure step: a new step lets an existing entry switch shop without being removed and re-added. The typical case is a Knuspr account added on an old version by editing the URL. Entries old enough to have no unique id get the account's id assigned during reconfigure.
  • Currency:
    • The money sensors (credit, cart total, spent this month/year/all time), the calendar and the cart to-do list use the shop's currency instead of CZK/Kč.
    • These units were previously set in the translation files. They are now set in code, which Home Assistant requires once the unit varies by shop.
    • Rohlík.cz installs with Home Assistant set to Czech keep Kč, so long-term statistics see no unit change.
  • Timezone:
    • Month and year boundaries, delivery-announcement clock times and the last-refresh time use the shop's timezone. This only differs for Sezamo.ro (Europe/Bucharest).
    • The timezone is loaded off the event loop.
  • Device manufacturer shows the shop name.
  • Credit Balance shows "unknown" instead of the text "N/A" when the value is missing, because a sensor with a unit must hold a number.
  • Translations: en/cs strings for the shop selector and the reconfigure step, and the wording is no longer Rohlik.cz-specific.
  • README: documents shop selection and Reconfigure. It also says the "in N minutes" delivery countdown is only parsed in Czech; announcements that give a clock time work in every shop.

Review notes

A code review ran on the branch, and its fixes are in the second commit. Two findings were deliberately left out:

  • Account identity across shops: the unique id is still the bare numeric user id. If the shops keep separate user databases, a Rohlík.cz and a Knuspr.de account with the same id would collide. That seems very unlikely. Prefixing the id with the shop would break the upgrade path for existing Knuspr entries.
  • Data kept on a shop switch: reconfigure keeps stored order history and the monthly total. It only accepts the same account id, so in practice it corrects the shop of an entry that was already on that shop, and the relabelled unit is the correct one.

The library's own multi-shop follow-up is tracked in dvejsada/rohlik_api_python#10: publishing the shop list, adding a currency to the cart models, and removing "CZK" from its docs. Once that ships, the integration can drop its own shop table.

Testing

  • python -m pytest tests/: 75 passed.
  • New tests cover:
    • the shop default and choosing a shop
    • validate_input using the shop's URL
    • reauth keeping the shop
    • reconfigure: success, invalid auth, wrong account, entry without a unique id
    • currency units per shop, including Czech keeping Kč
    • delivery-time parsing in the shop's timezone

🤖 Generated with Claude Code

https://claude.ai/code/session_0135WLPbnfESWnAJmw4P8uRH


Generated by Claude Code

The Rohlík Group shops all run the same backend, and older versions could
be pointed at another shop by editing BASE_URL in the in-tree client. That
file went away with the move to the rohlik-api package, leaving every entry
hard-wired to Rohlík.cz and CZK.

- Config flow: pick the shop when adding the account; it is stored on the
  entry and passed to RohlikAPI as base_url. Entries without one stay on
  Rohlík.cz. Reauth keeps the entry's shop.
- New reconfigure step so existing entries (e.g. set up against Knuspr.de on
  an old version) can switch shop without being removed and re-added.
- Money sensors (credit, cart total, spent this month/year/all time), the
  calendar and the cart todo use the shop's currency instead of CZK/Kč.
  Czech-language installs on Rohlík.cz keep the "Kč" unit they had, so
  long-term statistics do not see a unit change.
- Month/year boundaries and announcement clock times use the shop's
  timezone (matters for Sezamo.ro, Europe/Bucharest).
- Device manufacturer shows the shop name.
- Credit Balance reports unknown instead of the string "N/A" when missing,
  as a sensor with a unit must be numeric.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0135WLPbnfESWnAJmw4P8uRH
… times

- Reconfigure: entries from before unique ids existed have none to compare
  against, so the mismatch check always aborted with wrong_account. Adopt
  the account's id instead, unless another entry already has it.
- Load the shop's timezone with dt_util.async_get_time_zone in setup, so
  reading tzdata never blocks the event loop; the coordinator takes it from
  the cache.
- The last-refresh time uses the shop's timezone and the order store's
  tracking_since uses HA's, instead of a hardcoded Europe/Prague.
- get_site() is the one place that defaults to Rohlík.cz; drop the unused
  RohlikAccount.site property.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0135WLPbnfESWnAJmw4P8uRH

Copy link
Copy Markdown
Owner Author

@claude review this PR. Focus on correctness bugs, Home Assistant conventions (config/reconfigure flow, translations, sensor units) and regressions for existing Rohlík.cz entries.


Generated by Claude Code

@claude

claude Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Claude finished @dvejsada's task in 4m 5s —— View job


Review: Multi-shop support (Knuspr.de, Gurkerl.at, Kifli.hu, Sezamo.ro)

  • Gather context (diff, CLAUDE.md, changed files)
  • Review config_flow.py (shop selection + reconfigure)
  • Review hub.py / init.py (base_url wiring, reauth)
  • Review sensor.py / calendar.py / todo.py / utils.py (currency & timezone)
  • Review translations (en/cs)
  • Check regressions for existing Rohlík.cz entries
  • Post final review

No correctness bugs found. This is a careful, well-scoped change. Highlights of what I checked and why it holds up:

Config/reconfigure flow (config_flow.py)

  • async_step_user, async_step_reauth_confirm, and the new async_step_reconfigure all correctly thread CONF_SITE through validate_input → RohlikAPI(base_url=...). Reauth preserves the entry's existing site by spreading **reauth_entry.data before overriding only the password — good, matches the "reauth keeps the shop" claim.
  • async_step_reconfigure correctly uses _get_reconfigure_entry(), _abort_if_unique_id_mismatch, and async_update_reload_and_abort, and handles the legacy no-unique-id case via _abort_if_unique_id_configured() before adopting the new id. Tests cover success, invalid auth, wrong account, and the legacy-entry path (tests/test_config_flow.py:172-296).

Timezone preloading (__init__.py:47-49, hub.py:398-400)

  • await dt_util.async_get_time_zone(...) followed by a sync dt_util.get_time_zone(...) in the coordinator relies on HA's lru_cache-backed _get_time_zone (a strong-reference cache, not zoneinfo's own weak-value cache), so this pattern genuinely avoids a second blocking disk read — the comment is accurate, not just aspirational.

Currency/unit handling (sensor.py MoneySensor, hub.py currency property)

  • Every money sensor and cart/deposit currency reference goes through rohlik_account.currency now; I grepped for leftover hardcoded "CZK"/"Kč"/Europe/Prague and found only the intentional Rohlík.cz default in const.py and the cs-language "Kč" special case (sensor.py:541-542), which is well-justified (avoids a unit change in existing long-term statistics for Czech-language installs) and has a dedicated regression test (tests/test_init.py test_czech_language_keeps_kc_unit).
  • CreditAmount returning None instead of the string "N/A" is correct — a numeric sensor with a unit_of_measurement can't hold a string state.

Regressions for existing Rohlík.cz entries

  • get_site(None) defaults to cz/CZK/Prague, so entries with no CONF_SITE (pre-existing installs) are unaffected in behavior. No config migration was needed and none was added, which is correct since entry.data.get(CONF_SITE) degrades gracefully.
  • device_info["manufacturer"] now shows the shop name instead of a hardcoded "Rohlík.cz", but device identifiers are still (DOMAIN, user_id), so this doesn't create duplicate devices for existing installs.

Minor, non-blocking observations (not raised as findings — already acknowledged in the PR description itself):

  • Cross-shop unique-id collisions and unit changes on a "real" shop switch via reconfigure are both called out explicitly in the PR's "Review notes" section, with reasoning I agree with.

Not run: I wasn't able to execute pytest in this sandboxed environment (commands were blocked pending approval), so I relied on static review of the diff and the new/changed tests in tests/test_config_flow.py, tests/test_init.py, and tests/test_extract_delivery_datetime.py, all of which look like they exercise the right edge cases. If CI hasn't run yet, worth confirming the reported "75 passed" locally.
· branch claude/ha-integration-open-issues-1hg1fx

@IngoPodolak

Copy link
Copy Markdown

Thanks for the quick update. Knuspr.de is working as expected for me now, and in Euro too.

I also tried out the cards, the currency is still incorrect there.
If you'd like, I could also help with a German translation.

@dvejsada

Copy link
Copy Markdown
Owner Author

Thanks for the quick update. Knuspr.de is working as expected for me now, and in Euro too.

I also tried out the cards, the currency is still incorrect there. If you'd like, I could also help with a German translation.

@IngoPodolak Thanks, please kindly open the issues in cards repo for both currency and translations, much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

knuspr.de

3 participants