intents
intents copied to clipboard
Similar phrases for different device_classes produces error
Let's say we have the following entities (in Romanian):
tests/ro/_fixtures.yaml
areas:
- name: Garaj
id: garage
entities:
- name: intrarea dinspre garaj # meaning "entrance from the garage"
id: cover.garage_backdoor
device_class: door
area: garage
- name: rulou garaj
id: cover.garage_door
device_class: garage
area: garage
And the following sentences to operate them
sentences/ro/_common.yaml
expansion_rules:
area: "{area} [(zona | zonă | regiune)]"
name: "({name}[ul] | {name})"
din: "(din | (î|i)n | pentru | [de] la)"
inchide: "((î|i)nchide | coboar(ă|a))"
usa: "(u(ș|s)a | u(ș|s)ile)"
poarta: "(poarta | gardul)"
sentences/ro/cover_HassCloseCover.yaml
intents:
HassCloseCover:
data:
- sentences:
- "<inchide> <usa>"
- "<inchide> <usa> [<din>] <area>"
slots:
device_class: door
- sentences:
- "<inchide> <poarta>"
- "<inchide> <poarta> [<din>] <area>"
slots:
device_class: gate
- sentences:
- "<inchide> (<poarta> | <usa>) [<din>] garaj"
slots:
device_class: garage
Say I wanted to close the garage door. Id' say "inchide usa de la garaj"="close the garage door", which should match the last sentence in the set above. Here's the test for this scenario:
tests/ro/cover_HassCloseCover.yaml
tests:
- sentences:
- "inchide usa de la garaj"
intent:
name: HassCloseCover
slots:
device_class: garage
Just because I have an area called "garaj"="garage" and a specific device_class "usa"="door" for the cover_HassCloseCover
intent, that means my sentences will not get properly matched.
E AssertionError: Slots do not match for: inchide usa de la garaj
E assert {'area': 'gar...lass': 'door'} == {'device_class': 'garage'}
E Differing items:
E {'device_class': 'door'} != {'device_class': 'garage'}
E Left contains 1 more item:
E {'area': 'garage'}
E Use -v to get more diff
tests/test_language_sentences.py:75: AssertionError
FAILED tests/test_language_sentences.py::test_cover_HassCloseCover[ro] - AssertionError: Slots do not match for: inchide usa de la garaj
This seems like a very plausible real-world scenario that should be mitigated somehow and I don't think it's particular to the Romanian language. I could easily come up with a similar example in English
I think we can use "incuie /descuie" to doors as usual are not automated like garage doors. In case you have locks will be the same "incuie /descuie". So "inchide / deschide" should be more specific to automatic closing doors, blinds or whatever is motorized.
"incuie"/"descuie" are for the lock
domain, not the cover
domain. And that's not yet covered in the supported intents.
Good point :) then "inchide /deschide" are appropriate to moving objects like garage doors, covers, blinds. I'm currently using in EN "open/close Gate" (automatic garage door) and "turn on/off light", so to translate that in RO will need to have different words so" inchide/deschide" is more matching to objects that move. "aprinde/stinge" i will say are more appropriate to turn on or off lights. I'm sure we cannot cover all possible scenarios but most common sentences should be covered.
I have a PR in to fix this. A change would need to be made to sentences/ro/cover_HassCloseCover.yaml
:
intents:
HassCloseCover:
data:
- sentences:
- "<inchide> <usa>"
- "<inchide> <usa> [<din>] <area>"
slots:
device_class:
- door
- garage
- sentences:
- "<inchide> <poarta>"
- "<inchide> <poarta> [<din>] <area>"
slots:
device_class: gate
We haven't added it to the validation yet, but generic sentences like "close doors" (with no area) are something we'd like to avoid. Taking an action on a specific entity or area (with domain or device class) is preferred.
Fair enough, we can do that. The only device class that would be useful for would probably be external rollers (e.g. when leaving on vacation), but that's really not a must.
I'll refactor and test this later today or tomorrow. Thanks a lot!
@synesthesiam what about inferred context such as saying "close the blinds" in a certain room, meaning "close the blinds in that room"? How do we handle that?
For that, I think we'll use what you mentioned in the other issue. Something like:
requires_context:
area:
any: true
And then, the satellite will inject area
into the context during the request.