1
0
mirror of https://github.com/home-assistant/core.git synced 2025-08-21 19:30:02 +00:00
Files
.devcontainer
.github
.vscode
homeassistant
auth
backports
brands
components
generated
helpers
backports
service_info
__init__.py
aiohttp_client.py
area_registry.py
category_registry.py
check_config.py
collection.py
condition.py
config_entry_flow.py
config_entry_oauth2_flow.py
config_validation.py
data_entry_flow.py
debounce.py
deprecation.py
device_registry.py
discovery.py
discovery_flow.py
dispatcher.py
entity.py
entity_component.py
entity_platform.py
entity_registry.py
entity_values.py
entityfilter.py
event.py
floor_registry.py
frame.py
group.py
http.py
httpx_client.py
icon.py
importlib.py
instance_id.py
integration_platform.py
intent.py
issue_registry.py
json.py
label_registry.py
location.py
network.py
normalized_name_base_registry.py
ratelimit.py
recorder.py
redact.py
registry.py
reload.py
restore_state.py
schema_config_entry_flow.py
script.py
script_variables.py
selector.py
sensor.py
service.py
signal.py
significant_change.py
singleton.py
start.py
state.py
storage.py
sun.py
system_info.py
temperature.py
template.py
trace.py
translation.py
trigger.py
trigger_template_entity.py
typing.py
update_coordinator.py
scripts
util
__init__.py
__main__.py
block_async_io.py
bootstrap.py
config.py
config_entries.py
const.py
core.py
data_entry_flow.py
exceptions.py
loader.py
package_constraints.txt
py.typed
requirements.py
runner.py
setup.py
strings.json
machine
pylint
rootfs
script
tests
.core_files.yaml
.coveragerc
.dockerignore
.git-blame-ignore-revs
.gitattributes
.gitignore
.hadolint.yaml
.pre-commit-config.yaml
.prettierignore
.strict-typing
.yamllint
CLA.md
CODEOWNERS
CODE_OF_CONDUCT.md
CONTRIBUTING.md
Dockerfile
Dockerfile.dev
LICENSE.md
MANIFEST.in
README.rst
build.yaml
codecov.yml
mypy.ini
pyproject.toml
requirements.txt
requirements_all.txt
requirements_test.txt
requirements_test_all.txt
requirements_test_pre_commit.txt
core/homeassistant/helpers/state.py

99 lines
2.5 KiB
Python

"""Helpers that help with state related things."""
from __future__ import annotations
import asyncio
from collections import defaultdict
from collections.abc import Iterable
import logging
from types import ModuleType
from typing import Any
from homeassistant.components.sun import STATE_ABOVE_HORIZON, STATE_BELOW_HORIZON
from homeassistant.const import (
STATE_CLOSED,
STATE_HOME,
STATE_LOCKED,
STATE_NOT_HOME,
STATE_OFF,
STATE_ON,
STATE_OPEN,
STATE_UNKNOWN,
STATE_UNLOCKED,
)
from homeassistant.core import Context, HomeAssistant, State
from homeassistant.loader import IntegrationNotFound, async_get_integration, bind_hass
_LOGGER = logging.getLogger(__name__)
@bind_hass
async def async_reproduce_state(
hass: HomeAssistant,
states: State | Iterable[State],
*,
context: Context | None = None,
reproduce_options: dict[str, Any] | None = None,
) -> None:
"""Reproduce a list of states on multiple domains."""
if isinstance(states, State):
states = [states]
to_call: dict[str, list[State]] = defaultdict(list)
for state in states:
to_call[state.domain].append(state)
async def worker(domain: str, states_by_domain: list[State]) -> None:
try:
integration = await async_get_integration(hass, domain)
except IntegrationNotFound:
_LOGGER.warning(
"Trying to reproduce state for unknown integration: %s", domain
)
return
try:
platform: ModuleType = await integration.async_get_platform(
"reproduce_state"
)
except ImportError:
_LOGGER.warning("Integration %s does not support reproduce state", domain)
return
await platform.async_reproduce_states(
hass, states_by_domain, context=context, reproduce_options=reproduce_options
)
if to_call:
# run all domains in parallel
await asyncio.gather(
*(worker(domain, data) for domain, data in to_call.items())
)
def state_as_number(state: State) -> float:
"""Try to coerce our state to a number.
Raises ValueError if this is not possible.
"""
if state.state in (
STATE_ON,
STATE_LOCKED,
STATE_ABOVE_HORIZON,
STATE_OPEN,
STATE_HOME,
):
return 1
if state.state in (
STATE_OFF,
STATE_UNLOCKED,
STATE_UNKNOWN,
STATE_BELOW_HORIZON,
STATE_CLOSED,
STATE_NOT_HOME,
):
return 0
return float(state.state)