Skip to content

Translate bubbles select options - #162

Open
Maaatze wants to merge 1 commit into
cdpuk:mainfrom
Maaatze:translate-bubbles-options
Open

Maaatze wants to merge 1 commit into
cdpuk:mainfrom
Maaatze:translate-bubbles-options

Conversation

@Maaatze

@Maaatze Maaatze commented Sep 4, 2026

Copy link
Copy Markdown

The three-way bubbles select exposes its options as the literal strings OFF/MEDIUM/MAX, so every UI shows them in English regardless of the user's language. There is currently no entity block in the translation files at all.

Home Assistant translates select states by looking the option value up under entity.select.<key>.state, which requires slug values plus a translation_key on the entity description.

Changes

  • option values become slugs (off/medium/max)
  • translation_key added to the select description
  • entity.select.bubbles.state block added to en.json
  • de.json added — German for the states and the options flow
  • two tests: options are slugs, and every language translates every option

The entity name is deliberately left in the description, so display names do not change.

⚠️ Breaking change: automations calling select.select_option with the literal OFF/MEDIUM/MAX need updating to off/medium/max. I see no way to translate the states without it — happy to drop the PR if you consider that too disruptive for existing users.

Verified locally (uv sync against the repo's own lockfile, Python 3.14.2): baseline main 282 passed → with this change 284 passed; pre-commit run --all-files passes all eight hooks.

The three-way bubbles select exposed its options as the literal strings
OFF/MEDIUM/MAX, so every UI showed them in English regardless of the
user language. Home Assistant translates select states by looking the
option value up under entity.select.<key>.state, which requires slug
values and a translation_key on the entity description.

- switch option values to slugs (off/medium/max)
- add translation_key to the select description
- add the entity.select.bubbles.state block to en.json
- add de.json with German translations for the states and options flow
- add tests asserting the options are slugs and that every language
  translates every option

BREAKING CHANGE: automations calling select.select_option with the
literal OFF/MEDIUM/MAX values need updating to off/medium/max.
@OdynBrouwer

Copy link
Copy Markdown

Reviewed the diff against the current main (v1.11.1), and checked the
mechanism rather than taking it on faith.

The approach is correct, and the breaking change is unavoidable. The Home
Assistant localisation docs are explicit:

Note that translated states must be snake_case just like all other
translation keys.

— https://developers.home-assistant.io/docs/internationalization/core/#state-of-entities

So OFF/MEDIUM/MAX can never carry a translation entry, and the option
values have to become slugs for the labels to be translatable at all. The
instinct in the PR description ("I see no way to translate the states without
it") is right — this is not a style choice, and the breaking change does not
look avoidable while keeping the feature.

Worth making the blast radius explicit in the release notes, because it is
wider than select.select_option calls:

  • templates and select conditions comparing
    states('select.*_bubbles') == 'MEDIUM'
  • scenes and scripts that store the option string
  • recorder history: existing entries keep the old value, new ones record the
    slug
  • anything that renders the raw state rather than the translated label

Checks run against this branch:

  • translations/de.json is valid UTF-8 (Gerätegeneration, Mittel,
    Maximum all render correctly), and every key in it also exists in
    en.json — the key-parity check is satisfied, no orphan keys.
  • de.json is deliberately partial: the three auth config steps and
    config.error fall back to English. Worth stating in the PR so it is not
    read as a complete translation.
  • No file overlap with Fix Hydrojet V02 MEDIUM selection: step MAX then MEDIUM from OFF #153 (that one touches the write path in
    aws_iot/api.py / smartspa/api.py / const.py; this one the labels), so
    there is no conflict and no required merge order — the two are
    complementary.
  • Deployed on an F12D9Q San Francisco HydroJet Pro (SmartSpa backend): the
    select still drives the panel to every level with the new slug values, so
    the change is transparent on that hardware.

One nit in the new test: Path("custom_components/bestway/translations")
in tests/test_select_translations.py depends on the working directory. It
works in CI because pytest runs from the repo root, but
Path(__file__).parents[1] / "custom_components/bestway/translations" makes it
independent of where it is invoked from.

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.

2 participants