HomeIntent
HomeIntent copied to clipboard
German Translation
Hey @JarvyJ,
I will be working on a german translation.
As a proof that I am in fact German, I accidentally capitalized the T in translation.
Is there a way to overwrite numbers? Rhasspy maps them via num2words package, but it lacks some details.
For example it maps 128: einhundertachtundzwanzig, but in most cases you would just say hunderachtundzwanzig.
We should be able to create a custom number slot dictionary:
@intents.dictionary_slots
def number(self):
return {
"one": "1",
"two": "2",
"three": "3",
}
and then in the sentences do:
"set timer ($number) minutes"
~~I might play around and see what's possible.~~ The above should work!
Ah, right now, we can't do "repeatable" slots... so instead of one slot defining all the numbers and then reusing for hours/minutes/seconds. It has to be effectively the same slot repeated three times with different slot names. So instead of "number" in the example above, you'd have a slot for minutes
, hours
, and then seconds
. Not super ideal...
I might try to work in "repeatable" slots, so you could have one slot definition for numbers, then reuse the slot in the sentence:
multiply ($number){first} times ($number){second}
and the actual number would come back in first
and second
I did create a new branch (#234) that has a repeatable_dictionary_slots
in the intent, which should allow for the above to work. I'll write up some docs on it and merge it in. It's mostly so we can try it out and see if it works for the use case!
Nice. Unfortunately I couldn't figure out how to get it running.
Do I need to put
@intents.repeatable_dictionary_slots
def number(self):
return {
"one": "1",
"two": "2",
"three": "3",
}
inside the de.py and/or the base class?
Yes, it would be inside the de.py class. I think technically it would have to be timer_number
for it to be named properly.
So you'd have something like this (but with all the numbers in german in de.py):
@intents.repeatable_dictionary_slots
def timer_number(self):
return {
"five": "5",
"four": "4",
"three": "3",
"two": "2",
"one": "1",
}
and then one of the sentences would look something like this:
"set timer [($timer_number){hours} hours] [($timer_number){minutes} minutes] [($timer_number){seconds} seconds]"
I've also written some docs and will merge those in to hopefully clarify a bit more if needed: https://homeintent.io/reference/api/intents-class/#intentsrepeatable_dictionary_slots
Hope it helps!
and I ended up merging the repeatable_dictionary_slots
into main for now!
Yes, it would be inside the de.py class. I think technically it would have to be
timer_number
for it to be named properly.So you'd have something like this (but with all the numbers in german in de.py):
@intents.repeatable_dictionary_slots def timer_number(self): return { "five": "5", "four": "4", "three": "3", "two": "2", "one": "1", }
and then one of the sentences would look something like this:
"set timer [($timer_number){hours} hours] [($timer_number){minutes} minutes] [($timer_number){seconds} seconds]"
I've also written some docs and will merge those in to hopefully clarify a bit more if needed: https://homeintent.io/reference/api/intents-class/#intentsrepeatable_dictionary_slots
Hope it helps!
Yes, it helps. Thanks a lot. The incorrect naming was the problem I faced yesterday.
With
"time =($timer_number|0..99)"
and then using
"(<time>){hours}"
as before, I managed to only specify the numbers >99 inside timer_numbers to avoid having to write out the ones that don't need changing. This does exactly what I needed, thanks again.
Since the states of entities (lights) that are returned by HA api are in english ("on"), I implemented a little translation function into the language file.
This principle works perfectly fine, but maybe there is a better way to implement a function like this. For example Integrating it into the base class and only define the translated states inside the translation. This would make it work the same for all translations.
Yeah, this is kinda interesting. Since it affects just Home Assistant, I think I might add a language dictionary that gets auto-loaded based on language settings and provided back in the base constructor for use. English words that need to be translated from Home Assistant could all be defined there with their translations and the code could reference. I'll create a new issue and play around with it a bit to see how it would work.
Is there a way to get a working frontend running with the dev setup? It seems as though it would only communicate with rhasspy once on startup. Also, it seems as my custom rhasspy config in /config gets ignored which might be related to that.
Yeah, the dev frontend situation is not super great... It should be able to read/write the config, and view logs. So the "Save" partially works, but the restart functionality doesn't work.
When I need to test it all end-to-end, I have a separate docker-compose file (docker-compose.build.yaml
):
version: "3.9"
services:
homeintent:
build: .
container_name: homeintent
restart: unless-stopped
volumes:
- "./development-env/rhasspy:/profiles"
- "./development-env/config:/config"
- "/etc/localtime:/etc/localtime:ro"
ports:
- "12101:12101"
- "11102:11102"
devices:
- "/dev/snd:/dev/snd"
environment:
- LANGUAGE=en
and then just do a docker-compose -f docker-compose.build.yaml up --build
and restart as necessary... If I could get the API to control the other containers, that would help with that, but I haven't looked into it much.
Can you post your rhasspy config? I might've introduced a bug while setting the default TTS based on language...
Sure. That's the config. Ah I just remember to have read something about externally managed rhasspy flag. Do I have to activate that additionally?
{
"dialogue": {
"system": "rhasspy"
},
"intent": {
"system": "fsticuffs"
},
"microphone": {
"pyaudio": {
"device": "6",
"udp_audio_host": "127.0.0.1",
"udp_audio_port": "12202"
},
"system": "pyaudio"
},
"sounds": {
"aplay": {
"device": "sysdefault:CARD=Generic"
},
"system": "aplay"
},
"speech_to_text": {
"system": "kaldi"
},
"text_to_speech": {
"marytts": {
"locale": "de",
"url": "http://192.168.2.2:59125/process",
"voice": "bits1-hsmm",
"volume": "0.65"
},
"system": "marytts"
},
"wake": {
"porcupine": {
"keyword_path": "jarvis_linux.ppn",
"udp_audio": "127.0.0.1:12202"
},
"system": "porcupine"
}
}
And thanks for that docker-compose code.
I did end up introducing a bug with the profile code... >.< The tts section currently gets overridden with nanotts or espeak... I'll need to update my checks and merge code accordingly.
But yeah, you could also use an externally managed Rhasspy instead. It basically wont touch any of the Rhasspy settings and just install the slots/sentences and restart.
I see. That explains some things. :smile:
The docker-compose file you posted works perfectly for my needs - I don't do developing on the other components anyway.
Hey @oerkel47 thanks for your work. Unfortunately I get an error during the startup with the german translation (the english version works fine). Any idea how to fix that?
I pulled the latest docker image and configured the connection to home assistant but haven't activated the timer plugin.
9.5.2022, 20:00:27 INFO home_intent.rhasspy_api Trying to connect to Rhasspy at http://localhost:12101
9.5.2022, 20:00:34 INFO root Using language: de
9.5.2022, 20:00:34 ERROR root The argument 'cover_close_entity' is not associated in the sentence for <function Cover.close_cover at 0xb5b1d978>. Make sure the sentence decorator includes a ($cover_close_entity) or remove it as an argument.
Traceback (most recent call last):
File "/usr/src/app/home_intent/__main__.py", line 63, in main
_load_integrations(settings, home_intent)
File "/usr/src/app/home_intent/__main__.py", line 83, in _load_integrations
loaded_builtin_components = _load_builtin_components(components, home_intent)
File "/usr/src/app/home_intent/__main__.py", line 112, in _load_builtin_components
integration.setup(home_intent)
File "/usr/src/app/home_intent/components/home_assistant/__init__.py", line 79, in setup
cover = home_intent.import_module(f"{__name__}.cover")
File "/usr/src/app/home_intent/home_intent.py", line 136, in import_module
module = import_module(f"{module_name}.{self.settings.home_intent.language}")
File "/usr/lib/python3.7/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 728, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/usr/src/app/home_intent/components/home_assistant/cover/de.py", line 4, in <module>
class Cover(BaseCover):
File "/usr/src/app/home_intent/components/home_assistant/cover/de.py", line 17, in Cover
"Mache (das | den | die) ($cover_open_entity) zu"])
File "/usr/src/app/home_intent/intents/intents.py", line 82, in inner
sentence_slots = _check_if_args_in_sentence_slots(sentences, func)
File "/usr/src/app/home_intent/intents/util.py", line 60, in _check_if_args_in_sentence_slots
f"The argument '{arg}' is not associated in the sentence for {func}. "
home_intent.intents.util.IntentException: The argument 'cover_close_entity' is not associated in the sentence for <function Cover.close_cover at 0xb5b1d978>. Make sure the sentence decorator includes a ($cover_close_entity) or remove it as an argument.
Hi @trayhem, you are right. There is a stupid copy paste bug in the code. Sorry.
I created a fix, but it will probably take some time to show up in the docker image. In the meantime you could clone https://github.com/oerkel47/HomeIntent/tree/dev_DE and create the docker dev environment. Basically all you need to do is change the docker compose file and start it up (edit: or use as state earlier in this thread in https://github.com/JarvyJ/HomeIntent/issues/232#issuecomment-1008348179). The docker dev has some quirks though, you might have to restart it manually to get settings to apply.
Thanks for the report and the fix, I'll get it merged in here shortly!
Many thanks to both of you. I tried the nightly build and it works like a charm now - although it seems as if most of my lights from home assistant weren't recognized so I had to add them manually via rhasspy -> slots -> light but that is just a minor inconvenience.
Please keep up the good work ❤️