* Keep track of top level components
Currently we have to do a set comp for icons, translations,
and integration platforms every time to split the top level
components from the platforms. Keep track of the top level
components in a seperate set so avoid having to do the setcomp
every time.
* remove impossible paths
* remove unused code
* preen
* preen
* fix
* coverage and fixes
* Update homeassistant/core.py
* Update homeassistant/core.py
* Update tests/test_core.py
* Remove unused state translations
There have been replaced with entity translations
https://github.com/home-assistant/developers.home-assistant/pull/1557https://github.com/home-assistant/core/pull/82701
* nothing does merging anymore
* useless dispatch
* remove
* remove platform code from hassfest
* preen
* Update homeassistant/helpers/translation.py
* ruff
* fix merge
* check is impossible now since we already know if translations exist or not
* keep the function for now
* remove unreachable code since we filter out `.` before now
* reduce
* reduce
* fix merge conflict (again)
* Fix race in TimestampDataUpdateCoordinator
The last_update_success_time value was being set after the listeners
were fired which could lead to a loop because the listener may
re-trigger an update because it thinks the data is stale
* coverage
* docstring
* Add notify entity component
* Device classes, restore state, icons
* Add icons file
* Add tests for kitchen_sink
* Remove notify from no_entity_platforms in hassfest icons, translation link
* ruff
* Remove `data` feature
* Only message support
* Complete initial device classes
* mypy pylint
* Remove device_class implementation
* format
* Follow up comments
* Remove _attr_supported_features
* Use setup_test_component_platform
* User helper at other places
* last comment
* Add entry unload test and non async test
* Avoid default mutable object in constructor
* Avoid checking for polling if an entity fails to add
* no need to do protected access
* no need to do protected access
* no need to do protected access
* no need to do protected access
* coverage
* fix test
* fix
* broken one must be first
* Bump aiodns to 3.2.0
changelog: https://github.com/saghul/aiodns/compare/v3.1.1...v3.2.0
* Switch to using the AsyncResolver with aiohttp
This avoids creating executor jobs to do DNS resolution
AsyncResolver was not usable before https://github.com/aio-libs/aiohttp/pull/8270
because it did not fallback to fallback to A records and only returned AAAA records
in most cases when IPv6 was available
This is a backport of https://github.com/aio-libs/aiohttp/pull/8270
* Switch to using the AsyncResolver with aiohttp
This avoids creating executor jobs to do DNS resolution
AsyncResolver was not usable before https://github.com/aio-libs/aiohttp/pull/8270
because it did not fallback to fallback to A records and only returned AAAA records
in most cases when IPv6 was available
This is a backport of https://github.com/aio-libs/aiohttp/pull/8270
* Switch to using the AsyncResolver with aiohttp
This avoids creating executor jobs to do DNS resolution
AsyncResolver was not usable before https://github.com/aio-libs/aiohttp/pull/8270
because it did not fallback to fallback to A records and only returned AAAA records
in most cases when IPv6 was available
This is a backport of https://github.com/aio-libs/aiohttp/pull/8270
* Switch to using the AsyncResolver with aiohttp
This avoids creating executor jobs to do DNS resolution
AsyncResolver was not usable before https://github.com/aio-libs/aiohttp/pull/8270
because it did not fallback to fallback to A records and only returned AAAA records
in most cases when IPv6 was available
This is a backport of https://github.com/aio-libs/aiohttp/pull/8270
* fixes
* fix mocking in next_dns
* fix unmocked calls in blink
* more mocking fixes
* more fixes
* more fixes
* Fix missing mocking in nextdns tests
extracted from #114539
* extract from context
* DNM: Make run_immediately the default for listeners
This is a test to see how much progress we have made twords this goal
https://github.com/home-assistant/core/pull/113727#issuecomment-2004587947
* fix shutdown
* Revert "fix shutdown"
This reverts commit a8969d7db9.
* set false since it break utility meter tests
* one more
* fix rfxtrx test
* test needs to be explict now
* fix matrix
* fail sooner
* Adjust async_load_platform comment
Its likely the deadlock here has been fixed for a long time, however
we should still do these in a task because it has to wait for base
components if they are not loaded yet.
* Adjust async_load_platform comment
Its likely the deadlock here has been fixed for a long time, however
we should still do these in a task because it has to wait for base
components if they are not loaded yet.
* Add missing platforms_exist guard to check_config
related issue #112811
When the exception hits, the config will end up being saved in the traceback
so the memory is never released.
This matches the check_config code to homeassistant.config to avoid having
the exception thrown.
* patch
* merge branch
This function was only ever used in homekit, and since there is
now an index of devices in the entity registry, homekit no longer
uses it.
I searched github code for all references to async_get_device_class_lookup
and the only think I could find using it were forks of core. It seems
unlikely that any custom components are affected by removing this
function
Co-authored-by: Sid <27780930+autinerd@users.noreply.github.com>
Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
* Small performance improvement to template expand
- Avoid fetching entity sources each loop
- Skip already found entities
- Avoid startswith in favor of equality check
* unneeded changes
* Use CONF_CORE to reference `homeassistant` domain
* Just use DOMAIN
* USE DOMAIN for `homeasistant` domain in config_schema.py
* Use DOMAIN_HA as constant for homeassistant domain
* Rename CONF_CORE to DOMAIN_HA
* Rename DOMAIN_HA to HA_DOMAIN
* Use relative import
* Use direct imports
* Refactor rate limit helper to track time in seconds
Currently we created datetime and timedelta objects to enforce the
rate limit. When the rate limit was being hit hard, this got expensive.
We now use floats everywhere instead as they are much cheaper which
is important when we are running up against a rate limit, which is
by definition a hot path
The rate limit helper is currently only used for templates and
we do not have any code in the code base that directly passes
in a rate limit so the impact to custom components is expected
to be negligible if any
* misesd two
* Cache parsing the url for the device registry
There are lots of hub integrations that use the same url for every
sub-device which results in a lot of url parsing at startup. The
logic can be simplified quite a bit here by only using yarl
for URLs
* fix onvif
* Refactor setup time tracking to exclude time waiting on other operations
We now exclude the import time and th time waiting on
base platforms to setup from the setup times
* tweak
* tweak
* tweak
* tweak
* adjust
* fixes
* fixes
* preen
* preen
* tweak
* tweak
* adjust
* tweak
* reduce
* do not count integrtion platforms against their parent integration
* handle legacy tts platforms
* stt as well
* one more wait
* use the same pattern in all the legacy
* fix tts and stt legacy
* fix
* fix
* reduce
* preen
* entity comp does not wait for platforms
* scene blocks as well
* fix test
* test fixes
* coverage
* coverage
* coverage
* fix test
* Update tests/test_setup.py
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
* Update tests/test_setup.py
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
* Update homeassistant/setup.py
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
* strip
* strip WAIT_PLATFORM_INTEGRATION
* strip WAIT_PLATFORM_INTEGRATION
* strip WAIT_PLATFORM_INTEGRATION
* strip WAIT_PLATFORM_INTEGRATION
* remove complexity
* Apply suggestions from code review
* no longer works that way
* fixes
* fixes
* fixes
---------
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
* Add category registry
* Add entity registry support
* Update homeassistant/components/config/entity_registry.py
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
* Use ulid instead
* Add tests for adding same name in different scopes
* Handle keyerror on update
* Lookup tweak
* Omit categories from entity registry snapshots
* Use base registry
* Update snapshots
* Update snapshots
---------
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
* Reduce script overhead by avoiding creation of many tasks
* no eager stop
* reduce
* make sure wait being cancelled is handled
* make sure wait being cancelled is handled
* make sure wait being cancelled is handled
* preen
* preen
* result already raises cancelled error, remove redundant code
* no need to raise it into the future
* will never set an exception
* Simplify long action script implementation
* comment
* preen
* dry
* dry
* preen
* dry
* preen
* no need to access protected
* no need to access protected
* dry
* name
* dry
* dry
* dry
* dry
* reduce name changes
* drop one more task
* stale comment
* stale comment
We save the device and entity registry to disk quite often, and
the cost of serializing them to the storage can block the event
loop for >100ms. Add a cache to reduce the change the loop is blocked
at an inopportune time at run time. The first write after startup
will still be a little slow but we do have to serialize the
bulk of it at least once as there is no way to avoid this
```
2024-03-14 11:28:19.765 WARNING (MainThread) [homeassistant.helpers.storage] Writing data with data_func: core.device_registry
2024-03-14 11:28:20.020 WARNING (MainThread) [homeassistant.helpers.storage] Writing data with data_func: core.entity_registry
2024-03-14 11:28:20.178 WARNING (MainThread) [asyncio] Executing <TimerHandle cancelled when=2319925.760294916 Store._async_schedule_callback_delayed_write() created at /Users/bdraco/home-assistant/homeassistant/helpers/storage.py:328> took 0.159 seconds
```
Construct storage data in the executor
Constructing storage data can be expensive for large files and can block the event
loop. While ideally we optimize the construction of the data, there are some places
we cannot make it any faster. To avoid blocking the loop, the construction of
the data is now done in the executor by running the data_func in the executor.
2024-03-14 11:28:20.178 WARNING (MainThread) [asyncio] Executing <TimerHandle cancelled when=2319925.760294916 Store._async_schedule_callback_delayed_write() created at /Users/bdraco/home-assistant/homeassistant/helpers/storage.py:328> took 0.159 seconds
There is some risk that the data_func is not thread-safe and needs to be run in
the event loop, but I could not find any cases in our existing code where it
would be a problem
* Add a helper to import modules in the event loop
Replaces the one used for triggers with a more generic helper
that can be reused and uses a future to avoid importing concurrently
* Add a helper to import modules in the event loop
Replaces the one used for triggers with a more generic helper
that can be reused and uses a future to avoid importing concurrently
* coverage
* make sure we do not retry
* coverage
There were a few places we were missing the set to list
conversions in the registries. We do this before its
cached to avoid the JSON serializer having to fallback
to the default method every time since its expensive
to switch back from the native code into python context
for every set.
Await discovery_function in the DiscoveryFlowHandler instead of wrapping
This function was always a coro so it can be awaited
directly instead of wrapping it in add_job
* Run coroutines as eager tasks in async_run_hass_job
Note that this does not change async_add_hass_job
Do not merge this. For test run only
* Phase out periodic tasks
* false by default or some tests will block forever, will need to fix each one manually
* kwarg works
* kwarg works
* kwarg works
* fixes
* fix more tests
* fix more tests
* fix lifx
* opensky
* pvpc_hourly_pricing
* adjust more
* adjust more
* smarttub
* adjust more
* adjust more
* adjust more
* adjust more
* adjust
* no eager executor
* zha
* qnap_qsw
* fix more
* fix fix
* docs
* its a wrapper now
* add more coverage
* coverage
* cover all combos
* more fixes
* more fixes
* more fixes
* remaining issues are legit bugs in tests
* make tplink test more predictable
* more fixes
* feedreader
* grind out some more
* make test race safe
* limit first scope to triggers
* one more
* Start tasks eagerly in for async_at_start(ed)
A few of these can avoid being scheduled on the loop
during startup
* fix cloud
* Revert "fix cloud"
This reverts commit 5eb3ce695d.
* fix test to do what start does
* flip flag
* flip flag
* Fix here_travel_time creating many refresh requests at startup
- Each entity would try to refresh the coordinator which
created many tasks. Move the refresh to a single
async_at_started
- The tests fired the EVENT_HOMEASSISTANT_START event
but the code used async_at_started which only worked
because the tests did not set CoreState to not_running
* fix azure
* remove kw
* remove kw
* rip
* cover
* more rips
* more rips
* more rips
* Phase out periodic tasks
* false by default or some tests will block forever, will need to fix each one manually
* kwarg works
* kwarg works
* kwarg works
* fixes
* fix more tests
* fix more tests
* fix lifx
* opensky
* pvpc_hourly_pricing
* adjust more
* adjust more
* smarttub
* adjust more
* adjust more
* adjust more
* adjust more
* adjust
* no eager executor
* zha
* qnap_qsw
* fix more
* fix fix
* docs
* its a wrapper now
* add more coverage
* coverage
* cover all combos
* more fixes
* more fixes
* more fixes
* remaining issues are legit bugs in tests
* make tplink test more predictable
* more fixes
* feedreader
* grind out some more
* make test race safe
* one more
* Schedule periodic coordinator updates as background tasks.
Currently, the coordinator's periodic refreshes delay startup because they are not scheduled as background tasks. We will wait if the startup takes long enough for the first planned refresh. Another coordinator's scheduled refresh will be fired on busy systems, further delaying the startup. This chain of events results in the startup taking a long time and hitting the safety timeout because too many coordinators are refreshing.
This case can also happen with scheduled entity refreshes, but it's less common. A future PR will address that case.
* periodic_tasks
* periodic_tasks
* periodic_tasks
* merge
* merge
* merge
* merge
* merge
* fix test that call the sync api from async
* one more place
* cannot chain
* async_run_periodic_hass_job
* sun and pattern time changes from automations also block startup
* Revert "sun and pattern time changes from automations also block startup"
This reverts commit 6de2defa05.
* make sure polling is cancelled when config entry is unloaded
* Revert "Revert "sun and pattern time changes from automations also block startup""
This reverts commit e8f12aad55.
* remove DisabledError from homewizard test as it relies on a race
* fix race
* direct coverage
These were very likely to be cached so they were low on the
list to migrate, but since they are called in the event loop
its best to be sure we do no blocking I/O
discovered in https://github.com/home-assistant/core/pull/112295#discussion_r1513505710
We only checked if the last language had files to load
instead of all of them. The checks for each language
are the same because the only reason we would skip
a language is a missing/broken integration or the integration
is a single file. Both of these loop conditions are always
the same reguardless of the language so the check worked
Some of the data we had to search for was already available
in a dict or underlying data structure. Make it available
instead of having to build it every time.
There are more places these can be used, but I only did
the device registry cleanup for now
* Add 'issues' template function for listing active issues.
* Add issue template function test
* Add 'issue' template function for getting specific issue by domain and issue_id
* Remove comment
* Fix function description
* Remove reduntant function,
Fix tests
* remove pass_context
* remove issues filter
Co-authored-by: Erik Montnemery <erik@montnemery.com>
---------
Co-authored-by: Erik Montnemery <erik@montnemery.com>
* Avoid trying to import platforms that do not exist
* adjust
* fixes
* cleanup
* cleanup
* cleanup
* Apply suggestions from code review
* docs
* fixes
* fixes
* comment
* coverage
* coverage
* coverage
* Switch config to use async_get_component
This was another path where integrations that were marked to load in the executor
would be loaded in the loop
* Switch config to use async_get_component/async_get_platform
This was another path where integrations that were marked to load in the executor
would be loaded in the loop
* merge
* refactor
* refactor
* coverage
* preen
* preen
* Avoid expensive inspect calls in config validators
inspect has a performance problem https://github.com/python/cpython/issues/92041
We now avoid calling inspect unless we are going to log
* remove unused
* reduce
* get_integration_logger
* Move HassSetPosition to homeassistant domain
* Add test for unsupported domain with HassSetPosition
* Split service intent handler
* cleanup
---------
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
* Deprecate @bind_hass and log error if used inside custom component
* Log also when accessing `hass.components`
* Log warning only when `hass.components` is used
* Change version
* Process code review
* Reduce latancy to load storage by making the task eager
This changes the semantics a bit under the hood because it
can raise sooner which means we do not store the task
as _load_task if it raises right away. That means
concurrent calls that result in failure are likely to try
again now which will be a tiny performance hit for this
case.
* fix
* will now finish in time
* Use an eager task to setup entity platforms
Ideally we would have awaited this function instead, but we want
to shield it from cancellation so we wrap it in asyncio.shield
which schedules it as a task. Since we have integrations that
never suspend in async_setup_entry, we can avoid scheduling on
the evnet loop with an eager task for this case
* its an executor future
* its an executor future
* fix
* doc string lied
* Use an eager task in the update coordinator scheduled refresh
We have a lot of places that will not suspend because the refresh function
decides it does not need to update. Currently these have to be scheduled
on the event loop even though they are a noop.
Since _handle_refresh_interval is subclassed in some integrations, I created
a dunder wrapper function to avoid integraions subclassing it
* fix time fires outside of patch
* Use eager task creation for entity platform polling
We have lots of places where `async_update` does not suspend and
is only a coro because its required to be a coro to run in the
event loop
* try again
The likely outcome from most discoveries is an near immediate abort
so we run them eagerly to avoid having to schedule on the event loop
for the common case
* Avoid circular import in Storage.async_delay_save
We call Storage.async_delay_save for every entity being added or removed
from the registry. The late import took more time than everything else
in the function.
* Avoid reschedule churn in Storage.async_delay_save
When we are adding or removing entities we will call async_delay_save
quite often which has to add and remove a TimerHandle on the event loop
which can add up when there are a lot of registry items changing.
If the timer handle still has 80% of the time remaining on it
we will avoid resceduling and let it fire at the time the
original async_delay_save call was made. This ensures we
do not force the event loop to rebuild its heapq because
too many timer handlers were cancelled at once
* div0
* add coverage for 0 since we had none
* fix bad conflict
* tweaks
* tweaks
* tweaks
* tweaks
* tweaks
* tweaks
* more test fixes
* mqtt tests rely on event loop overhead
* Convert debouncer async_shutdown to be a normal function
nothing was being awaited here and the shutdown call was only used
in integrations marked internal and other internals. Its possible
that a custom component might have been using the method but it
seemed uncommon enough that it did not warrent marking as a breaking
change. The update coordinator is no longer awaiting anything in
async_shutdown either now but it seemed likely that this use
would get subclassed.
* fix
Avoid linear search to remove from entity registry index
Because the entity registry index needs to preserve insertion order
for backwards compat, a list was used for the index. Because some
config entries/devices/areas have a large amount of entities, removing
the entities, the O(n) time complexity of removing from a list can
slow down reloads. As python has no orderedset in stdlib, use
a dict since it preserves insertion order has O(1) add/remove
time complexity for the average case
* Refactor keyed event trackers to avoid refactoring risk
Follow to https://github.com/home-assistant/core/pull/110978#discussion_r1496771106
I had to do some type ignores because of the EventType vs Event
which is hopefully not going to be needed after the next mypy
* delete constants only used one in other const
* no field
* fixes
* less refactoring later
* less refactoring later
* keep const
* Make adding entities in storage collection a normal function
Nothing is awaited when adding
* cleanup
* cleanup
* cleanup
* cleanup
* reduce
* reduce
* reduce
* reduce
* tweak
These functions created tasks to run small validators, and the cost of
creating all the tasks was more expensive than running the validators
themselves. Since the code is unlikely to suspend its more efficient to
await them in series.
* Add async_schedule_call to the Debouncer
async_schedule_call allows the Debouncer to schedule a call
from a callback without having to create tasks to run
async_call
* Update homeassistant/helpers/debounce.py
* Make device registry cleanup all callback function
* fix typing, code supported callback functions, but typing did not
* fixes
* fixes
* fix
* we had no coverage for other job types
* we had no coverage for other job types
* Reduce overhead to load multiple languages in translations
Instead of loading in a task, we now group everything
to be loaded into a single executor job
* fixes
* fixes
* fixes
* fixes
* fixes
* update tests
* add missing coverage (was existing)
* Add valve to HassTurnOn/Off
* Add set position for valves
* Add set position to covers
* Add HassTurnOn/Off for vacuums
* Add media player intents
* Split out vacuum intents
* Address comments
* Extra test
* Avoid creating tasks for checking integrations platforms
This is a followup to #110743 to avoid creating a task to check
if the integration platform exists. We created tasks because
we needed to await async_get_integrations but since its always
called from EVENT_COMPONENT_LOADED firing, we can use the
async_get_loaded_integration version which does not need
to be awaited. This eliminates one task for every loaded
component
* there is no more race risk
* reduce
* coro or callback
* reduce
* tweak
* race safe
* fix type
* fixes
* use built-in helper to make it smaller
* use built-in helper to make it smaller
* use built-in helper to make it smaller
* add coverage to ensure exceptions are logged
* improve readability a bit
* platforms
* Make context in data entry flow possible to modify for subclasses
* mypy
* Make get_context
* base view
* Review comments
* Remove context from options flow
* Add failing tests for package config validation error wrapping
* Wrap package schema validation errors in HomeAssistantError
* Fix yamllint errors
* Rework package merge validation
Ignore invalid package definitions instead of failing startup.
Output error messages with locations if possible when a package
definition has errors.
* Ruff format
* Fix linter errors
* Move package_definition_schema to module scope
* Move inner function to module level
* Merge exception handlers
Merge exception handlers for config schema validation and package merge
to avoid untested code branches
* Fix long lines and doc strings
* More minor changes to exception handler
---------
Co-authored-by: Erik Montnemery <erik@montnemery.com>