Allow area, device, and entity selectors to optionally support multiple selections like target selector#63138
Conversation
6226ae4 to
e7551f2
Compare
homeassistant/helpers/selector.py
Outdated
| @@ -125,6 +127,8 @@ class DeviceSelector(Selector): | |||
| vol.Optional("model"): str, | |||
| # Device has to contain entities matching this selector | |||
| vol.Optional("entity"): EntitySelector.CONFIG_SCHEMA, | |||
There was a problem hiding this comment.
This selector is changing. Please inline the old config schema.
CC @emontnemery
homeassistant/helpers/selector.py
Outdated
| vol.Optional("entity"): EntitySelector.CONFIG_SCHEMA, | ||
| vol.Optional("device"): DeviceSelector.CONFIG_SCHEMA, |
There was a problem hiding this comment.
This selector is changing. Please inline the old config schema.
homeassistant/helpers/selector.py
Outdated
| { | ||
| vol.Optional("entity"): EntitySelector.CONFIG_SCHEMA, | ||
| vol.Optional("device"): DeviceSelector.CONFIG_SCHEMA, | ||
| # Allow multiple area selection |
There was a problem hiding this comment.
Please remove comments. It's clear what multiple means 😄
|
Please update the |
…le selections like target selector
e7551f2 to
9ef8b40
Compare
|
@r-t-s Please do not squash commits, it makes it really hard to follow changes during the review. Thanks! 👍 |
homeassistant/helpers/selector.py
Outdated
| ) | ||
|
|
||
| return entity_id | ||
| result = cv.entity_ids_or_uuids(data) |
There was a problem hiding this comment.
When multiple is set to true, we should only validate it as multiple entities, and only validate as single if multiple is false.
There was a problem hiding this comment.
I was keeping with the interface for entity_id in a trigger. It accepts a single or a list. Currently in the selector I only return a single entity if one is selected, and a list if enabled and more than 1 is selected. I believe the entity_id in the target selector behaves the same way.
There was a problem hiding this comment.
That is not always the case, selectors can also be used in places that can't handle lists.
There was a problem hiding this comment.
They selector config must specify multiple and the user must pick more than one to get a list. So we should be OK.
The question is should we always return a list (even an empty list) if multiple is specified.
There was a problem hiding this comment.
Yes we should always return a list if multiple is set to true and a string if not.
However, your current code is not checking if multiple is set, but just validates first as a single, then as multiple. We should just check the value of multiple.
homeassistant/helpers/selector.py
Outdated
| result: str | list[str] | ||
|
|
||
| def validate(e_or_u: str) -> None: | ||
| if "domain" in self.config: |
There was a problem hiding this comment.
Use guard clauses to keep the code readable.
if 'domain' not in self.config:
return
homeassistant/helpers/selector.py
Outdated
|
|
||
| def validate(e_or_u: str) -> None: | ||
| if "domain" in self.config: | ||
| if valid_entity_id(e_or_u): |
There was a problem hiding this comment.
Why would you not raise if it's not a valid entity ID ?
There was a problem hiding this comment.
Because it could be a uuid the previous validation was a little obscure ... and I needed to test each result in the list.
| "integration": "zha", | ||
| "manufacturer": "IKEA of Sweden", | ||
| "model": "TRADFRI remote control", | ||
| "multiple": False, |
There was a problem hiding this comment.
Let's not update all tests but also leave some where we don't specify multiple, to verify the default is False.
There was a problem hiding this comment.
That's exactly what happens; "multiple" has False as default value so it's added to the validated blueprint input 👍
The changes just adjusts the test because the validated blueprint input has changed.
|
|
||
| def validate(e_or_u: str) -> str: | ||
| if not valid_entity_id(e_or_u): | ||
| return e_or_u |
There was a problem hiding this comment.
Should we still verify it looks like a uuid ?
There was a problem hiding this comment.
Oh nm you do that before passing to validate.
homeassistant/helpers/selector.py
Outdated
| return e_or_u | ||
|
|
||
| if not self.config["multiple"]: | ||
| return validate(cv.entity_id_or_uuid(cv.string(data))) |
There was a problem hiding this comment.
Looks like you could move cv.entity_id_or_uuid(cv.string(data)) inside validate too ?
Is cv.string necessary on top of cv.entity_id_or_uuid ?
homeassistant/helpers/selector.py
Outdated
| return validate(data) | ||
| if not isinstance(data, list): | ||
| raise vol.Invalid("Value should be a list") | ||
| return [validate(item) for item in data] |
There was a problem hiding this comment.
If you do vol.Schema([validate]) it will give a nicer error message, something like "value at index X invalid: XX". Not sure if that really matters.
There was a problem hiding this comment.
Yeah, that's a bit better indeed 👍
before:
voluptuous.error.MultipleInvalid: Entity light.def456 belongs to domain light, expected sensor for dictionary value @ data['selection']
after:
voluptuous.error.MultipleInvalid: Entity light.def456 belongs to domain light, expected sensor @ data['selection'][1]
emontnemery
left a comment
There was a problem hiding this comment.
Thanks @r-t-s, this is great 👍
Proposed change
Changes to the Area, Device, and Entity selectors to allow them to select multiple entities.
The user interface is similar to the Area, Device and Entity selector component of the target selector.
Single or multi select is configured with the optional multiple option on the selector configuration.
The selectors can now potentially return a list of area, device, or entity IDs.
This is motivated by the need to have multiple entity selector so a blueprint can trigger on multiple entities.
But brings a consistent UI for the Area, Device, Entity, and Target selector.
The associated User Interface PR #11059
Type of change
Additional information
Checklist
black --fast homeassistant tests)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest.requirements_all.txt.Updated by running
python3 -m script.gen_requirements_all..coveragerc.The integration reached or maintains the following Integration Quality Scale:
To help with the load of incoming pull requests: