home-assistant / frontend

:lollipop: Frontend for Home Assistant
https://demo.home-assistant.io
Other
3.99k stars 2.72k forks source link

"detected" and "cleared" log entries need per device type variants #22247

Open NoRi2909 opened 2 days ago

NoRi2909 commented 2 days ago

Checklist

Describe the issue you are experiencing

Currently there is just a single string for both the "detected" and "cleared" log entries under

So for an occupancy sensor the log entry looks like this:

Screenshot 2024-10-05 15 03 55

In many languages there is no single translation that fits all device classes, so especially the "Cleared" log entries look really strange. In German "cleared" is currently translated as "zurückgesetzt" ("reset") which makes this even worse.

Screenshot 2024-10-05 15 04 12

Also note that due to grammar issues we need to use "kein(e)" to translate the simple "no" in English. So to really fix this for all device classes we do need separate strings.

Describe the behavior you expected

For the state shown in the dashboard this is already solved as there are different strings defined, so the "off" state can have a proper translation.

Many can have identical translations following:

So by defaut all other were dirived from the above, which works OK for similar sensors like:

But for other this needs to be adapted, for example:

So we need a similar approach for the log entries, differentiating the "off" state.

A possible simpler approach would be to use the "on" and "off" states already defined above to create the log entries:

Steps to reproduce the issue

Just look through the different UI languages for such occupancy sensor logs, e.g.

What version of Home Assistant Core has the issue?

core-2024.10.0

What was the last working version of Home Assistant Core?

No response

In which browser are you experiencing the issue with?

n/a

Which operating system are you using to run this browser?

n/a

State of relevant entities

No response

Problem-relevant frontend configuration

No response

Javascript errors shown in your browser console/inspector

No response

Additional information

Note that the Swedish lokalizer already left a similar comment that he's running into that problem, too.

https://app.lokalise.com/project/3420425759f6d6d241f598.13594006/?k=58795583

karwosts commented 2 days ago

We sort of have this already, but only for some device classes, and which ones are individually translatable are fixed in code, e.g.

          case "door":                                                                                                                                        |          // If there's no key for a specific device class, fallback to generic string
          case "garage_door":                                                                                                                                 |          localize(`${LOGBOOK_LOCALIZE_PATH}.${isOn ? "detected_device_class" : "cleared_device_class"}`, {
          case "opening":                                                                                                                                     |            device_class: autoCaseNoun(
          case "window":                                                                                                                                      |              localize(
            if (isOn) {                                                                                                                                       |                `component.binary_sensor.entity_component.${device_class}.name`
              return localize(`${LOGBOOK_LOCALIZE_PATH}.was_opened`);                                                                                         |              ) || device_class,
            }                                                                                                                                                 |              hass.language
            if (isOff) {                                                                                                                                      |            ),
              return localize(`${LOGBOOK_LOCALIZE_PATH}.was_closed`);                                                                                         |          });
            }             

But many device classes are just yoked together with the same fixed translation.

        case "cold":
        case "gas":
        case "heat":
        case "moisture":
        case "motion":
        case "occupancy":
        case "power":
        case "problem":
        case "smoke":
        case "sound":
        case "vibration":
          if (isOn) {
            return localize(`${LOGBOOK_LOCALIZE_PATH}.detected_device_class`, {
              device_class: autoCaseNoun(
                localize(
                  `component.binary_sensor.entity_component.${device_class}.name`
                ),
                hass.language
              ),
            });
          }

I think we could probably move this logic into the localization file itself, and just give each device_class its own key, but by default link all the existing ones back to the main translation key. Then I believe individual translators can break that link as desired for their language to give a custom string?

e.g.

          "detected_device_class": "detected {device_class}",

          "detected_device_classes": {
              "battery": "[%key:ui::components::logbook::messages::was_low%]",
              "battery_charging": "started charging",
              "carbon_monoxide": "[%key:ui::components::logbook::messages::detected_device_class%]",
              "cold": "[%key:ui::components::logbook::messages::detected_device_class%]",
              "connectivity": "[%key:ui::components::logbook::messages::was_connected%]",
              "door": "[%key:ui::components::logbook::messages::was_opened%]",
              "garage_door": "[%key:ui::components::logbook::messages::was_opened%]",
              "gas": "[%key:ui::components::logbook::messages::detected_device_class%]",
              "heat": "[%key:ui::components::logbook::messages::detected_device_class%]",
              "light": "[%key:ui::components::logbook::messages::detected_device_class%]",
              "lock": "[%key:ui::components::logbook::messages::was_unlocked%]",
              "moisture": "[%key:ui::components::logbook::messages::detected_device_class%]",
              "motion": "[%key:ui::components::logbook::messages::detected_device_class%]",
              "moving": "[%key:ui::components::logbook::messages::detected_device_class%]",
              "occupancy": "[%key:ui::components::logbook::messages::detected_device_class%]",
              "opening": "[%key:ui::components::logbook::messages::was_opened%]",
              "plug": "[%key:ui::components::logbook::messages::was_plugged_in%]",
              "power": "[%key:ui::components::logbook::messages::detected_device_class%]",
              "presence": "[%key:ui::components::logbook::messages::was_at_home%]",
              "problem": "[%key:ui::components::logbook::messages::detected_device_class%]",
              "running": "[%key:ui::components::logbook::messages::detected_device_class%]",
              "safety": "[%key:ui::components::logbook::messages::was_unsafe%]",
              "smoke": "[%key:ui::components::logbook::messages::detected_device_class%]",
              "sound": "[%key:ui::components::logbook::messages::detected_device_class%]",
              "tamper": "[%key:ui::components::logbook::messages::detected_tampering%]",
              "update": "[%key:ui::components::logbook::messages::detected_device_class%]",
              "vibration": "[%key:ui::components::logbook::messages::detected_device_class%]",
              "window": "[%key:ui::components::logbook::messages::was_opened%]"
          },

I think that works in Lokalise, but would be good to get a confirmation.

NoRi2909 commented 2 days ago

@karwosts Yes, that's seems to be how it's already done for the "off" and "on" status in HA Core.

I found this out using this search:

https://app.lokalise.com/project/130246255a974bd3b5e8a1.51616605/?view=single&reference_lang_id=640&single_lang_id=666&search=component::binary_sensor::entity_component::gas::state::off

Here

 component::binary_sensor::entity_component::gas::state::off
 component::binary_sensor::entity_component::gas::state::on  

are the ones with a static "Clear" or "Detected" in the English language. All others are referenced from there so we can change this when a localization needs it.

For an occupancy sensor I changed that pair in German to "Frei" and "Belegt" which work much better.