Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Translation possible? #30

Open
StijnVdd opened this issue Nov 13, 2024 · 57 comments
Open

Translation possible? #30

StijnVdd opened this issue Nov 13, 2024 · 57 comments
Labels
enhancement New feature or request

Comments

@StijnVdd
Copy link

Hi,

First of all, thanks a lot for this integration!

Would it be possible to provide a translation for all the entities and their state ?
I've been renaming the entity names in HA and this mostly does meet my requirement, but the states of the entities are not changeable (at least not without defining a template entity or something like that)

I would therefore like to suggest the possibility to configure the language of integration. For example via a setting or by using the same language as the HA frontend.

I would love to help out with the translation files.

Thanks a lot the the consideration.

@MadOne
Copy link
Collaborator

MadOne commented Nov 13, 2024

Value Translation is possible, but a lot of work.

Entity renaming is also possible but won't work with our current dynamic prefix system.

I will work on the values first.

@OStrama
Copy link
Owner

OStrama commented Nov 13, 2024

Adding translation possibility of all names and values will be part of a new version.

Inbeteween you can help yourself as follows:

  1. In principle, all of the fixed strings are concentrated in the file hpconst.py.
  2. You can simply edit the strings in this file to have all values in the language you prefer.
  3. If you do so, it would be great to send us the modified file (please no direct pull request, since it will flip the default language ;-)), so that we cann use this as input for future translations.

@StijnVdd
Copy link
Author

Thanks a lot for the feedback!

With the help of some AI, I've translated the file in Dutch.
A lot of translations are not 100% ok, but I'll tweak those on the go.

Please find attached the translated file.

After changing this file and restarting HA, the integration created completely new entities (and thus entity_ids) causing the few automations I had build to break.

May I suggest to keep this in mind when developing this translation feature?
Suggestion: keep the entity IDs in English (a bit more universal) and allow the name to change based on the language configuration.

I assume this translation feature will result in a rather large refactor, so another suggestion I would like to make is the possibility to define icons in the hpconst.py file.

hpconst_NL.zip

@OStrama
Copy link
Owner

OStrama commented Nov 13, 2024

For the next version, we can include entity names and states as described here:

https://developers.home-assistant.io/docs/internationalization/core

But we have to look how to handle pre and postfixes..

@MadOne
Copy link
Collaborator

MadOne commented Nov 13, 2024

Im already working on the translation feature. It will NOT change the "unique id" witch HA take for statistics and translate the name.

But we have to put EVERY sensor in a json like this:
"Fehlerfrei": {
"state": {
"Fehler aktiv": "Fehler aktiv",
"Störungsfreier Betrieb": "Störungsfreier Betrieb",
},
"name": "Fehlerfrei"
}

As you can imagine this is verry time consuming, so please be patient.

@OStrama
Copy link
Owner

OStrama commented Nov 13, 2024

@StijnVdd thanks for the file. I hope that the entity IDs will preserve when using the method described in the link in my last post. (It‘s my 1st integration, have to learn a lot..)
When back home I do a try with putting some sensor translations in the json files..

@OStrama
Copy link
Owner

OStrama commented Nov 13, 2024

Im already working on the translation feature. It will NOT change the "unique id" witch HA take for statistics and translate the name.

But we have to put EVERY sensor in a json like this: "Fehlerfrei": { "state": { "Fehler aktiv": "Fehler aktiv", "Störungsfreier Betrieb": "Störungsfreier Betrieb", }, "name": "Fehlerfrei" }

As you can imagine this is verry time consuming, so please be patient.

A kind of coincidence ;-)

@MadOne
Copy link
Collaborator

MadOne commented Nov 13, 2024

@OStrama :
I created a new branch for this, as it breaks all entity names as long as the string.json and de.json are not complete.

@OStrama
Copy link
Owner

OStrama commented Nov 13, 2024

Maybe, it‘s faster to write a little python script that crunches through the ModbusItem and StatusItem lists and builds the json file automatically ;-)

@MadOne
Copy link
Collaborator

MadOne commented Nov 13, 2024

Can you read my mind? Scary ;)

@MadOne
Copy link
Collaborator

MadOne commented Nov 14, 2024

I have a version we can test. But can't push from here in work. Will Push when i am at home.

Prefix should work with {placeholder}

@StijnVdd
Copy link
Author

Once pushed, I'll give it a try. Looking forward to it

@MadOne
Copy link
Collaborator

MadOne commented Nov 14, 2024

@StijnVdd : No build to test for you yet. Still working on it, sorry.

@OStrama: I made a generation function in init.py. We have to copy strings manually by now.
For testing i copied the strings.json to en.json and de.json. Not sure if there was a translation yet.

I am working on a automatical generation of strings.json and the {place_holder} now.

@MadOne
Copy link
Collaborator

MadOne commented Nov 16, 2024

@OStrama : I finally finished the translation system. Can you please also check if it is working as expected?

@MadOne MadOne added the enhancement New feature or request label Nov 16, 2024
@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

I tested the files that were checked in. To see what happens, I translated some of the entities in en.json into English.

The entity names seem to be translated. However, the name of the selections of a select entity do not change:

    "select": {
        "hz_betriebsart": {
            "name": "Operation mode",
            "state": {
                "hz_betriebsart_absenk": "Lowering mode",
                "hz_betriebsart_auto": "Automatic",
                "hz_betriebsart_normal": "Normal",
                "hz_betriebsart_standy": "Standby",
                "hz_betriebsat_komfort": "Comfort"
            }
        },

image

I checked out "translation"

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

Maybe, it also would make sense to add translations to the devices, like this:

"device":{
    "System": {"name": "System"},
    "Wärmepumpe": {"name": "Heat pump"},
    "Warmwasser": {"name": "Hot water"},
    "Heizkreis": {"name": "Heating circuit"},
    "Heizkreis2": {"name": "Heating circuit2"},
    "Heizkreis3": {"name": "Heating circuit3"},
    "Heizkreis4": {"name": "Heating circuit4"},
    "Heizkreis5": {"name": "Heating circuit5"},
    "2. Wärmeerzeuger": {"name": "2nd heat source"},
    "Statistik": {"name": "Statistics"},
    "Unknown": {"name": "Unknown"},
    "Eingänge/Ausgänge": {"name": "Input/output"}
},

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

Another point. If I look at:

ModbusItem( address=30001, name="Aussentemperatur", mformat=FORMATS.TEMPERATUR, mtype=TYPES.SENSOR, device=DEVICES.SYS, resultlist=TEMPRANGE_STD, translation_key="aussentemp"),

And the usage of the name, it looks as if the name of the modbus item itself is not longer used. Shouldn't we completely replace it by the translation key or generate one of them automatically? Or do you need both to cretae strins.json?

@MadOne
Copy link
Collaborator

MadOne commented Nov 17, 2024

Maybe, it also would make sense to add translations to the devices, like this:

"device":{
    "System": {"name": "System"},
    "Wärmepumpe": {"name": "Heat pump"},
    "Warmwasser": {"name": "Hot water"},
    "Heizkreis": {"name": "Heating circuit"},
    "Heizkreis2": {"name": "Heating circuit2"},
    "Heizkreis3": {"name": "Heating circuit3"},
    "Heizkreis4": {"name": "Heating circuit4"},
    "Heizkreis5": {"name": "Heating circuit5"},
    "2. Wärmeerzeuger": {"name": "2nd heat source"},
    "Statistik": {"name": "Statistics"},
    "Unknown": {"name": "Unknown"},
    "Eingänge/Ausgänge": {"name": "Input/output"}
},

Yes we should do this!

@MadOne
Copy link
Collaborator

MadOne commented Nov 17, 2024

Another point. If I look at:

ModbusItem( address=30001, name="Aussentemperatur", mformat=FORMATS.TEMPERATUR, mtype=TYPES.SENSOR, device=DEVICES.SYS, resultlist=TEMPRANGE_STD, translation_key="aussentemp"),

And the usage of the name, it looks as if the name of the modbus item itself is not longer used. Shouldn't we completely replace it by the translation key or generate one of them automatically? Or do you need both to cretae strins.json?

At the moment i use the name to gereate the strings.json. When the translation system is complete, we can erase the names.

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

I found a way also to translate the list entries..

@MadOne
Copy link
Collaborator

MadOne commented Nov 17, 2024

Please push it.

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

done ;-)

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

it was basically using translation_key as strings here, too..

@MadOne
Copy link
Collaborator

MadOne commented Nov 17, 2024

Bildschirmfoto vom 2024-11-17 14-43-45

Seems to not work for me.

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

switch your language to english. I translated the English version
image

@MadOne
Copy link
Collaborator

MadOne commented Nov 17, 2024

I was on a similar path, but changed the text_from_number function whitch seems to break something else.
Oh of course. I edited the german version for testing but overwrote with pull.

This looks good to me. So only the devices are missing and perhaps the prefix system

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

text_from_number is also used to get text of error messages etc. When we put all in translation system, we could get rid of one of them..

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

But it seems to work, too:

image

I catched a cold, that's why 25° ;-)

@MadOne
Copy link
Collaborator

MadOne commented Nov 17, 2024

You have to be carefull with your translation_key values:

Error: R] [TRANSLATIONS] Invalid strings.json: Invalid translation key 'System', need to be [a-z0-9-_]+ and cannot start or end with a hyphen or underscore. for dictionary value @ data['device']. Got {'System': {'name': 'System'}, 'Wärmepumpe': {'name': 'Heat pump'}, 'Warmwasser': {'name': 'Hot water'}, 'Heizkreis': {'name': 'Heating circuit'}, 'Heizkreis2': {'name': 'Heating circuit2'}, 'Heizkreis3': {'name': 'Heating circuit3'}, 'Heizkreis4': {'name': 'Heating circuit4'}, 'Heizkreis5': {'name': 'Heating circuit5'}, '2. Wärmeerzeuger': {'name': '2nd heat source'}, 'Statistik': {'name': 'Statistics'}, 'Unknown': {'name': 'Unknown'}, 'Eingänge/Ausgänge': {'name': 'Input/output'}}

The hacs check complains: Invalid translation key 'System', need to be [a-z0-9-_]+ and cannot start or end with a hyphen or underscore.

This is why i had to recreate the translation_key. Before i had just copied the name over. But his HACS check won't allow that. Thats the reason why you probably got 20 emails ;)

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

Got it:
image
But it will again replicate all device entries...

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

But entities stay as they are, so we could use this..
Will check in in a minute..

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

done ;-)

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

I completely translated en.json. @StijnVdd : What about adding a file nl.json ;-)

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

@MadOne What do you think, should we try to merge back translation to main?

@MadOne
Copy link
Collaborator

MadOne commented Nov 17, 2024

@MadOne What do you think, should we try to merge back translation to main?

Not sure if we should fix the prefix system first.

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

Ah yes, makes sense. I saw on some source codes in core constructs like this:

"config": {
"step": {
"user": {
"title": "Fill in your Abode login information",
"data": {
"username": "[%key:common::config_flow::data::email%]",
"password": "[%key:common::config_flow::data::password%]"
}
},

I do not really understand the syntax, but it seems that there's a way to use variables in names.

Otherwise, we have to find out what method of the entity class does the translation and overwrite it..

@MadOne
Copy link
Collaborator

MadOne commented Nov 17, 2024

As far as i know this are official home assistant strings.

@MadOne
Copy link
Collaborator

MadOne commented Nov 17, 2024

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

... or the brute-force method: Overwriting _device_class_name_helper() in SensorEntity and thwe others ;-)

def _device_class_name_helper(
    self,
    component_translations: dict[str, str],
) -> str | None:
    """Return a decorated translated name of the entity based on its device class."""
    name = super()._device_class_name_helper(component_translations)

    if name is None:
        return name

    dev_postfix = ""
    dev_postfix = "_" + self._config_entry.data[CONF_DEVICE_POSTFIX]

    if dev_postfix == "_":
        dev_postfix = ""

    dev_prefix = CONST.DEF_PREFIX
    dev_prefix = self._config_entry.data[CONF_PREFIX]

    if self._config_entry.data[CONF_NAME_DEVICE_PREFIX]:
        name_device_prefix = self._config_entry.data[CONF_PREFIX] + "_"
    else:
        name_device_prefix = ""

    if self._config_entry.data[CONF_NAME_TOPIC_PREFIX]:
        name_topic_prefix = reverse_device_list[self._modbus_item.device] + "_"
    else:
        name_topic_prefix = ""

    name_prefix = name_topic_prefix + name_device_prefix
    complete_name = name_prefix + name

    return complete_name

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

Looks a bit weird, because I made some mistakes in setting up the name..

image

@MadOne
Copy link
Collaborator

MadOne commented Nov 17, 2024

Looks a bit hacky to me. I think i got it with this:
https://developers.home-assistant.io/blog/2024/01/19/entity-translations-placeholders/

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

OK, then delete the helper function to avoid interference..

@MadOne
Copy link
Collaborator

MadOne commented Nov 17, 2024

I have no working solution yet but this looks very promising. But its good to have a backup strategy.

Could you please look at this?
I would love to have this integration in the default hacs.

@MadOne
Copy link
Collaborator

MadOne commented Nov 17, 2024

I somehow messed up the merge and now the translation of the sensor values and dropdowns is again not working. Can you have a look at it?

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

Yes, sure!

@OStrama
Copy link
Owner

OStrama commented Nov 17, 2024

I think you should delete this function in entities.py

def _device_class_name_helper()

Then maybe the reverse_device_list was changed and could cause an issue..

@MadOne
Copy link
Collaborator

MadOne commented Nov 18, 2024

Translation will be possible in the next release.

@MadOne MadOne closed this as completed Nov 18, 2024
@StijnVdd
Copy link
Author

Hi,

I just downloaded the most recent version of the integration.
How can I contribute to the 'dutch' translation ?

@MadOne
Copy link
Collaborator

MadOne commented Nov 25, 2024

Hi,
you can take one of the following files:
strings.json
translation/en.json
translation/de.json and translate the strings.
Strings with underscore are most likely translation_keys and are not allowed to change.

We did not aktivate the translation yet, due to an entity naming issue. Anyways you can already start translaing.

@StijnVdd
Copy link
Author

I'll translate the strings.json to dutch.
It that the one used by default for now ?

Is it correct the entity ID will always be in German and the 'translation' changes just the name?

@MadOne
Copy link
Collaborator

MadOne commented Nov 25, 2024

Strings.json is used as default when translation is enabled, but it is NOT at the moment.
Your changes in strings.json have NO effect on your homeassistant at the moment.

As far as i have in mind the entity id says the same and only the friendly name changes. But can not test / confirm that right now.

@StijnVdd
Copy link
Author

Thanks for you fast reply !

Is there a way for me to 'enable' the translations for now so I can play around with it ?

@MadOne
Copy link
Collaborator

MadOne commented Nov 25, 2024

I created a new release UNSTABLE_1.0.2_Translation_UNSTABLE.

Be aware, this can create new devices and entitys, thus create new sensor history.
If you don't care about your sensor history you can use this whithout risk.

@StijnVdd
Copy link
Author

Thanks a lot.

I installed this version and replaced the strings.json with my own version (dutch). I also added the nl.json in the translation folder but the integration is not picking up my file.

I do notice the entity IDs changes to english an no longer are in german.

I'll test a bit more and provide more feedback.

How is the language selected?

@MadOne
Copy link
Collaborator

MadOne commented Nov 25, 2024

Leave string.json and place your files in the translation folder. Language is taken from your home assistant. You may need to restart ha for change of language

@OStrama
Copy link
Owner

OStrama commented Nov 25, 2024

Hi, please use version 1.0.4pre. In this version translation is enabled.
Please enable option „use old name style“ when updating from a former version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants