diff --git a/custom_components/localthings/entity.py b/custom_components/localthings/entity.py index 84501b4..634f631 100644 --- a/custom_components/localthings/entity.py +++ b/custom_components/localthings/entity.py @@ -43,7 +43,11 @@ def _derive_name(state_key: str) -> str: Strips a trailing instance number of 0 (singleton), promotes any other instance number with a space: "door_cooler_open1" → "Door Cooler Open 1". """ - name = re.sub(r'(\d+)$', lambda m: f' {m.group()}' if int(m.group()) > 0 else '', state_key) + name = re.sub( + r'_?(\d+)$', + lambda match: f' {match.group(1)}' if int(match.group(1)) > 0 else '', + state_key, + ) return _snake_to_title(name).strip() diff --git a/custom_components/localthings/select.py b/custom_components/localthings/select.py index c85cc95..2b0c62b 100644 --- a/custom_components/localthings/select.py +++ b/custom_components/localthings/select.py @@ -129,8 +129,14 @@ def _display(value, translation_key: Optional[str]): """ if not isinstance(value, str): return value - if translation_key and (translated := _translation_state(value, translation_key)): - return translated + if translation_key: + if translated := _translation_state(value, translation_key): + return translated + if translation_key not in TRANSLATED_SELECT_STATES: + # The entity name is translated, but this select deliberately has + # no static state catalog (for example an unknown course table). + # Keep its opaque device value untouched. + return value if value.islower(): return value.replace('_', ' ').title() return _CAMEL_BOUNDARY_RE.sub(' ', value) diff --git a/custom_components/localthings/strings.json b/custom_components/localthings/strings.json index 412cec0..c3860aa 100644 --- a/custom_components/localthings/strings.json +++ b/custom_components/localthings/strings.json @@ -488,6 +488,9 @@ "filter_progress": { "name": "Filter progress" }, + "filter_usage": { + "name": "Filter usage" + }, "fine_dust": { "name": "Fine dust" }, diff --git a/custom_components/localthings/translations/en.json b/custom_components/localthings/translations/en.json index 412cec0..c3860aa 100644 --- a/custom_components/localthings/translations/en.json +++ b/custom_components/localthings/translations/en.json @@ -488,6 +488,9 @@ "filter_progress": { "name": "Filter progress" }, + "filter_usage": { + "name": "Filter usage" + }, "fine_dust": { "name": "Fine dust" }, diff --git a/custom_components/localthings/translations/nl.json b/custom_components/localthings/translations/nl.json index 05510d0..4998fdd 100644 --- a/custom_components/localthings/translations/nl.json +++ b/custom_components/localthings/translations/nl.json @@ -488,6 +488,9 @@ "filter_progress": { "name": "Filterverbruik" }, + "filter_usage": { + "name": "Filtergebruik" + }, "fine_dust": { "name": "Fijnstof" }, diff --git a/tests/test_select_display.py b/tests/test_select_display.py index 3476c9a..a3e5ee3 100644 --- a/tests/test_select_display.py +++ b/tests/test_select_display.py @@ -2,7 +2,7 @@ from custom_components.localthings.select import _display _UNTRANSLATED = None -_TRANSLATED = 'door_alert' +_TRANSLATED = 'ice_type' def test_display_titlecases_a_fully_lowercase_device_native_token(): diff --git a/tests/test_select_options.py b/tests/test_select_options.py index 6a64719..b318a95 100644 --- a/tests/test_select_options.py +++ b/tests/test_select_options.py @@ -49,7 +49,7 @@ def test_callable_options_receives_full_resource_snapshot(): '/other/vs/0': {'codes': ['1C', '1D']}, } entity = _make_select(desc, '/x/vs/0', resources) - assert entity.options == ['1c', '1d'] + assert entity.options == ['1C', '1D'] assert calls == [resources]