-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
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
Address post-merge reviews for KNX integration #123038
Conversation
Hey there @Julius2342, @marvin-w, mind taking a look at this pull request as it has been labeled with an integration ( Code owner commandsCode owners of
|
19fe4f0
to
7501f2a
Compare
@@ -34,11 +34,11 @@ async def async_setup_entry( | |||
async_add_entities: AddEntitiesCallback, | |||
) -> None: | |||
"""Set up the KNX binary sensor platform.""" | |||
xknx: XKNX = hass.data[DOMAIN].xknx | |||
knx_module: KNXModule = hass.data[DOMAIN] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For a future improvement; this could be moved to the runtime_data property of the config entry (removing the need to use hass.data overall)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately there are some places in the integration where I do need it, but don't have a config_entry handle.
Device triggers
https://github.com/home-assistant/core/blob/dev/homeassistant/components/knx/device_trigger.py#L66-L70
Services
https://github.com/home-assistant/core/blob/dev/homeassistant/components/knx/services.py#L225-L227
Websockets
https://github.com/home-assistant/core/blob/dev/homeassistant/components/knx/websocket.py#L122-L128
For Websockets we could probably pass an instance before registering.
But services shall be registered in async_setup()
so that is too early and for device triggers I don't know either.
await self.entities.pop(unique_id).async_remove() | ||
async_dispatcher_send(self.hass, SIGNAL_ENTITY_REMOVE.format(unique_id)) | ||
self.async_add_entity[platform](unique_id, data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MartinHjelmare would I need to await the entities async_remove()
(eg. by passing a future with the dispatcher) before adding the entity again? Or is it safe to do it like this way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should wait for the entity remove to complete before adding it again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it may be better to contain all this code within the platform since then we can access the platform helper and use its methods. Eg, we could get the platform helper with async_get_current_platform
and then look up the entity instance via the entity_id and operate directly on the entity. Probably define a common function that can be imported in each platform and used.
The storage should just be responsible for holding the stored config and singnaling the changes of the config. The platforms are responsible for actuating the changes in the config to the entities.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have to use the dispatcher either. The important thing is to split the abstraction correctly between storage and platforms.
Eg, we could create a small class with abstract methods that each platform is responsible to implement where the abstract interface has methods for adding a new config item (entity) and removing a config item (entity) and updating a config item (entity). Then the platforms register this instance to the storage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So like extending what already happens here
self._knx_module.config_store.entities.add(self._attr_unique_id) |
Would you know of any integration that does this already, so I can have a look at an example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So how can this platform helper instance remove an entity (call Entity.async_remove()
)? Would it also need to dispatch a signal to the entity instance or can it have a reference to the entity itself (like the storage did before)?
Should it be instantiated in the platforms async_setup_entry()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can work on the entity directly since it can access the EntityPlatform
instance that holds all the entities of the platform.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's also EntityPlatform.async_remove_entity
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be instantiated in the platforms async_setup_entry()?
Yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in #123128
Thanks for your suggestions! 👍
Proposed change
1163e34 -> #122342 (comment)
Entities now get passed a reference to the
KNXModule
object instead of theXKNX
object. This is used to pass an added entities unique_id toself._knx_module.config_store
(instead of passing the Entity reference) and additionaly avoids callinghass.data[DOMAIN]
inavailable()
property. The PR has grown quite big because of that since all platforms had to be changed. Adding UI Entitiy variants additionally to YAML variants will be easier now though.This is where the relevant stuff happens:
core/homeassistant/components/knx/knx_entity.py
Lines 71 to 77 in 19fe4f0
storage/config_store.py
.the other commits are a minor typing improvement and some cleanup regarding the previous commit
Type of change
Additional information
Checklist
ruff format 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
.To help with the load of incoming pull requests: