forked from home-assistant/core
Compare commits
7 Commits
improve_tr
...
get_automa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e00e15fa5 | ||
|
|
3e19b5f6d5 | ||
|
|
3f1d3bfc4a | ||
|
|
08a8bfaf8f | ||
|
|
31f8ea523f | ||
|
|
0924740cb4 | ||
|
|
9f039002ff |
@@ -55,6 +55,7 @@ from homeassistant.helpers.deprecation import (
|
||||
DeprecatedConstantEnum,
|
||||
all_with_deprecated_constants,
|
||||
check_if_deprecated_constant,
|
||||
deprecated_function,
|
||||
dir_with_deprecated_constants,
|
||||
)
|
||||
from homeassistant.helpers.entity import Entity, EntityDescription
|
||||
@@ -85,10 +86,10 @@ from .prefs import CameraPreferences, DynamicStreamSettings # noqa: F401
|
||||
from .webrtc import (
|
||||
DATA_ICE_SERVERS,
|
||||
CameraWebRTCProvider,
|
||||
WebRTCAnswer, # noqa: F401
|
||||
WebRTCAnswer,
|
||||
WebRTCCandidate, # noqa: F401
|
||||
WebRTCClientConfiguration,
|
||||
WebRTCError, # noqa: F401
|
||||
WebRTCError,
|
||||
WebRTCMessage, # noqa: F401
|
||||
WebRTCSendMessage,
|
||||
async_get_supported_provider,
|
||||
@@ -472,6 +473,9 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
self.async_update_token()
|
||||
self._create_stream_lock: asyncio.Lock | None = None
|
||||
self._webrtc_provider: CameraWebRTCProvider | None = None
|
||||
self._supports_native_sync_webrtc = (
|
||||
type(self).async_handle_web_rtc_offer != Camera.async_handle_web_rtc_offer
|
||||
)
|
||||
self._supports_native_async_webrtc = (
|
||||
type(self).async_handle_async_webrtc_offer
|
||||
!= Camera.async_handle_async_webrtc_offer
|
||||
@@ -575,6 +579,15 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
"""
|
||||
return None
|
||||
|
||||
async def async_handle_web_rtc_offer(self, offer_sdp: str) -> str | None:
|
||||
"""Handle the WebRTC offer and return an answer.
|
||||
|
||||
This is used by cameras with CameraEntityFeature.STREAM
|
||||
and StreamType.WEB_RTC.
|
||||
|
||||
Integrations can override with a native WebRTC implementation.
|
||||
"""
|
||||
|
||||
async def async_handle_async_webrtc_offer(
|
||||
self, offer_sdp: str, session_id: str, send_message: WebRTCSendMessage
|
||||
) -> None:
|
||||
@@ -587,6 +600,42 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
|
||||
Integrations can override with a native WebRTC implementation.
|
||||
"""
|
||||
if self._supports_native_sync_webrtc:
|
||||
try:
|
||||
answer = await deprecated_function(
|
||||
"async_handle_async_webrtc_offer",
|
||||
breaks_in_ha_version="2025.6",
|
||||
)(self.async_handle_web_rtc_offer)(offer_sdp)
|
||||
except ValueError as ex:
|
||||
_LOGGER.error("Error handling WebRTC offer: %s", ex)
|
||||
send_message(
|
||||
WebRTCError(
|
||||
"webrtc_offer_failed",
|
||||
str(ex),
|
||||
)
|
||||
)
|
||||
except TimeoutError:
|
||||
# This catch was already here and should stay through the deprecation
|
||||
_LOGGER.error("Timeout handling WebRTC offer")
|
||||
send_message(
|
||||
WebRTCError(
|
||||
"webrtc_offer_failed",
|
||||
"Timeout handling WebRTC offer",
|
||||
)
|
||||
)
|
||||
else:
|
||||
if answer:
|
||||
send_message(WebRTCAnswer(answer))
|
||||
else:
|
||||
_LOGGER.error("Error handling WebRTC offer: No answer")
|
||||
send_message(
|
||||
WebRTCError(
|
||||
"webrtc_offer_failed",
|
||||
"No answer on WebRTC offer",
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
if self._webrtc_provider:
|
||||
await self._webrtc_provider.async_handle_async_webrtc_offer(
|
||||
self, offer_sdp, session_id, send_message
|
||||
@@ -715,7 +764,9 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
new_provider = None
|
||||
|
||||
# Skip all providers if the camera has a native WebRTC implementation
|
||||
if not self._supports_native_async_webrtc:
|
||||
if not (
|
||||
self._supports_native_sync_webrtc or self._supports_native_async_webrtc
|
||||
):
|
||||
# Camera doesn't have a native WebRTC implementation
|
||||
new_provider = await self._async_get_supported_webrtc_provider(
|
||||
async_get_supported_provider
|
||||
@@ -747,12 +798,17 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
"""Return the WebRTC client configuration and extend it with the registered ice servers."""
|
||||
config = self._async_get_webrtc_client_configuration()
|
||||
|
||||
ice_servers = [
|
||||
server
|
||||
for servers in self.hass.data.get(DATA_ICE_SERVERS, [])
|
||||
for server in servers()
|
||||
]
|
||||
config.configuration.ice_servers.extend(ice_servers)
|
||||
if not self._supports_native_sync_webrtc:
|
||||
# Until 2024.11, the frontend was not resolving any ice servers
|
||||
# The async approach was added 2024.11 and new integrations need to use it
|
||||
ice_servers = [
|
||||
server
|
||||
for servers in self.hass.data.get(DATA_ICE_SERVERS, [])
|
||||
for server in servers()
|
||||
]
|
||||
config.configuration.ice_servers.extend(ice_servers)
|
||||
|
||||
config.get_candidates_upfront = self._supports_native_sync_webrtc
|
||||
|
||||
return config
|
||||
|
||||
@@ -782,7 +838,7 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
"""Return the camera capabilities."""
|
||||
frontend_stream_types = set()
|
||||
if CameraEntityFeature.STREAM in self.supported_features_compat:
|
||||
if self._supports_native_async_webrtc:
|
||||
if self._supports_native_sync_webrtc or self._supports_native_async_webrtc:
|
||||
# The camera has a native WebRTC implementation
|
||||
frontend_stream_types.add(StreamType.WEB_RTC)
|
||||
else:
|
||||
|
||||
@@ -111,11 +111,13 @@ class WebRTCClientConfiguration:
|
||||
|
||||
configuration: RTCConfiguration = field(default_factory=RTCConfiguration)
|
||||
data_channel: str | None = None
|
||||
get_candidates_upfront: bool = False
|
||||
|
||||
def to_frontend_dict(self) -> dict[str, Any]:
|
||||
"""Return a dict that can be used by the frontend."""
|
||||
data: dict[str, Any] = {
|
||||
"configuration": self.configuration.to_dict(),
|
||||
"getCandidatesUpfront": self.get_candidates_upfront,
|
||||
}
|
||||
if self.data_channel is not None:
|
||||
data["dataChannel"] = self.data_channel
|
||||
|
||||
@@ -43,7 +43,6 @@ VALID_REPAIR_TRANSLATION_KEYS = {
|
||||
"no_subscription",
|
||||
"warn_bad_custom_domain_configuration",
|
||||
"reset_bad_custom_domain_configuration",
|
||||
"subscription_expired",
|
||||
}
|
||||
|
||||
|
||||
@@ -405,12 +404,7 @@ class CloudClient(Interface):
|
||||
) -> None:
|
||||
"""Create a repair issue."""
|
||||
if translation_key not in VALID_REPAIR_TRANSLATION_KEYS:
|
||||
_LOGGER.error(
|
||||
"Invalid translation key %s for repair issue %s",
|
||||
translation_key,
|
||||
identifier,
|
||||
)
|
||||
return
|
||||
raise ValueError(f"Invalid translation key {translation_key}")
|
||||
async_create_issue(
|
||||
hass=self._hass,
|
||||
domain=DOMAIN,
|
||||
|
||||
@@ -73,10 +73,6 @@
|
||||
"reset_bad_custom_domain_configuration": {
|
||||
"title": "Custom domain ignored",
|
||||
"description": "The DNS configuration for your custom domain ({custom_domains}) is not correct. This domain has now been ignored and will not be used for Home Assistant Cloud. If you want to use this domain, please fix the DNS configuration and restart Home Assistant. If you do not need this anymore, you can remove it from the account page."
|
||||
},
|
||||
"subscription_expired": {
|
||||
"title": "Subscription has expired",
|
||||
"description": "Your Home Assistant Cloud subscription has expired. Resubscribe at {account_url}."
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["aiocomelit"],
|
||||
"quality_scale": "bronze",
|
||||
"requirements": ["aiocomelit==0.12.1"]
|
||||
"requirements": ["aiocomelit==0.12.0"]
|
||||
}
|
||||
|
||||
@@ -9,12 +9,13 @@ import voluptuous as vol
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components import websocket_api
|
||||
from homeassistant.components.websocket_api import ERR_NOT_FOUND, require_admin
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.core import HomeAssistant, callback, split_entity_id
|
||||
from homeassistant.helpers import (
|
||||
config_validation as cv,
|
||||
device_registry as dr,
|
||||
entity_registry as er,
|
||||
)
|
||||
from homeassistant.helpers.entity_component import async_get_entity_suggested_object_id
|
||||
from homeassistant.helpers.json import json_dumps
|
||||
|
||||
|
||||
@@ -22,6 +23,7 @@ from homeassistant.helpers.json import json_dumps
|
||||
def async_setup(hass: HomeAssistant) -> bool:
|
||||
"""Enable the Entity Registry views."""
|
||||
|
||||
websocket_api.async_register_command(hass, websocket_get_automatic_entity_ids)
|
||||
websocket_api.async_register_command(hass, websocket_get_entities)
|
||||
websocket_api.async_register_command(hass, websocket_get_entity)
|
||||
websocket_api.async_register_command(hass, websocket_list_entities_for_display)
|
||||
@@ -316,3 +318,43 @@ def websocket_remove_entity(
|
||||
|
||||
registry.async_remove(msg["entity_id"])
|
||||
connection.send_message(websocket_api.result_message(msg["id"]))
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "config/entity_registry/get_automatic_entity_ids",
|
||||
vol.Required("entity_ids"): cv.entity_ids,
|
||||
}
|
||||
)
|
||||
@callback
|
||||
def websocket_get_automatic_entity_ids(
|
||||
hass: HomeAssistant,
|
||||
connection: websocket_api.ActiveConnection,
|
||||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Return the automatic entity IDs for the given entity IDs.
|
||||
|
||||
This is used to help user reset entity IDs which have been customized by the user.
|
||||
"""
|
||||
registry = er.async_get(hass)
|
||||
|
||||
entity_ids = msg["entity_ids"]
|
||||
automatic_entity_ids: dict[str, str | None] = {}
|
||||
for entity_id in entity_ids:
|
||||
if not (entry := registry.entities.get(entity_id)):
|
||||
automatic_entity_ids[entity_id] = None
|
||||
continue
|
||||
if (
|
||||
suggested := async_get_entity_suggested_object_id(hass, entity_id)
|
||||
) == split_entity_id(entry.entity_id)[1]:
|
||||
# No need to generate a new entity ID
|
||||
automatic_entity_ids[entity_id] = None
|
||||
continue
|
||||
automatic_entity_ids[entity_id] = registry.async_generate_entity_id(
|
||||
entry.domain,
|
||||
suggested or f"{entry.platform}_{entry.unique_id}",
|
||||
)
|
||||
|
||||
connection.send_message(
|
||||
websocket_api.result_message(msg["id"], automatic_entity_ids)
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
],
|
||||
"quality_scale": "internal",
|
||||
"requirements": [
|
||||
"aiodhcpwatcher==1.2.0",
|
||||
"aiodhcpwatcher==1.1.1",
|
||||
"aiodiscover==2.7.0",
|
||||
"cached-ipaddress==0.10.0"
|
||||
]
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
"ac_module_temperature_sensor_faulty_l2": "AC module temperature sensor faulty (L2)",
|
||||
"dc_component_measured_in_grid_too_high": "DC component measured in the grid too high",
|
||||
"fixed_voltage_mode_out_of_range": "Fixed voltage mode has been selected instead of MPP voltage mode and the fixed voltage has been set to too low or too high a value",
|
||||
"safety_cut_out_triggered": "Safety cut-out via option card or RECERBO has triggered",
|
||||
"safety_cut_out_triggered": "Safety cut out via option card or RECERBO has triggered",
|
||||
"no_communication_between_power_stage_and_control_system": "No communication possible between power stage set and control system",
|
||||
"hardware_id_problem": "Hardware ID problem",
|
||||
"unique_id_conflict": "Unique ID conflict",
|
||||
@@ -148,7 +148,7 @@
|
||||
"update_file_does_not_match_device": "Update file does not match the device, update file too old",
|
||||
"write_or_read_error_occurred": "Write or read error occurred",
|
||||
"file_could_not_be_opened": "File could not be opened",
|
||||
"log_file_cannot_be_saved": "Log file cannot be saved (e.g. USB flash drive is write-protected or full)",
|
||||
"log_file_cannot_be_saved": "Log file cannot be saved (e.g. USB flash drive is write protected or full)",
|
||||
"initialisation_error_file_system_error_on_usb": "Initialization error in file system on USB flash drive",
|
||||
"error_during_logging_data_recording": "Error during recording of logging data",
|
||||
"error_during_update_process": "Error occurred during update process",
|
||||
@@ -166,7 +166,7 @@
|
||||
"invalid_device_type": "Invalid device type",
|
||||
"insulation_measurement_triggered": "Insulation measurement triggered",
|
||||
"inverter_settings_changed_restart_required": "Inverter settings have been changed, inverter restart required",
|
||||
"wired_shut_down_triggered": "Wired shutdown triggered",
|
||||
"wired_shut_down_triggered": "Wired shut down triggered",
|
||||
"grid_frequency_exceeded_limit_reconnecting": "The grid frequency has exceeded a limit value when reconnecting",
|
||||
"mains_voltage_dependent_power_reduction": "Mains voltage-dependent power reduction",
|
||||
"too_little_dc_power_for_feed_in_operation": "Too little DC power for feed-in operation",
|
||||
|
||||
@@ -14,78 +14,49 @@ from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.storage import Store
|
||||
from homeassistant.util.hass_dict import HassKey
|
||||
|
||||
DATA_STORAGE: HassKey[dict[str, UserStore]] = HassKey("frontend_storage")
|
||||
DATA_STORAGE: HassKey[tuple[dict[str, Store], dict[str, dict]]] = HassKey(
|
||||
"frontend_storage"
|
||||
)
|
||||
STORAGE_VERSION_USER_DATA = 1
|
||||
|
||||
|
||||
@callback
|
||||
def _initialize_frontend_storage(hass: HomeAssistant) -> None:
|
||||
"""Set up frontend storage."""
|
||||
if DATA_STORAGE in hass.data:
|
||||
return
|
||||
hass.data[DATA_STORAGE] = ({}, {})
|
||||
|
||||
|
||||
async def async_setup_frontend_storage(hass: HomeAssistant) -> None:
|
||||
"""Set up frontend storage."""
|
||||
_initialize_frontend_storage(hass)
|
||||
websocket_api.async_register_command(hass, websocket_set_user_data)
|
||||
websocket_api.async_register_command(hass, websocket_get_user_data)
|
||||
websocket_api.async_register_command(hass, websocket_subscribe_user_data)
|
||||
|
||||
|
||||
async def async_user_store(hass: HomeAssistant, user_id: str) -> UserStore:
|
||||
async def async_user_store(
|
||||
hass: HomeAssistant, user_id: str
|
||||
) -> tuple[Store, dict[str, Any]]:
|
||||
"""Access a user store."""
|
||||
stores = hass.data.setdefault(DATA_STORAGE, {})
|
||||
_initialize_frontend_storage(hass)
|
||||
stores, data = hass.data[DATA_STORAGE]
|
||||
if (store := stores.get(user_id)) is None:
|
||||
store = stores[user_id] = UserStore(hass, user_id)
|
||||
await store.async_load()
|
||||
|
||||
return store
|
||||
|
||||
|
||||
class UserStore:
|
||||
"""User store for frontend data."""
|
||||
|
||||
def __init__(self, hass: HomeAssistant, user_id: str) -> None:
|
||||
"""Initialize the user store."""
|
||||
self._store = _UserStore(hass, user_id)
|
||||
self.data: dict[str, Any] = {}
|
||||
self.subscriptions: dict[str | None, list[Callable[[], None]]] = {}
|
||||
|
||||
async def async_load(self) -> None:
|
||||
"""Load the data from the store."""
|
||||
self.data = await self._store.async_load() or {}
|
||||
|
||||
async def async_set_item(self, key: str, value: Any) -> None:
|
||||
"""Set an item item and save the store."""
|
||||
self.data[key] = value
|
||||
await self._store.async_save(self.data)
|
||||
for cb in self.subscriptions.get(None, []):
|
||||
cb()
|
||||
for cb in self.subscriptions.get(key, []):
|
||||
cb()
|
||||
|
||||
@callback
|
||||
def async_subscribe(
|
||||
self, key: str | None, on_update_callback: Callable[[], None]
|
||||
) -> Callable[[], None]:
|
||||
"""Save the data to the store."""
|
||||
self.subscriptions.setdefault(key, []).append(on_update_callback)
|
||||
|
||||
def unsubscribe() -> None:
|
||||
"""Unsubscribe from the store."""
|
||||
self.subscriptions[key].remove(on_update_callback)
|
||||
|
||||
return unsubscribe
|
||||
|
||||
|
||||
class _UserStore(Store[dict[str, Any]]):
|
||||
"""User store for frontend data."""
|
||||
|
||||
def __init__(self, hass: HomeAssistant, user_id: str) -> None:
|
||||
"""Initialize the user store."""
|
||||
super().__init__(
|
||||
store = stores[user_id] = Store(
|
||||
hass,
|
||||
STORAGE_VERSION_USER_DATA,
|
||||
f"frontend.user_data_{user_id}",
|
||||
)
|
||||
|
||||
if user_id not in data:
|
||||
data[user_id] = await store.async_load() or {}
|
||||
|
||||
def with_user_store(
|
||||
return store, data[user_id]
|
||||
|
||||
|
||||
def with_store(
|
||||
orig_func: Callable[
|
||||
[HomeAssistant, ActiveConnection, dict[str, Any], UserStore],
|
||||
[HomeAssistant, ActiveConnection, dict[str, Any], Store, dict[str, Any]],
|
||||
Coroutine[Any, Any, None],
|
||||
],
|
||||
) -> Callable[
|
||||
@@ -94,17 +65,17 @@ def with_user_store(
|
||||
"""Decorate function to provide data."""
|
||||
|
||||
@wraps(orig_func)
|
||||
async def with_user_store_func(
|
||||
async def with_store_func(
|
||||
hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any]
|
||||
) -> None:
|
||||
"""Provide user specific data and store to function."""
|
||||
user_id = connection.user.id
|
||||
|
||||
store = await async_user_store(hass, user_id)
|
||||
store, user_data = await async_user_store(hass, user_id)
|
||||
|
||||
await orig_func(hass, connection, msg, store)
|
||||
await orig_func(hass, connection, msg, store, user_data)
|
||||
|
||||
return with_user_store_func
|
||||
return with_store_func
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
@@ -115,57 +86,41 @@ def with_user_store(
|
||||
}
|
||||
)
|
||||
@websocket_api.async_response
|
||||
@with_user_store
|
||||
@with_store
|
||||
async def websocket_set_user_data(
|
||||
hass: HomeAssistant,
|
||||
connection: ActiveConnection,
|
||||
msg: dict[str, Any],
|
||||
store: UserStore,
|
||||
store: Store,
|
||||
data: dict[str, Any],
|
||||
) -> None:
|
||||
"""Handle set user data command."""
|
||||
await store.async_set_item(msg["key"], msg["value"])
|
||||
connection.send_result(msg["id"])
|
||||
"""Handle set global data command.
|
||||
|
||||
Async friendly.
|
||||
"""
|
||||
data[msg["key"]] = msg["value"]
|
||||
await store.async_save(data)
|
||||
connection.send_message(websocket_api.result_message(msg["id"]))
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
{vol.Required("type"): "frontend/get_user_data", vol.Optional("key"): str}
|
||||
)
|
||||
@websocket_api.async_response
|
||||
@with_user_store
|
||||
@with_store
|
||||
async def websocket_get_user_data(
|
||||
hass: HomeAssistant,
|
||||
connection: ActiveConnection,
|
||||
msg: dict[str, Any],
|
||||
store: UserStore,
|
||||
store: Store,
|
||||
data: dict[str, Any],
|
||||
) -> None:
|
||||
"""Handle get user data command."""
|
||||
data = store.data
|
||||
connection.send_result(
|
||||
msg["id"], {"value": data.get(msg["key"]) if "key" in msg else data}
|
||||
)
|
||||
"""Handle get global data command.
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
{vol.Required("type"): "frontend/subscribe_user_data", vol.Optional("key"): str}
|
||||
)
|
||||
@websocket_api.async_response
|
||||
@with_user_store
|
||||
async def websocket_subscribe_user_data(
|
||||
hass: HomeAssistant,
|
||||
connection: ActiveConnection,
|
||||
msg: dict[str, Any],
|
||||
store: UserStore,
|
||||
) -> None:
|
||||
"""Handle subscribe to user data command."""
|
||||
key: str | None = msg.get("key")
|
||||
|
||||
def on_data_update() -> None:
|
||||
"""Handle user data update."""
|
||||
data = store.data
|
||||
connection.send_event(
|
||||
msg["id"], {"value": data.get(key) if key is not None else data}
|
||||
Async friendly.
|
||||
"""
|
||||
connection.send_message(
|
||||
websocket_api.result_message(
|
||||
msg["id"], {"value": data.get(msg["key"]) if "key" in msg else data}
|
||||
)
|
||||
|
||||
connection.subscriptions[msg["id"]] = store.async_subscribe(key, on_data_update)
|
||||
on_data_update()
|
||||
connection.send_result(msg["id"])
|
||||
)
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/google",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["googleapiclient"],
|
||||
"requirements": ["gcal-sync==7.0.1", "oauth2client==4.1.3", "ical==9.2.2"]
|
||||
"requirements": ["gcal-sync==7.0.0", "oauth2client==4.1.3", "ical==9.2.1"]
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@ import jwt
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import SOURCE_REAUTH, ConfigFlowResult
|
||||
from homeassistant.helpers import config_entry_oauth2_flow, device_registry as dr
|
||||
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo
|
||||
from homeassistant.helpers import config_entry_oauth2_flow
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
@@ -59,22 +58,3 @@ class OAuth2FlowHandler(
|
||||
)
|
||||
self._abort_if_unique_id_configured()
|
||||
return await super().async_oauth_create_entry(data)
|
||||
|
||||
async def async_step_dhcp(
|
||||
self, discovery_info: DhcpServiceInfo
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle a DHCP discovery."""
|
||||
device_registry = dr.async_get(self.hass)
|
||||
if device_entry := device_registry.async_get_device(
|
||||
identifiers={
|
||||
(DOMAIN, discovery_info.hostname),
|
||||
(DOMAIN, discovery_info.hostname.split("-")[-1]),
|
||||
}
|
||||
):
|
||||
device_registry.async_update_device(
|
||||
device_entry.id,
|
||||
new_connections={
|
||||
(dr.CONNECTION_NETWORK_MAC, discovery_info.macaddress)
|
||||
},
|
||||
)
|
||||
return await super().async_step_dhcp(discovery_info)
|
||||
|
||||
@@ -110,14 +110,14 @@ class AutomowerLawnMowerEntity(AutomowerAvailableEntity, LawnMowerEntity):
|
||||
mower_attributes = self.mower_attributes
|
||||
if mower_attributes.mower.state in PAUSED_STATES:
|
||||
return LawnMowerActivity.PAUSED
|
||||
if (mower_attributes.mower.state == "RESTRICTED") or (
|
||||
mower_attributes.mower.activity in DOCKED_ACTIVITIES
|
||||
):
|
||||
return LawnMowerActivity.DOCKED
|
||||
if mower_attributes.mower.state in MowerStates.IN_OPERATION:
|
||||
if mower_attributes.mower.activity == MowerActivities.GOING_HOME:
|
||||
return LawnMowerActivity.RETURNING
|
||||
return LawnMowerActivity.MOWING
|
||||
if (mower_attributes.mower.state == "RESTRICTED") or (
|
||||
mower_attributes.mower.activity in DOCKED_ACTIVITIES
|
||||
):
|
||||
return LawnMowerActivity.DOCKED
|
||||
return LawnMowerActivity.ERROR
|
||||
|
||||
@property
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["xknx", "xknxproject"],
|
||||
"requirements": [
|
||||
"xknx==3.8.0",
|
||||
"xknx==3.6.0",
|
||||
"xknxproject==3.8.2",
|
||||
"knx-frontend==2025.4.1.91934"
|
||||
],
|
||||
|
||||
@@ -19,6 +19,7 @@ from homeassistant.const import (
|
||||
CONF_PORT,
|
||||
CONF_USERNAME,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
@@ -43,6 +44,21 @@ CONFIG_SCHEMA = vol.Schema(CONFIG_DATA)
|
||||
USER_SCHEMA = vol.Schema(USER_DATA)
|
||||
|
||||
|
||||
def get_config_entry(
|
||||
hass: HomeAssistant, data: ConfigType
|
||||
) -> config_entries.ConfigEntry | None:
|
||||
"""Check config entries for already configured entries based on the ip address/port."""
|
||||
return next(
|
||||
(
|
||||
entry
|
||||
for entry in hass.config_entries.async_entries(DOMAIN)
|
||||
if entry.data[CONF_IP_ADDRESS] == data[CONF_IP_ADDRESS]
|
||||
and entry.data[CONF_PORT] == data[CONF_PORT]
|
||||
),
|
||||
None,
|
||||
)
|
||||
|
||||
|
||||
async def validate_connection(data: ConfigType) -> str | None:
|
||||
"""Validate if a connection to LCN can be established."""
|
||||
error = None
|
||||
@@ -104,20 +120,19 @@ class LcnFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
if user_input is None:
|
||||
return self.async_show_form(step_id="user", data_schema=USER_SCHEMA)
|
||||
|
||||
self._async_abort_entries_match(
|
||||
{
|
||||
CONF_IP_ADDRESS: user_input[CONF_IP_ADDRESS],
|
||||
CONF_PORT: user_input[CONF_PORT],
|
||||
}
|
||||
)
|
||||
errors = None
|
||||
if get_config_entry(self.hass, user_input):
|
||||
errors = {CONF_BASE: "already_configured"}
|
||||
elif (error := await validate_connection(user_input)) is not None:
|
||||
errors = {CONF_BASE: error}
|
||||
|
||||
if (error := await validate_connection(user_input)) is not None:
|
||||
if errors is not None:
|
||||
return self.async_show_form(
|
||||
step_id="user",
|
||||
data_schema=self.add_suggested_values_to_schema(
|
||||
USER_SCHEMA, user_input
|
||||
),
|
||||
errors={CONF_BASE: error},
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
data: dict = {
|
||||
@@ -137,21 +152,15 @@ class LcnFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
if user_input is not None:
|
||||
user_input[CONF_HOST] = reconfigure_entry.data[CONF_HOST]
|
||||
|
||||
self._async_abort_entries_match(
|
||||
{
|
||||
CONF_IP_ADDRESS: user_input[CONF_IP_ADDRESS],
|
||||
CONF_PORT: user_input[CONF_PORT],
|
||||
}
|
||||
)
|
||||
|
||||
await self.hass.config_entries.async_unload(reconfigure_entry.entry_id)
|
||||
if (error := await validate_connection(user_input)) is not None:
|
||||
errors = {CONF_BASE: error}
|
||||
|
||||
if (error := await validate_connection(user_input)) is None:
|
||||
if errors is None:
|
||||
return self.async_update_reload_and_abort(
|
||||
reconfigure_entry, data_updates=user_input
|
||||
)
|
||||
|
||||
errors = {CONF_BASE: error}
|
||||
await self.hass.config_entries.async_setup(reconfigure_entry.entry_id)
|
||||
|
||||
return self.async_show_form(
|
||||
|
||||
@@ -66,11 +66,11 @@
|
||||
"error": {
|
||||
"authentication_error": "Authentication failed. Wrong username or password.",
|
||||
"license_error": "Maximum number of connections was reached. An additional licence key is required.",
|
||||
"connection_refused": "Unable to connect to PCHK. Check IP and port."
|
||||
"connection_refused": "Unable to connect to PCHK. Check IP and port.",
|
||||
"already_configured": "PCHK connection using the same ip address/port is already configured."
|
||||
},
|
||||
"abort": {
|
||||
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]",
|
||||
"already_configured": "PCHK connection using the same ip address/port is already configured."
|
||||
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]"
|
||||
}
|
||||
},
|
||||
"issues": {
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/local_calendar",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["ical"],
|
||||
"requirements": ["ical==9.2.2"]
|
||||
"requirements": ["ical==9.2.1"]
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/local_todo",
|
||||
"iot_class": "local_polling",
|
||||
"requirements": ["ical==9.2.2"]
|
||||
"requirements": ["ical==9.2.1"]
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@ from .const import MieleAppliance
|
||||
from .coordinator import MieleConfigEntry
|
||||
from .entity import MieleEntity
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
||||
@@ -17,8 +17,6 @@ from .const import DOMAIN, PROCESS_ACTION, MieleActions, MieleAppliance
|
||||
from .coordinator import MieleConfigEntry
|
||||
from .entity import MieleEntity
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
||||
@@ -26,8 +26,6 @@ from .const import DEVICE_TYPE_TAGS, DISABLED_TEMP_ENTITIES, DOMAIN, MieleApplia
|
||||
from .coordinator import MieleConfigEntry, MieleDataUpdateCoordinator
|
||||
from .entity import MieleEntity
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
||||
@@ -27,8 +27,6 @@ from .const import DOMAIN, POWER_OFF, POWER_ON, VENTILATION_STEP, MieleAppliance
|
||||
from .coordinator import MieleConfigEntry, MieleDataUpdateCoordinator
|
||||
from .entity import MieleEntity
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SPEED_RANGE = (1, 4)
|
||||
|
||||
@@ -32,9 +32,6 @@
|
||||
"core_target_temperature": {
|
||||
"default": "mdi:thermometer-probe"
|
||||
},
|
||||
"target_temperature": {
|
||||
"default": "mdi:thermometer-check"
|
||||
},
|
||||
"drying_step": {
|
||||
"default": "mdi:water-outline"
|
||||
},
|
||||
|
||||
@@ -23,8 +23,6 @@ from .const import AMBIENT_LIGHT, DOMAIN, LIGHT, LIGHT_OFF, LIGHT_ON, MieleAppli
|
||||
from .coordinator import MieleConfigEntry
|
||||
from .entity import MieleDevice, MieleEntity
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
||||
@@ -32,23 +32,18 @@ rules:
|
||||
Handled by a setting in manifest.json as there is no account information in API
|
||||
|
||||
# Silver
|
||||
action-exceptions:
|
||||
status: done
|
||||
comment: No custom actions are defined
|
||||
action-exceptions: todo
|
||||
config-entry-unloading: done
|
||||
docs-configuration-parameters:
|
||||
status: exempt
|
||||
comment: No configuration parameters
|
||||
docs-installation-parameters:
|
||||
status: exempt
|
||||
comment: |
|
||||
Integration uses account linking via Nabu casa so no installation parameters are needed.
|
||||
docs-installation-parameters: todo
|
||||
entity-unavailable: done
|
||||
integration-owner: done
|
||||
log-when-unavailable:
|
||||
status: done
|
||||
comment: Handled by DataUpdateCoordinator
|
||||
parallel-updates: done
|
||||
log-when-unavailable: todo
|
||||
parallel-updates:
|
||||
status: exempt
|
||||
comment: Handled by coordinator
|
||||
reauthentication-flow: done
|
||||
test-coverage: todo
|
||||
|
||||
|
||||
@@ -39,8 +39,6 @@ from .const import (
|
||||
from .coordinator import MieleConfigEntry, MieleDataUpdateCoordinator
|
||||
from .entity import MieleEntity
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DISABLED_TEMPERATURE = -32768
|
||||
@@ -384,7 +382,6 @@ SENSOR_TYPES: Final[tuple[MieleSensorDefinition, ...]] = (
|
||||
MieleAppliance.OVEN,
|
||||
MieleAppliance.OVEN_MICROWAVE,
|
||||
MieleAppliance.STEAM_OVEN_COMBI,
|
||||
MieleAppliance.STEAM_OVEN_MK2,
|
||||
),
|
||||
description=MieleSensorDescription(
|
||||
key="state_core_target_temperature",
|
||||
@@ -401,29 +398,6 @@ SENSOR_TYPES: Final[tuple[MieleSensorDefinition, ...]] = (
|
||||
),
|
||||
),
|
||||
),
|
||||
MieleSensorDefinition(
|
||||
types=(
|
||||
MieleAppliance.WASHING_MACHINE,
|
||||
MieleAppliance.WASHER_DRYER,
|
||||
MieleAppliance.OVEN,
|
||||
MieleAppliance.OVEN_MICROWAVE,
|
||||
MieleAppliance.STEAM_OVEN_MICRO,
|
||||
MieleAppliance.STEAM_OVEN_COMBI,
|
||||
MieleAppliance.STEAM_OVEN_MK2,
|
||||
),
|
||||
description=MieleSensorDescription(
|
||||
key="state_target_temperature",
|
||||
translation_key="target_temperature",
|
||||
zone=1,
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_fn=(
|
||||
lambda value: cast(int, value.state_target_temperature[0].temperature)
|
||||
/ 100.0
|
||||
),
|
||||
),
|
||||
),
|
||||
MieleSensorDefinition(
|
||||
types=(
|
||||
MieleAppliance.OVEN,
|
||||
|
||||
@@ -876,9 +876,6 @@
|
||||
"core_temperature": {
|
||||
"name": "Core temperature"
|
||||
},
|
||||
"target_temperature": {
|
||||
"name": "Target temperature"
|
||||
},
|
||||
"core_target_temperature": {
|
||||
"name": "Core target temperature"
|
||||
}
|
||||
|
||||
@@ -28,8 +28,6 @@ from .const import (
|
||||
from .coordinator import MieleConfigEntry
|
||||
from .entity import MieleEntity
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
||||
@@ -24,8 +24,6 @@ from .const import DOMAIN, PROCESS_ACTION, PROGRAM_ID, MieleActions, MieleApplia
|
||||
from .coordinator import MieleConfigEntry
|
||||
from .entity import MieleEntity
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
# The following const classes define program speeds and programs for the vacuum cleaner.
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"sections": {
|
||||
"auth": {
|
||||
"name": "Authentication",
|
||||
"description": "Depending on whether the server is configured to support access control, some topics may be read/write protected so that only users with the correct credentials can subscribe or publish to them. To publish/subscribe to protected topics, you can provide a username and password. Home Assistant will automatically generate an access token to authenticate with ntfy.",
|
||||
"description": "Depending on whether the server is configured to support access control, some topics may be read/write protected so that only users with the correct credentials can subscribe or publish to them. To publish/subscribe to protected topics, you can provide a username and password.",
|
||||
"data": {
|
||||
"username": "[%key:common::config_flow::data::username%]",
|
||||
"password": "[%key:common::config_flow::data::password%]"
|
||||
|
||||
@@ -32,8 +32,6 @@ from .const import (
|
||||
PLACEHOLDER_WEBHOOK_URL,
|
||||
)
|
||||
|
||||
AUTH_TOKEN_URL = "https://intercom.help/plaato/en/articles/5004720-auth_token"
|
||||
|
||||
|
||||
class PlaatoConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
"""Handles a Plaato config flow."""
|
||||
@@ -155,10 +153,7 @@ class PlaatoConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
step_id="api_method",
|
||||
data_schema=data_schema,
|
||||
errors=errors,
|
||||
description_placeholders={
|
||||
PLACEHOLDER_DEVICE_TYPE: device_type.name,
|
||||
"auth_token_url": AUTH_TOKEN_URL,
|
||||
},
|
||||
description_placeholders={PLACEHOLDER_DEVICE_TYPE: device_type.name},
|
||||
)
|
||||
|
||||
async def _get_webhook_id(self):
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
},
|
||||
"api_method": {
|
||||
"title": "Select API method",
|
||||
"description": "To be able to query the API an 'auth token' is required which can be obtained by following [these instructions]({auth_token_url})\n\nSelected device: **{device_type}** \n\nIf you prefer to use the built-in webhook method (Airlock only) please check the box below and leave 'Auth token' blank",
|
||||
"description": "To be able to query the API an 'auth token' is required which can be obtained by following [these instructions](https://plaato.zendesk.com/hc/en-us/articles/360003234717-Auth-token)\n\n Selected device: **{device_type}** \n\nIf you prefer to use the built-in webhook method (Airlock only) please check the box below and leave 'Auth token' blank",
|
||||
"data": {
|
||||
"use_webhook": "Use webhook",
|
||||
"token": "Auth token"
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["ical"],
|
||||
"quality_scale": "silver",
|
||||
"requirements": ["ical==9.2.2"]
|
||||
"requirements": ["ical==9.2.1"]
|
||||
}
|
||||
|
||||
@@ -33,11 +33,7 @@ from homeassistant.const import (
|
||||
from homeassistant.core import CALLBACK_TYPE, Event, HomeAssistant, callback
|
||||
from homeassistant.helpers import device_registry as dr, issue_registry as ir
|
||||
from homeassistant.helpers.debounce import Debouncer
|
||||
from homeassistant.helpers.device_registry import (
|
||||
CONNECTION_BLUETOOTH,
|
||||
CONNECTION_NETWORK_MAC,
|
||||
format_mac,
|
||||
)
|
||||
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, format_mac
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
|
||||
from .bluetooth import async_connect_scanner
|
||||
@@ -164,11 +160,6 @@ class ShellyCoordinatorBase[_DeviceT: BlockDevice | RpcDevice](
|
||||
"""Sleep period of the device."""
|
||||
return self.config_entry.data.get(CONF_SLEEP_PERIOD, 0)
|
||||
|
||||
@property
|
||||
def connections(self) -> set[tuple[str, str]]:
|
||||
"""Connections of the device."""
|
||||
return {(CONNECTION_NETWORK_MAC, self.mac)}
|
||||
|
||||
def async_setup(self, pending_platforms: list[Platform] | None = None) -> None:
|
||||
"""Set up the coordinator."""
|
||||
self._pending_platforms = pending_platforms
|
||||
@@ -176,7 +167,7 @@ class ShellyCoordinatorBase[_DeviceT: BlockDevice | RpcDevice](
|
||||
device_entry = dev_reg.async_get_or_create(
|
||||
config_entry_id=self.config_entry.entry_id,
|
||||
name=self.name,
|
||||
connections=self.connections,
|
||||
connections={(CONNECTION_NETWORK_MAC, self.mac)},
|
||||
identifiers={(DOMAIN, self.mac)},
|
||||
manufacturer="Shelly",
|
||||
model=get_shelly_model_name(self.model, self.sleep_period, self.device),
|
||||
@@ -532,14 +523,6 @@ class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]):
|
||||
"""
|
||||
return format_mac(bluetooth_mac_from_primary_mac(self.mac)).upper()
|
||||
|
||||
@property
|
||||
def connections(self) -> set[tuple[str, str]]:
|
||||
"""Connections of the device."""
|
||||
connections = super().connections
|
||||
if not self.sleep_period:
|
||||
connections.add((CONNECTION_BLUETOOTH, self.bluetooth_source))
|
||||
return connections
|
||||
|
||||
async def async_device_online(self, source: str) -> None:
|
||||
"""Handle device going online."""
|
||||
if not self.sleep_period:
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
}
|
||||
},
|
||||
"confirm_discovery": {
|
||||
"description": "Do you want to set up the {model} at {host}?\n\nBattery-powered devices that are password-protected must be woken up before continuing with setting up.\nBattery-powered devices that are not password-protected will be added when the device wakes up, you can now manually wake the device up using a button on it or wait for the next data update from the device."
|
||||
"description": "Do you want to set up the {model} at {host}?\n\nBattery-powered devices that are password protected must be woken up before continuing with setting up.\nBattery-powered devices that are not password protected will be added when the device wakes up, you can now manually wake the device up using a button on it or wait for the next data update from the device."
|
||||
},
|
||||
"reconfigure": {
|
||||
"description": "Update configuration for {device_name}.\n\nBefore setup, battery-powered devices must be woken up, you can now wake the device up using a button on it.",
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
"""Offer sun based automation rules."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from typing import cast
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import CONF_CONDITION, SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.condition import (
|
||||
ConditionCheckerType,
|
||||
condition_trace_set_result,
|
||||
condition_trace_update_result,
|
||||
trace_condition_function,
|
||||
)
|
||||
from homeassistant.helpers.sun import get_astral_event_date
|
||||
from homeassistant.helpers.typing import ConfigType, TemplateVarsType
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
CONDITION_SCHEMA = vol.All(
|
||||
vol.Schema(
|
||||
{
|
||||
**cv.CONDITION_BASE_SCHEMA,
|
||||
vol.Required(CONF_CONDITION): "sun",
|
||||
vol.Optional("before"): cv.sun_event,
|
||||
vol.Optional("before_offset"): cv.time_period,
|
||||
vol.Optional("after"): vol.All(
|
||||
vol.Lower, vol.Any(SUN_EVENT_SUNSET, SUN_EVENT_SUNRISE)
|
||||
),
|
||||
vol.Optional("after_offset"): cv.time_period,
|
||||
}
|
||||
),
|
||||
cv.has_at_least_one_key("before", "after"),
|
||||
)
|
||||
|
||||
|
||||
def sun(
|
||||
hass: HomeAssistant,
|
||||
before: str | None = None,
|
||||
after: str | None = None,
|
||||
before_offset: timedelta | None = None,
|
||||
after_offset: timedelta | None = None,
|
||||
) -> bool:
|
||||
"""Test if current time matches sun requirements."""
|
||||
utcnow = dt_util.utcnow()
|
||||
today = dt_util.as_local(utcnow).date()
|
||||
before_offset = before_offset or timedelta(0)
|
||||
after_offset = after_offset or timedelta(0)
|
||||
|
||||
sunrise = get_astral_event_date(hass, SUN_EVENT_SUNRISE, today)
|
||||
sunset = get_astral_event_date(hass, SUN_EVENT_SUNSET, today)
|
||||
|
||||
has_sunrise_condition = SUN_EVENT_SUNRISE in (before, after)
|
||||
has_sunset_condition = SUN_EVENT_SUNSET in (before, after)
|
||||
|
||||
after_sunrise = today > dt_util.as_local(cast(datetime, sunrise)).date()
|
||||
if after_sunrise and has_sunrise_condition:
|
||||
tomorrow = today + timedelta(days=1)
|
||||
sunrise = get_astral_event_date(hass, SUN_EVENT_SUNRISE, tomorrow)
|
||||
|
||||
after_sunset = today > dt_util.as_local(cast(datetime, sunset)).date()
|
||||
if after_sunset and has_sunset_condition:
|
||||
tomorrow = today + timedelta(days=1)
|
||||
sunset = get_astral_event_date(hass, SUN_EVENT_SUNSET, tomorrow)
|
||||
|
||||
# Special case: before sunrise OR after sunset
|
||||
# This will handle the very rare case in the polar region when the sun rises/sets
|
||||
# but does not set/rise.
|
||||
# However this entire condition does not handle those full days of darkness
|
||||
# or light, the following should be used instead:
|
||||
#
|
||||
# condition:
|
||||
# condition: state
|
||||
# entity_id: sun.sun
|
||||
# state: 'above_horizon' (or 'below_horizon')
|
||||
#
|
||||
if before == SUN_EVENT_SUNRISE and after == SUN_EVENT_SUNSET:
|
||||
wanted_time_before = cast(datetime, sunrise) + before_offset
|
||||
condition_trace_update_result(wanted_time_before=wanted_time_before)
|
||||
wanted_time_after = cast(datetime, sunset) + after_offset
|
||||
condition_trace_update_result(wanted_time_after=wanted_time_after)
|
||||
return utcnow < wanted_time_before or utcnow > wanted_time_after
|
||||
|
||||
if sunrise is None and has_sunrise_condition:
|
||||
# There is no sunrise today
|
||||
condition_trace_set_result(False, message="no sunrise today")
|
||||
return False
|
||||
|
||||
if sunset is None and has_sunset_condition:
|
||||
# There is no sunset today
|
||||
condition_trace_set_result(False, message="no sunset today")
|
||||
return False
|
||||
|
||||
if before == SUN_EVENT_SUNRISE:
|
||||
wanted_time_before = cast(datetime, sunrise) + before_offset
|
||||
condition_trace_update_result(wanted_time_before=wanted_time_before)
|
||||
if utcnow > wanted_time_before:
|
||||
return False
|
||||
|
||||
if before == SUN_EVENT_SUNSET:
|
||||
wanted_time_before = cast(datetime, sunset) + before_offset
|
||||
condition_trace_update_result(wanted_time_before=wanted_time_before)
|
||||
if utcnow > wanted_time_before:
|
||||
return False
|
||||
|
||||
if after == SUN_EVENT_SUNRISE:
|
||||
wanted_time_after = cast(datetime, sunrise) + after_offset
|
||||
condition_trace_update_result(wanted_time_after=wanted_time_after)
|
||||
if utcnow < wanted_time_after:
|
||||
return False
|
||||
|
||||
if after == SUN_EVENT_SUNSET:
|
||||
wanted_time_after = cast(datetime, sunset) + after_offset
|
||||
condition_trace_update_result(wanted_time_after=wanted_time_after)
|
||||
if utcnow < wanted_time_after:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def async_condition_from_config(config: ConfigType) -> ConditionCheckerType:
|
||||
"""Wrap action method with sun based condition."""
|
||||
before = config.get("before")
|
||||
after = config.get("after")
|
||||
before_offset = config.get("before_offset")
|
||||
after_offset = config.get("after_offset")
|
||||
|
||||
@trace_condition_function
|
||||
def sun_if(hass: HomeAssistant, variables: TemplateVarsType = None) -> bool:
|
||||
"""Validate time based if-condition."""
|
||||
return sun(hass, before, after, before_offset, after_offset)
|
||||
|
||||
return sun_if
|
||||
@@ -469,7 +469,6 @@ class ResultStream:
|
||||
use_file_cache: bool
|
||||
language: str
|
||||
options: dict
|
||||
supports_streaming_input: bool
|
||||
|
||||
_manager: SpeechManager
|
||||
|
||||
@@ -485,10 +484,7 @@ class ResultStream:
|
||||
|
||||
@callback
|
||||
def async_set_message(self, message: str) -> None:
|
||||
"""Set message to be generated.
|
||||
|
||||
This method will leverage a disk cache to speed up generation.
|
||||
"""
|
||||
"""Set message to be generated."""
|
||||
self._result_cache.set_result(
|
||||
self._manager.async_cache_message_in_memory(
|
||||
engine=self.engine,
|
||||
@@ -501,10 +497,7 @@ class ResultStream:
|
||||
|
||||
@callback
|
||||
def async_set_message_stream(self, message_stream: AsyncGenerator[str]) -> None:
|
||||
"""Set a stream that will generate the message.
|
||||
|
||||
This method can result in faster first byte when generating long responses.
|
||||
"""
|
||||
"""Set a stream that will generate the message."""
|
||||
self._result_cache.set_result(
|
||||
self._manager.async_cache_message_stream_in_memory(
|
||||
engine=self.engine,
|
||||
@@ -733,10 +726,6 @@ class SpeechManager:
|
||||
if (engine_instance := get_engine_instance(self.hass, engine)) is None:
|
||||
raise HomeAssistantError(f"Provider {engine} not found")
|
||||
|
||||
supports_streaming_input = (
|
||||
isinstance(engine_instance, TextToSpeechEntity)
|
||||
and engine_instance.async_supports_streaming_input()
|
||||
)
|
||||
language, options = self.process_options(engine_instance, language, options)
|
||||
if use_file_cache is None:
|
||||
use_file_cache = self.use_file_cache
|
||||
@@ -752,7 +741,6 @@ class SpeechManager:
|
||||
engine=engine,
|
||||
language=language,
|
||||
options=options,
|
||||
supports_streaming_input=supports_streaming_input,
|
||||
_manager=self,
|
||||
)
|
||||
self.token_to_stream[token] = result_stream
|
||||
|
||||
@@ -89,13 +89,6 @@ class TextToSpeechEntity(RestoreEntity, cached_properties=CACHED_PROPERTIES_WITH
|
||||
"""Return a mapping with the default options."""
|
||||
return self._attr_default_options
|
||||
|
||||
@classmethod
|
||||
def async_supports_streaming_input(cls) -> bool:
|
||||
"""Return if the TTS engine supports streaming input."""
|
||||
return (
|
||||
cls.async_stream_tts_audio is not TextToSpeechEntity.async_stream_tts_audio
|
||||
)
|
||||
|
||||
@callback
|
||||
def async_get_supported_voices(self, language: str) -> list[Voice] | None:
|
||||
"""Return a list of supported voices for a language."""
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"tls": "Enable this if you use a secure connection to your Velbus interface, like a Signum.",
|
||||
"host": "The IP address or hostname of the Velbus interface.",
|
||||
"port": "The port number of the Velbus interface.",
|
||||
"password": "The password of the Velbus interface, this is only needed if the interface is password-protected."
|
||||
"password": "The password of the Velbus interface, this is only needed if the interface is password protected."
|
||||
},
|
||||
"description": "TCP/IP configuration, in case you use a Signum, VelServ, velbus-tcp or any other Velbus to TCP/IP interface."
|
||||
},
|
||||
@@ -58,7 +58,7 @@
|
||||
"services": {
|
||||
"sync_clock": {
|
||||
"name": "Sync clock",
|
||||
"description": "Syncs the clock of the Velbus modules to the Home Assistant clock, this is the same as the 'sync clock' from VelbusLink.",
|
||||
"description": "Syncs the Velbus modules clock to the Home Assistant clock, this is the same as the 'sync clock' from VelbusLink.",
|
||||
"fields": {
|
||||
"interface": {
|
||||
"name": "Interface",
|
||||
@@ -104,7 +104,7 @@
|
||||
},
|
||||
"set_memo_text": {
|
||||
"name": "Set memo text",
|
||||
"description": "Sets the memo text to the display of modules like VMBGPO, VMBGPOD. Be sure the pages of the modules are configured to display the memo text.",
|
||||
"description": "Sets the memo text to the display of modules like VMBGPO, VMBGPOD Be sure the page(s) of the module is configured to display the memo text.",
|
||||
"fields": {
|
||||
"interface": {
|
||||
"name": "[%key:component::velbus::services::sync_clock::fields::interface::name%]",
|
||||
|
||||
@@ -278,39 +278,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
# and we'll handle the clean up below.
|
||||
await driver_events.setup(driver)
|
||||
|
||||
if (old_unique_id := entry.unique_id) is not None and old_unique_id != (
|
||||
new_unique_id := str(driver.controller.home_id)
|
||||
):
|
||||
device_registry = dr.async_get(hass)
|
||||
controller_model = "Unknown model"
|
||||
if (
|
||||
(own_node := driver.controller.own_node)
|
||||
and (
|
||||
controller_device_entry := device_registry.async_get_device(
|
||||
identifiers={get_device_id(driver, own_node)}
|
||||
)
|
||||
)
|
||||
and (model := controller_device_entry.model)
|
||||
):
|
||||
controller_model = model
|
||||
async_create_issue(
|
||||
hass,
|
||||
DOMAIN,
|
||||
f"migrate_unique_id.{entry.entry_id}",
|
||||
data={
|
||||
"config_entry_id": entry.entry_id,
|
||||
"config_entry_title": entry.title,
|
||||
"controller_model": controller_model,
|
||||
"new_unique_id": new_unique_id,
|
||||
"old_unique_id": old_unique_id,
|
||||
},
|
||||
is_fixable=True,
|
||||
severity=IssueSeverity.ERROR,
|
||||
translation_key="migrate_unique_id",
|
||||
)
|
||||
else:
|
||||
async_delete_issue(hass, DOMAIN, f"migrate_unique_id.{entry.entry_id}")
|
||||
|
||||
# If the listen task is already failed, we need to raise ConfigEntryNotReady
|
||||
if listen_task.done():
|
||||
listen_error, error_message = _get_listen_task_error(listen_task)
|
||||
|
||||
@@ -57,47 +57,6 @@ class DeviceConfigFileChangedFlow(RepairsFlow):
|
||||
)
|
||||
|
||||
|
||||
class MigrateUniqueIDFlow(RepairsFlow):
|
||||
"""Handler for an issue fixing flow."""
|
||||
|
||||
def __init__(self, data: dict[str, str]) -> None:
|
||||
"""Initialize."""
|
||||
self.description_placeholders: dict[str, str] = {
|
||||
"config_entry_title": data["config_entry_title"],
|
||||
"controller_model": data["controller_model"],
|
||||
"new_unique_id": data["new_unique_id"],
|
||||
"old_unique_id": data["old_unique_id"],
|
||||
}
|
||||
self._config_entry_id: str = data["config_entry_id"]
|
||||
|
||||
async def async_step_init(
|
||||
self, user_input: dict[str, str] | None = None
|
||||
) -> data_entry_flow.FlowResult:
|
||||
"""Handle the first step of a fix flow."""
|
||||
return await self.async_step_confirm()
|
||||
|
||||
async def async_step_confirm(
|
||||
self, user_input: dict[str, str] | None = None
|
||||
) -> data_entry_flow.FlowResult:
|
||||
"""Handle the confirm step of a fix flow."""
|
||||
if user_input is not None:
|
||||
config_entry = self.hass.config_entries.async_get_entry(
|
||||
self._config_entry_id
|
||||
)
|
||||
# If config entry was removed, we can ignore the issue.
|
||||
if config_entry is not None:
|
||||
self.hass.config_entries.async_update_entry(
|
||||
config_entry,
|
||||
unique_id=self.description_placeholders["new_unique_id"],
|
||||
)
|
||||
return self.async_create_entry(data={})
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="confirm",
|
||||
description_placeholders=self.description_placeholders,
|
||||
)
|
||||
|
||||
|
||||
async def async_create_fix_flow(
|
||||
hass: HomeAssistant, issue_id: str, data: dict[str, str] | None
|
||||
) -> RepairsFlow:
|
||||
@@ -106,7 +65,4 @@ async def async_create_fix_flow(
|
||||
if issue_id.split(".")[0] == "device_config_file_changed":
|
||||
assert data
|
||||
return DeviceConfigFileChangedFlow(data)
|
||||
if issue_id.split(".")[0] == "migrate_unique_id":
|
||||
assert data
|
||||
return MigrateUniqueIDFlow(data)
|
||||
return ConfirmRepairFlow()
|
||||
|
||||
@@ -273,17 +273,6 @@
|
||||
"invalid_server_version": {
|
||||
"description": "The version of Z-Wave Server you are currently running is too old for this version of Home Assistant. Please update the Z-Wave Server to the latest version to fix this issue.",
|
||||
"title": "Newer version of Z-Wave Server needed"
|
||||
},
|
||||
"migrate_unique_id": {
|
||||
"fix_flow": {
|
||||
"step": {
|
||||
"confirm": {
|
||||
"description": "A Z-Wave controller of model {controller_model} with a different ID ({new_unique_id}) than the previously connected controller ({old_unique_id}) was connected to the {config_entry_title} configuration entry.\n\nReasons for a different controller ID could be:\n\n1. The controller was factory reset, with a 3rd party application.\n2. A controller Non Volatile Memory (NVM) backup was restored to the controller, with a 3rd party application.\n3. A different controller was connected to this configuration entry.\n\nIf a different controller was connected, you should instead set up a new configuration entry for the new controller.\n\nIf you are sure that the current controller is the correct controller you can confirm this by pressing Submit, and the configuration entry will remember the new controller ID.",
|
||||
"title": "An unknown controller was detected"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "An unknown controller was detected"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
|
||||
@@ -866,17 +866,17 @@ class Config:
|
||||
# pylint: disable-next=import-outside-toplevel
|
||||
from .components.frontend import storage as frontend_store
|
||||
|
||||
owner_store = await frontend_store.async_user_store(
|
||||
_, owner_data = await frontend_store.async_user_store(
|
||||
self.hass, owner.id
|
||||
)
|
||||
|
||||
if (
|
||||
"language" in owner_store.data
|
||||
and "language" in owner_store.data["language"]
|
||||
"language" in owner_data
|
||||
and "language" in owner_data["language"]
|
||||
):
|
||||
with suppress(vol.InInvalid):
|
||||
data["language"] = cv.language(
|
||||
owner_store.data["language"]["language"]
|
||||
owner_data["language"]["language"]
|
||||
)
|
||||
# pylint: disable-next=broad-except
|
||||
except Exception:
|
||||
|
||||
@@ -42,6 +42,8 @@ from homeassistant.const import (
|
||||
ENTITY_MATCH_ANY,
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
SUN_EVENT_SUNRISE,
|
||||
SUN_EVENT_SUNSET,
|
||||
WEEKDAYS,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, State, callback
|
||||
@@ -58,6 +60,7 @@ from homeassistant.util import dt as dt_util
|
||||
from homeassistant.util.async_ import run_callback_threadsafe
|
||||
|
||||
from . import config_validation as cv, entity_registry as er
|
||||
from .sun import get_astral_event_date
|
||||
from .template import Template, render_complex
|
||||
from .trace import (
|
||||
TraceElement,
|
||||
@@ -82,6 +85,7 @@ _PLATFORM_ALIASES = {
|
||||
"numeric_state": None,
|
||||
"or": None,
|
||||
"state": None,
|
||||
"sun": None,
|
||||
"template": None,
|
||||
"time": None,
|
||||
"trigger": None,
|
||||
@@ -651,6 +655,105 @@ def state_from_config(config: ConfigType) -> ConditionCheckerType:
|
||||
return if_state
|
||||
|
||||
|
||||
def sun(
|
||||
hass: HomeAssistant,
|
||||
before: str | None = None,
|
||||
after: str | None = None,
|
||||
before_offset: timedelta | None = None,
|
||||
after_offset: timedelta | None = None,
|
||||
) -> bool:
|
||||
"""Test if current time matches sun requirements."""
|
||||
utcnow = dt_util.utcnow()
|
||||
today = dt_util.as_local(utcnow).date()
|
||||
before_offset = before_offset or timedelta(0)
|
||||
after_offset = after_offset or timedelta(0)
|
||||
|
||||
sunrise = get_astral_event_date(hass, SUN_EVENT_SUNRISE, today)
|
||||
sunset = get_astral_event_date(hass, SUN_EVENT_SUNSET, today)
|
||||
|
||||
has_sunrise_condition = SUN_EVENT_SUNRISE in (before, after)
|
||||
has_sunset_condition = SUN_EVENT_SUNSET in (before, after)
|
||||
|
||||
after_sunrise = today > dt_util.as_local(cast(datetime, sunrise)).date()
|
||||
if after_sunrise and has_sunrise_condition:
|
||||
tomorrow = today + timedelta(days=1)
|
||||
sunrise = get_astral_event_date(hass, SUN_EVENT_SUNRISE, tomorrow)
|
||||
|
||||
after_sunset = today > dt_util.as_local(cast(datetime, sunset)).date()
|
||||
if after_sunset and has_sunset_condition:
|
||||
tomorrow = today + timedelta(days=1)
|
||||
sunset = get_astral_event_date(hass, SUN_EVENT_SUNSET, tomorrow)
|
||||
|
||||
# Special case: before sunrise OR after sunset
|
||||
# This will handle the very rare case in the polar region when the sun rises/sets
|
||||
# but does not set/rise.
|
||||
# However this entire condition does not handle those full days of darkness
|
||||
# or light, the following should be used instead:
|
||||
#
|
||||
# condition:
|
||||
# condition: state
|
||||
# entity_id: sun.sun
|
||||
# state: 'above_horizon' (or 'below_horizon')
|
||||
#
|
||||
if before == SUN_EVENT_SUNRISE and after == SUN_EVENT_SUNSET:
|
||||
wanted_time_before = cast(datetime, sunrise) + before_offset
|
||||
condition_trace_update_result(wanted_time_before=wanted_time_before)
|
||||
wanted_time_after = cast(datetime, sunset) + after_offset
|
||||
condition_trace_update_result(wanted_time_after=wanted_time_after)
|
||||
return utcnow < wanted_time_before or utcnow > wanted_time_after
|
||||
|
||||
if sunrise is None and has_sunrise_condition:
|
||||
# There is no sunrise today
|
||||
condition_trace_set_result(False, message="no sunrise today")
|
||||
return False
|
||||
|
||||
if sunset is None and has_sunset_condition:
|
||||
# There is no sunset today
|
||||
condition_trace_set_result(False, message="no sunset today")
|
||||
return False
|
||||
|
||||
if before == SUN_EVENT_SUNRISE:
|
||||
wanted_time_before = cast(datetime, sunrise) + before_offset
|
||||
condition_trace_update_result(wanted_time_before=wanted_time_before)
|
||||
if utcnow > wanted_time_before:
|
||||
return False
|
||||
|
||||
if before == SUN_EVENT_SUNSET:
|
||||
wanted_time_before = cast(datetime, sunset) + before_offset
|
||||
condition_trace_update_result(wanted_time_before=wanted_time_before)
|
||||
if utcnow > wanted_time_before:
|
||||
return False
|
||||
|
||||
if after == SUN_EVENT_SUNRISE:
|
||||
wanted_time_after = cast(datetime, sunrise) + after_offset
|
||||
condition_trace_update_result(wanted_time_after=wanted_time_after)
|
||||
if utcnow < wanted_time_after:
|
||||
return False
|
||||
|
||||
if after == SUN_EVENT_SUNSET:
|
||||
wanted_time_after = cast(datetime, sunset) + after_offset
|
||||
condition_trace_update_result(wanted_time_after=wanted_time_after)
|
||||
if utcnow < wanted_time_after:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def sun_from_config(config: ConfigType) -> ConditionCheckerType:
|
||||
"""Wrap action method with sun based condition."""
|
||||
before = config.get("before")
|
||||
after = config.get("after")
|
||||
before_offset = config.get("before_offset")
|
||||
after_offset = config.get("after_offset")
|
||||
|
||||
@trace_condition_function
|
||||
def sun_if(hass: HomeAssistant, variables: TemplateVarsType = None) -> bool:
|
||||
"""Validate time based if-condition."""
|
||||
return sun(hass, before, after, before_offset, after_offset)
|
||||
|
||||
return sun_if
|
||||
|
||||
|
||||
def template(
|
||||
hass: HomeAssistant, value_template: Template, variables: TemplateVarsType = None
|
||||
) -> bool:
|
||||
@@ -951,10 +1054,8 @@ async def async_validate_condition_config(
|
||||
return config
|
||||
|
||||
platform = await _async_get_condition_platform(hass, config)
|
||||
if platform is not None:
|
||||
if hasattr(platform, "async_validate_condition_config"):
|
||||
return await platform.async_validate_condition_config(hass, config)
|
||||
return cast(ConfigType, platform.CONDITION_SCHEMA(config))
|
||||
if platform is not None and hasattr(platform, "async_validate_condition_config"):
|
||||
return await platform.async_validate_condition_config(hass, config)
|
||||
if platform is None and condition in ("numeric_state", "state"):
|
||||
validator = cast(
|
||||
Callable[[HomeAssistant, ConfigType], ConfigType],
|
||||
|
||||
@@ -1084,13 +1084,10 @@ def renamed(
|
||||
return validator
|
||||
|
||||
|
||||
type ValueSchemas = dict[Hashable, VolSchemaType | Callable[[Any], dict[str, Any]]]
|
||||
|
||||
|
||||
def key_value_schemas(
|
||||
key: str,
|
||||
value_schemas: ValueSchemas,
|
||||
default_schema: VolSchemaType | Callable[[Any], dict[str, Any]] | None = None,
|
||||
value_schemas: dict[Hashable, VolSchemaType | Callable[[Any], dict[str, Any]]],
|
||||
default_schema: VolSchemaType | None = None,
|
||||
default_description: str | None = None,
|
||||
) -> Callable[[Any], dict[Hashable, Any]]:
|
||||
"""Create a validator that validates based on a value for specific key.
|
||||
@@ -1738,41 +1735,25 @@ CONDITION_SHORTHAND_SCHEMA = vol.Schema(
|
||||
}
|
||||
)
|
||||
|
||||
BUILT_IN_CONDITIONS: ValueSchemas = {
|
||||
"and": AND_CONDITION_SCHEMA,
|
||||
"device": DEVICE_CONDITION_SCHEMA,
|
||||
"not": NOT_CONDITION_SCHEMA,
|
||||
"numeric_state": NUMERIC_STATE_CONDITION_SCHEMA,
|
||||
"or": OR_CONDITION_SCHEMA,
|
||||
"state": STATE_CONDITION_SCHEMA,
|
||||
"template": TEMPLATE_CONDITION_SCHEMA,
|
||||
"time": TIME_CONDITION_SCHEMA,
|
||||
"trigger": TRIGGER_CONDITION_SCHEMA,
|
||||
"zone": ZONE_CONDITION_SCHEMA,
|
||||
}
|
||||
|
||||
|
||||
# This is first round of validation, we don't want to mutate the config here already,
|
||||
# just ensure basics as condition type and alias are there.
|
||||
def _base_condition_validator(value: Any) -> Any:
|
||||
vol.Schema(
|
||||
{
|
||||
**CONDITION_BASE_SCHEMA,
|
||||
CONF_CONDITION: vol.All(str, vol.NotIn(BUILT_IN_CONDITIONS)),
|
||||
},
|
||||
extra=vol.ALLOW_EXTRA,
|
||||
)(value)
|
||||
return value
|
||||
|
||||
|
||||
CONDITION_SCHEMA: vol.Schema = vol.Schema(
|
||||
vol.Any(
|
||||
vol.All(
|
||||
expand_condition_shorthand,
|
||||
key_value_schemas(
|
||||
CONF_CONDITION,
|
||||
BUILT_IN_CONDITIONS,
|
||||
_base_condition_validator,
|
||||
{
|
||||
"and": AND_CONDITION_SCHEMA,
|
||||
"device": DEVICE_CONDITION_SCHEMA,
|
||||
"not": NOT_CONDITION_SCHEMA,
|
||||
"numeric_state": NUMERIC_STATE_CONDITION_SCHEMA,
|
||||
"or": OR_CONDITION_SCHEMA,
|
||||
"state": STATE_CONDITION_SCHEMA,
|
||||
"sun": SUN_CONDITION_SCHEMA,
|
||||
"template": TEMPLATE_CONDITION_SCHEMA,
|
||||
"time": TIME_CONDITION_SCHEMA,
|
||||
"trigger": TRIGGER_CONDITION_SCHEMA,
|
||||
"zone": ZONE_CONDITION_SCHEMA,
|
||||
},
|
||||
),
|
||||
),
|
||||
dynamic_template_condition,
|
||||
@@ -1799,11 +1780,20 @@ CONDITION_ACTION_SCHEMA: vol.Schema = vol.Schema(
|
||||
expand_condition_shorthand,
|
||||
key_value_schemas(
|
||||
CONF_CONDITION,
|
||||
BUILT_IN_CONDITIONS,
|
||||
vol.Any(
|
||||
dynamic_template_condition_action,
|
||||
_base_condition_validator,
|
||||
),
|
||||
{
|
||||
"and": AND_CONDITION_SCHEMA,
|
||||
"device": DEVICE_CONDITION_SCHEMA,
|
||||
"not": NOT_CONDITION_SCHEMA,
|
||||
"numeric_state": NUMERIC_STATE_CONDITION_SCHEMA,
|
||||
"or": OR_CONDITION_SCHEMA,
|
||||
"state": STATE_CONDITION_SCHEMA,
|
||||
"sun": SUN_CONDITION_SCHEMA,
|
||||
"template": TEMPLATE_CONDITION_SCHEMA,
|
||||
"time": TIME_CONDITION_SCHEMA,
|
||||
"trigger": TRIGGER_CONDITION_SCHEMA,
|
||||
"zone": ZONE_CONDITION_SCHEMA,
|
||||
},
|
||||
dynamic_template_condition_action,
|
||||
"a list of conditions or a valid template",
|
||||
),
|
||||
)
|
||||
@@ -1862,7 +1852,7 @@ def _base_trigger_list_flatten(triggers: list[Any]) -> list[Any]:
|
||||
return flatlist
|
||||
|
||||
|
||||
# This is first round of validation, we don't want to mutate the config here already,
|
||||
# This is first round of validation, we don't want to process the config here already,
|
||||
# just ensure basics as platform and ID are there.
|
||||
def _base_trigger_validator(value: Any) -> Any:
|
||||
_base_trigger_validator_schema(value)
|
||||
|
||||
@@ -29,20 +29,27 @@ from homeassistant.core import (
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.loader import async_get_integration, bind_hass
|
||||
from homeassistant.setup import async_prepare_setup_platform
|
||||
from homeassistant.util.hass_dict import HassKey
|
||||
|
||||
from . import config_validation as cv, discovery, entity, service
|
||||
from .entity_platform import EntityPlatform
|
||||
from . import (
|
||||
config_validation as cv,
|
||||
device_registry as dr,
|
||||
discovery,
|
||||
entity,
|
||||
entity_registry as er,
|
||||
service,
|
||||
)
|
||||
from .entity_platform import EntityPlatform, async_calculate_suggested_object_id
|
||||
from .typing import ConfigType, DiscoveryInfoType, VolDictType, VolSchemaType
|
||||
|
||||
DEFAULT_SCAN_INTERVAL = timedelta(seconds=15)
|
||||
DATA_INSTANCES = "entity_components"
|
||||
DATA_INSTANCES: HassKey[dict[str, EntityComponent]] = HassKey("entity_components")
|
||||
|
||||
|
||||
@bind_hass
|
||||
async def async_update_entity(hass: HomeAssistant, entity_id: str) -> None:
|
||||
"""Trigger an update for an entity."""
|
||||
domain = entity_id.partition(".")[0]
|
||||
entity_comp: EntityComponent[entity.Entity] | None
|
||||
entity_comp = hass.data.get(DATA_INSTANCES, {}).get(domain)
|
||||
|
||||
if entity_comp is None:
|
||||
@@ -60,6 +67,37 @@ async def async_update_entity(hass: HomeAssistant, entity_id: str) -> None:
|
||||
await entity_obj.async_update_ha_state(True)
|
||||
|
||||
|
||||
@callback
|
||||
def async_get_entity_suggested_object_id(
|
||||
hass: HomeAssistant, entity_id: str
|
||||
) -> str | None:
|
||||
"""Get the suggested object id for an entity.
|
||||
|
||||
Raises HomeAssistantError if the entity is not in the registry.
|
||||
"""
|
||||
entity_registry = er.async_get(hass)
|
||||
if not (entity_entry := entity_registry.async_get(entity_id)):
|
||||
raise HomeAssistantError(f"Entity {entity_id} is not in the registry.")
|
||||
|
||||
domain = entity_id.partition(".")[0]
|
||||
|
||||
if entity_entry.suggested_object_id:
|
||||
return entity_entry.suggested_object_id
|
||||
|
||||
if entity_entry.name:
|
||||
return entity_entry.name
|
||||
|
||||
entity_comp = hass.data.get(DATA_INSTANCES, {}).get(domain)
|
||||
entity_obj = entity_comp.get_entity(entity_id) if entity_comp else None
|
||||
if entity_obj:
|
||||
device: dr.DeviceEntry | None = None
|
||||
if device_id := entity_entry.device_id:
|
||||
device = dr.async_get(hass).async_get(device_id)
|
||||
return async_calculate_suggested_object_id(entity_obj, device)
|
||||
|
||||
return entity_entry.calculated_object_id
|
||||
|
||||
|
||||
class EntityComponent[_EntityT: entity.Entity = entity.Entity]:
|
||||
"""The EntityComponent manages platforms that manage entities.
|
||||
|
||||
@@ -95,7 +133,7 @@ class EntityComponent[_EntityT: entity.Entity = entity.Entity]:
|
||||
self.async_add_entities = domain_platform.async_add_entities
|
||||
self.add_entities = domain_platform.add_entities
|
||||
self._entities: dict[str, entity.Entity] = domain_platform.domain_entities
|
||||
hass.data.setdefault(DATA_INSTANCES, {})[domain] = self
|
||||
hass.data.setdefault(DATA_INSTANCES, {})[domain] = self # type: ignore[assignment]
|
||||
|
||||
@property
|
||||
def entities(self) -> Iterable[_EntityT]:
|
||||
|
||||
@@ -764,7 +764,7 @@ class EntityPlatform:
|
||||
already_exists = True
|
||||
return (already_exists, restored)
|
||||
|
||||
async def _async_add_entity( # noqa: C901
|
||||
async def _async_add_entity(
|
||||
self,
|
||||
entity: Entity,
|
||||
update_before_add: bool,
|
||||
@@ -843,31 +843,18 @@ class EntityPlatform:
|
||||
else:
|
||||
device = None
|
||||
|
||||
if not registered_entity_id:
|
||||
# Do not bother working out a suggested_object_id
|
||||
# if the entity is already registered as it will
|
||||
# be ignored.
|
||||
#
|
||||
# An entity may suggest the entity_id by setting entity_id itself
|
||||
suggested_entity_id: str | None = entity.entity_id
|
||||
if suggested_entity_id is not None:
|
||||
suggested_object_id = split_entity_id(entity.entity_id)[1]
|
||||
else:
|
||||
if device and entity.has_entity_name:
|
||||
device_name = device.name_by_user or device.name
|
||||
if entity.use_device_name:
|
||||
suggested_object_id = device_name
|
||||
else:
|
||||
suggested_object_id = (
|
||||
f"{device_name} {entity.suggested_object_id}"
|
||||
)
|
||||
if not suggested_object_id:
|
||||
suggested_object_id = entity.suggested_object_id
|
||||
# An entity may suggest the entity_id by setting entity_id itself
|
||||
calculated_object_id: str | None = None
|
||||
suggested_entity_id: str | None = entity.entity_id
|
||||
if suggested_entity_id is not None:
|
||||
suggested_object_id = split_entity_id(entity.entity_id)[1]
|
||||
else:
|
||||
calculated_object_id = async_calculate_suggested_object_id(
|
||||
entity, device
|
||||
)
|
||||
|
||||
if self.entity_namespace is not None:
|
||||
suggested_object_id = (
|
||||
f"{self.entity_namespace} {suggested_object_id}"
|
||||
)
|
||||
if self.entity_namespace is not None and suggested_object_id is not None:
|
||||
suggested_object_id = f"{self.entity_namespace} {suggested_object_id}"
|
||||
|
||||
disabled_by: RegistryEntryDisabler | None = None
|
||||
if not entity.entity_registry_enabled_default:
|
||||
@@ -881,6 +868,7 @@ class EntityPlatform:
|
||||
self.domain,
|
||||
self.platform_name,
|
||||
entity.unique_id,
|
||||
calculated_object_id=calculated_object_id,
|
||||
capabilities=entity.capability_attributes,
|
||||
config_entry=self.config_entry,
|
||||
config_subentry_id=config_subentry_id,
|
||||
@@ -1124,6 +1112,27 @@ class EntityPlatform:
|
||||
await asyncio.gather(*tasks)
|
||||
|
||||
|
||||
@callback
|
||||
def async_calculate_suggested_object_id(
|
||||
entity: Entity, device: dev_reg.DeviceEntry | None
|
||||
) -> str | None:
|
||||
"""Calculate the suggested object ID for an entity."""
|
||||
calculated_object_id: str | None = None
|
||||
if device and entity.has_entity_name:
|
||||
device_name = device.name_by_user or device.name
|
||||
if entity.use_device_name:
|
||||
calculated_object_id = device_name
|
||||
else:
|
||||
calculated_object_id = f"{device_name} {entity.suggested_object_id}"
|
||||
if not calculated_object_id:
|
||||
calculated_object_id = entity.suggested_object_id
|
||||
|
||||
if (platform := entity.platform) and platform.entity_namespace is not None:
|
||||
calculated_object_id = f"{platform.entity_namespace} {calculated_object_id}"
|
||||
|
||||
return calculated_object_id
|
||||
|
||||
|
||||
current_platform: ContextVar[EntityPlatform | None] = ContextVar(
|
||||
"current_platform", default=None
|
||||
)
|
||||
|
||||
@@ -79,7 +79,7 @@ EVENT_ENTITY_REGISTRY_UPDATED: EventType[EventEntityRegistryUpdatedData] = Event
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
STORAGE_VERSION_MAJOR = 1
|
||||
STORAGE_VERSION_MINOR = 16
|
||||
STORAGE_VERSION_MINOR = 17
|
||||
STORAGE_KEY = "core.entity_registry"
|
||||
|
||||
CLEANUP_INTERVAL = 3600 * 24
|
||||
@@ -195,9 +195,11 @@ class RegistryEntry:
|
||||
name: str | None = attr.ib(default=None)
|
||||
options: ReadOnlyEntityOptionsType = attr.ib(converter=_protect_entity_options)
|
||||
# As set by integration
|
||||
calculated_object_id: str | None = attr.ib()
|
||||
original_device_class: str | None = attr.ib()
|
||||
original_icon: str | None = attr.ib()
|
||||
original_name: str | None = attr.ib()
|
||||
suggested_object_id: str | None = attr.ib()
|
||||
supported_features: int = attr.ib()
|
||||
translation_key: str | None = attr.ib()
|
||||
unit_of_measurement: str | None = attr.ib()
|
||||
@@ -337,6 +339,7 @@ class RegistryEntry:
|
||||
{
|
||||
"aliases": list(self.aliases),
|
||||
"area_id": self.area_id,
|
||||
"calculated_object_id": self.calculated_object_id,
|
||||
"categories": self.categories,
|
||||
"capabilities": self.capabilities,
|
||||
"config_entry_id": self.config_entry_id,
|
||||
@@ -359,6 +362,7 @@ class RegistryEntry:
|
||||
"original_icon": self.original_icon,
|
||||
"original_name": self.original_name,
|
||||
"platform": self.platform,
|
||||
"suggested_object_id": self.suggested_object_id,
|
||||
"supported_features": self.supported_features,
|
||||
"translation_key": self.translation_key,
|
||||
"unique_id": self.unique_id,
|
||||
@@ -548,6 +552,12 @@ class EntityRegistryStore(storage.Store[dict[str, list[dict[str, Any]]]]):
|
||||
for entity in data["deleted_entities"]:
|
||||
entity["config_subentry_id"] = None
|
||||
|
||||
if old_minor_version < 17:
|
||||
# Version 1.17 adds calculated_object_id and suggested_object_id
|
||||
for entity in data["entities"]:
|
||||
entity["calculated_object_id"] = None
|
||||
entity["suggested_object_id"] = None
|
||||
|
||||
if old_major_version > 1:
|
||||
raise NotImplementedError
|
||||
return data
|
||||
@@ -836,6 +846,7 @@ class EntityRegistry(BaseRegistry):
|
||||
unique_id: str,
|
||||
*,
|
||||
# To influence entity ID generation
|
||||
calculated_object_id: str | None = None,
|
||||
suggested_object_id: str | None = None,
|
||||
# To disable or hide an entity if it gets created
|
||||
disabled_by: RegistryEntryDisabler | None = None,
|
||||
@@ -908,7 +919,7 @@ class EntityRegistry(BaseRegistry):
|
||||
|
||||
entity_id = self.async_generate_entity_id(
|
||||
domain,
|
||||
suggested_object_id or f"{platform}_{unique_id}",
|
||||
suggested_object_id or calculated_object_id or f"{platform}_{unique_id}",
|
||||
)
|
||||
|
||||
if (
|
||||
@@ -942,6 +953,8 @@ class EntityRegistry(BaseRegistry):
|
||||
original_icon=none_if_undefined(original_icon),
|
||||
original_name=none_if_undefined(original_name),
|
||||
platform=platform,
|
||||
calculated_object_id=calculated_object_id,
|
||||
suggested_object_id=suggested_object_id,
|
||||
supported_features=none_if_undefined(supported_features) or 0,
|
||||
translation_key=none_if_undefined(translation_key),
|
||||
unique_id=unique_id,
|
||||
@@ -1350,6 +1363,7 @@ class EntityRegistry(BaseRegistry):
|
||||
entities[entity["entity_id"]] = RegistryEntry(
|
||||
aliases=set(entity["aliases"]),
|
||||
area_id=entity["area_id"],
|
||||
calculated_object_id=entity["calculated_object_id"],
|
||||
categories=entity["categories"],
|
||||
capabilities=entity["capabilities"],
|
||||
config_entry_id=entity["config_entry_id"],
|
||||
@@ -1378,6 +1392,7 @@ class EntityRegistry(BaseRegistry):
|
||||
original_icon=entity["original_icon"],
|
||||
original_name=entity["original_name"],
|
||||
platform=entity["platform"],
|
||||
suggested_object_id=entity["suggested_object_id"],
|
||||
supported_features=entity["supported_features"],
|
||||
translation_key=entity["translation_key"],
|
||||
unique_id=entity["unique_id"],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Automatically generated by gen_requirements_all.py, do not edit
|
||||
|
||||
aiodhcpwatcher==1.2.0
|
||||
aiodhcpwatcher==1.1.1
|
||||
aiodiscover==2.7.0
|
||||
aiodns==3.4.0
|
||||
aiohasupervisor==0.3.1
|
||||
|
||||
10
requirements_all.txt
generated
10
requirements_all.txt
generated
@@ -211,10 +211,10 @@ aiobafi6==0.9.0
|
||||
aiobotocore==2.21.1
|
||||
|
||||
# homeassistant.components.comelit
|
||||
aiocomelit==0.12.1
|
||||
aiocomelit==0.12.0
|
||||
|
||||
# homeassistant.components.dhcp
|
||||
aiodhcpwatcher==1.2.0
|
||||
aiodhcpwatcher==1.1.1
|
||||
|
||||
# homeassistant.components.dhcp
|
||||
aiodiscover==2.7.0
|
||||
@@ -983,7 +983,7 @@ gardena-bluetooth==1.6.0
|
||||
gassist-text==0.0.12
|
||||
|
||||
# homeassistant.components.google
|
||||
gcal-sync==7.0.1
|
||||
gcal-sync==7.0.0
|
||||
|
||||
# homeassistant.components.geniushub
|
||||
geniushub-client==0.7.1
|
||||
@@ -1197,7 +1197,7 @@ ibmiotf==0.3.4
|
||||
# homeassistant.components.local_calendar
|
||||
# homeassistant.components.local_todo
|
||||
# homeassistant.components.remote_calendar
|
||||
ical==9.2.2
|
||||
ical==9.2.1
|
||||
|
||||
# homeassistant.components.caldav
|
||||
icalendar==6.1.0
|
||||
@@ -3101,7 +3101,7 @@ xbox-webapi==2.1.0
|
||||
xiaomi-ble==0.38.0
|
||||
|
||||
# homeassistant.components.knx
|
||||
xknx==3.8.0
|
||||
xknx==3.6.0
|
||||
|
||||
# homeassistant.components.knx
|
||||
xknxproject==3.8.2
|
||||
|
||||
@@ -18,7 +18,7 @@ pre-commit==4.0.0
|
||||
pydantic==2.11.3
|
||||
pylint==3.3.7
|
||||
pylint-per-file-ignores==1.4.0
|
||||
pipdeptree==2.26.1
|
||||
pipdeptree==2.25.1
|
||||
pytest-asyncio==0.26.0
|
||||
pytest-aiohttp==1.1.0
|
||||
pytest-cov==6.0.0
|
||||
|
||||
10
requirements_test_all.txt
generated
10
requirements_test_all.txt
generated
@@ -199,10 +199,10 @@ aiobafi6==0.9.0
|
||||
aiobotocore==2.21.1
|
||||
|
||||
# homeassistant.components.comelit
|
||||
aiocomelit==0.12.1
|
||||
aiocomelit==0.12.0
|
||||
|
||||
# homeassistant.components.dhcp
|
||||
aiodhcpwatcher==1.2.0
|
||||
aiodhcpwatcher==1.1.1
|
||||
|
||||
# homeassistant.components.dhcp
|
||||
aiodiscover==2.7.0
|
||||
@@ -837,7 +837,7 @@ gardena-bluetooth==1.6.0
|
||||
gassist-text==0.0.12
|
||||
|
||||
# homeassistant.components.google
|
||||
gcal-sync==7.0.1
|
||||
gcal-sync==7.0.0
|
||||
|
||||
# homeassistant.components.geniushub
|
||||
geniushub-client==0.7.1
|
||||
@@ -1018,7 +1018,7 @@ ibeacon-ble==1.2.0
|
||||
# homeassistant.components.local_calendar
|
||||
# homeassistant.components.local_todo
|
||||
# homeassistant.components.remote_calendar
|
||||
ical==9.2.2
|
||||
ical==9.2.1
|
||||
|
||||
# homeassistant.components.caldav
|
||||
icalendar==6.1.0
|
||||
@@ -2509,7 +2509,7 @@ xbox-webapi==2.1.0
|
||||
xiaomi-ble==0.38.0
|
||||
|
||||
# homeassistant.components.knx
|
||||
xknx==3.8.0
|
||||
xknx==3.6.0
|
||||
|
||||
# homeassistant.components.knx
|
||||
xknxproject==3.8.2
|
||||
|
||||
2
script/hassfest/docker/Dockerfile
generated
2
script/hassfest/docker/Dockerfile
generated
@@ -24,7 +24,7 @@ RUN --mount=from=ghcr.io/astral-sh/uv:0.7.1,source=/uv,target=/bin/uv \
|
||||
--no-cache \
|
||||
-c /usr/src/homeassistant/homeassistant/package_constraints.txt \
|
||||
-r /usr/src/homeassistant/requirements.txt \
|
||||
stdlib-list==0.10.0 pipdeptree==2.26.1 tqdm==4.67.1 ruff==0.11.0 \
|
||||
stdlib-list==0.10.0 pipdeptree==2.25.1 tqdm==4.67.1 ruff==0.11.0 \
|
||||
PyTurboJPEG==1.7.5 go2rtc-client==0.1.2 ha-ffmpeg==3.2.2 hassil==2.2.3 home-assistant-intents==2025.5.7 mutagen==1.47.0 pymicro-vad==1.0.1 pyspeex-noise==1.0.2
|
||||
|
||||
LABEL "name"="hassfest"
|
||||
|
||||
@@ -651,6 +651,7 @@ class RegistryEntryWithDefaults(er.RegistryEntry):
|
||||
"""Helper to create a registry entry with defaults."""
|
||||
|
||||
capabilities: Mapping[str, Any] | None = attr.ib(default=None)
|
||||
calculated_object_id: str | None = attr.ib(default=None)
|
||||
config_entry_id: str | None = attr.ib(default=None)
|
||||
config_subentry_id: str | None = attr.ib(default=None)
|
||||
created_at: datetime = attr.ib(factory=dt_util.utcnow)
|
||||
@@ -669,6 +670,7 @@ class RegistryEntryWithDefaults(er.RegistryEntry):
|
||||
original_device_class: str | None = attr.ib(default=None)
|
||||
original_icon: str | None = attr.ib(default=None)
|
||||
original_name: str | None = attr.ib(default=None)
|
||||
suggested_object_id: str | None = attr.ib(default=None)
|
||||
supported_features: int = attr.ib(default=0)
|
||||
translation_key: str | None = attr.ib(default=None)
|
||||
unit_of_measurement: str | None = attr.ib(default=None)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'LUNAR-DDEEFF Timer running',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': 'Timer running',
|
||||
'platform': 'acaia',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'timer_running',
|
||||
'unique_id': 'aa:bb:cc:dd:ee:ff_timer_running',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'LUNAR-DDEEFF Reset timer',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': 'Reset timer',
|
||||
'platform': 'acaia',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'reset_timer',
|
||||
'unique_id': 'aa:bb:cc:dd:ee:ff_reset_timer',
|
||||
@@ -51,6 +53,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'LUNAR-DDEEFF Start/stop timer',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -74,6 +77,7 @@
|
||||
'original_name': 'Start/stop timer',
|
||||
'platform': 'acaia',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'start_stop',
|
||||
'unique_id': 'aa:bb:cc:dd:ee:ff_start_stop',
|
||||
@@ -98,6 +102,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'LUNAR-DDEEFF Tare',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -121,6 +126,7 @@
|
||||
'original_name': 'Tare',
|
||||
'platform': 'acaia',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'tare',
|
||||
'unique_id': 'aa:bb:cc:dd:ee:ff_tare',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'LUNAR-DDEEFF Battery',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -29,6 +30,7 @@
|
||||
'original_name': 'Battery',
|
||||
'platform': 'acaia',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'aa:bb:cc:dd:ee:ff_battery',
|
||||
@@ -56,6 +58,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'LUNAR-DDEEFF Volume flow rate',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -84,6 +87,7 @@
|
||||
'original_name': 'Volume flow rate',
|
||||
'platform': 'acaia',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'aa:bb:cc:dd:ee:ff_flow_rate',
|
||||
@@ -111,6 +115,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'LUNAR-DDEEFF Weight',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -136,6 +141,7 @@
|
||||
'original_name': 'Weight',
|
||||
'platform': 'acaia',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'aa:bb:cc:dd:ee:ff_weight',
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -245,6 +245,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Home',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -268,6 +269,7 @@
|
||||
'original_name': None,
|
||||
'platform': 'accuweather',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': <WeatherEntityFeature: 1>,
|
||||
'translation_key': None,
|
||||
'unique_id': '0123456',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Calibrate CO2 sensor',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': 'Calibrate CO2 sensor',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'co2_calibration',
|
||||
'unique_id': '84fce612f5b8-co2_calibration',
|
||||
@@ -51,6 +53,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Test LED bar',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -74,6 +77,7 @@
|
||||
'original_name': 'Test LED bar',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'led_bar_test',
|
||||
'unique_id': '84fce612f5b8-led_bar_test',
|
||||
@@ -98,6 +102,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Calibrate CO2 sensor',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -121,6 +126,7 @@
|
||||
'original_name': 'Calibrate CO2 sensor',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'co2_calibration',
|
||||
'unique_id': '84fce612f5b8-co2_calibration',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Display brightness',
|
||||
'capabilities': dict({
|
||||
'max': 100,
|
||||
'min': 0,
|
||||
@@ -32,6 +33,7 @@
|
||||
'original_name': 'Display brightness',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'display_brightness',
|
||||
'unique_id': '84fce612f5b8-display_brightness',
|
||||
@@ -61,6 +63,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient LED bar brightness',
|
||||
'capabilities': dict({
|
||||
'max': 100,
|
||||
'min': 0,
|
||||
@@ -89,6 +92,7 @@
|
||||
'original_name': 'LED bar brightness',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'led_bar_brightness',
|
||||
'unique_id': '84fce612f5b8-led_bar_brightness',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient CO2 automatic baseline duration',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'1',
|
||||
@@ -36,6 +37,7 @@
|
||||
'original_name': 'CO2 automatic baseline duration',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'co2_automatic_baseline_calibration',
|
||||
'unique_id': '84fce612f5b8-co2_automatic_baseline_calibration',
|
||||
@@ -68,6 +70,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Configuration source',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'cloud',
|
||||
@@ -96,6 +99,7 @@
|
||||
'original_name': 'Configuration source',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'configuration_control',
|
||||
'unique_id': '84fce612f5b8-configuration_control',
|
||||
@@ -124,6 +128,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Display PM standard',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'ugm3',
|
||||
@@ -152,6 +157,7 @@
|
||||
'original_name': 'Display PM standard',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'display_pm_standard',
|
||||
'unique_id': '84fce612f5b8-display_pm_standard',
|
||||
@@ -180,6 +186,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Display temperature unit',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'c',
|
||||
@@ -208,6 +215,7 @@
|
||||
'original_name': 'Display temperature unit',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'display_temperature_unit',
|
||||
'unique_id': '84fce612f5b8-display_temperature_unit',
|
||||
@@ -236,6 +244,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient LED bar mode',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'off',
|
||||
@@ -265,6 +274,7 @@
|
||||
'original_name': 'LED bar mode',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'led_bar_mode',
|
||||
'unique_id': '84fce612f5b8-led_bar_mode',
|
||||
@@ -294,6 +304,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient NOx index learning offset',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'12',
|
||||
@@ -325,6 +336,7 @@
|
||||
'original_name': 'NOx index learning offset',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'nox_index_learning_time_offset',
|
||||
'unique_id': '84fce612f5b8-nox_index_learning_time_offset',
|
||||
@@ -356,6 +368,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient VOC index learning offset',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'12',
|
||||
@@ -387,6 +400,7 @@
|
||||
'original_name': 'VOC index learning offset',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'voc_index_learning_time_offset',
|
||||
'unique_id': '84fce612f5b8-voc_index_learning_time_offset',
|
||||
@@ -418,6 +432,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient CO2 automatic baseline duration',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'1',
|
||||
@@ -450,6 +465,7 @@
|
||||
'original_name': 'CO2 automatic baseline duration',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'co2_automatic_baseline_calibration',
|
||||
'unique_id': '84fce612f5b8-co2_automatic_baseline_calibration',
|
||||
@@ -482,6 +498,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Configuration source',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'cloud',
|
||||
@@ -510,6 +527,7 @@
|
||||
'original_name': 'Configuration source',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'configuration_control',
|
||||
'unique_id': '84fce612f5b8-configuration_control',
|
||||
@@ -538,6 +556,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient NOx index learning offset',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'12',
|
||||
@@ -569,6 +588,7 @@
|
||||
'original_name': 'NOx index learning offset',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'nox_index_learning_time_offset',
|
||||
'unique_id': '84fce612f5b8-nox_index_learning_time_offset',
|
||||
@@ -600,6 +620,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient VOC index learning offset',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'12',
|
||||
@@ -631,6 +652,7 @@
|
||||
'original_name': 'VOC index learning offset',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'voc_index_learning_time_offset',
|
||||
'unique_id': '84fce612f5b8-voc_index_learning_time_offset',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Carbon dioxide',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -29,6 +30,7 @@
|
||||
'original_name': 'Carbon dioxide',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '84fce612f5b8-co2',
|
||||
@@ -56,6 +58,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Carbon dioxide automatic baseline calibration',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -79,6 +82,7 @@
|
||||
'original_name': 'Carbon dioxide automatic baseline calibration',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'co2_automatic_baseline_calibration_days',
|
||||
'unique_id': '84fce612f5b8-co2_automatic_baseline_calibration_days',
|
||||
@@ -105,6 +109,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Display brightness',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -128,6 +133,7 @@
|
||||
'original_name': 'Display brightness',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'display_brightness',
|
||||
'unique_id': '84fce612f5b8-display_brightness',
|
||||
@@ -153,6 +159,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Display PM standard',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'ugm3',
|
||||
@@ -181,6 +188,7 @@
|
||||
'original_name': 'Display PM standard',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'display_pm_standard',
|
||||
'unique_id': '84fce612f5b8-display_pm_standard',
|
||||
@@ -210,6 +218,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Display temperature unit',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'c',
|
||||
@@ -238,6 +247,7 @@
|
||||
'original_name': 'Display temperature unit',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'display_temperature_unit',
|
||||
'unique_id': '84fce612f5b8-display_temperature_unit',
|
||||
@@ -267,6 +277,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Humidity',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -292,6 +303,7 @@
|
||||
'original_name': 'Humidity',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '84fce612f5b8-humidity',
|
||||
@@ -319,6 +331,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient LED bar brightness',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -342,6 +355,7 @@
|
||||
'original_name': 'LED bar brightness',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'led_bar_brightness',
|
||||
'unique_id': '84fce612f5b8-led_bar_brightness',
|
||||
@@ -367,6 +381,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient LED bar mode',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'off',
|
||||
@@ -396,6 +411,7 @@
|
||||
'original_name': 'LED bar mode',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'led_bar_mode',
|
||||
'unique_id': '84fce612f5b8-led_bar_mode',
|
||||
@@ -426,6 +442,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient NOx index',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -451,6 +468,7 @@
|
||||
'original_name': 'NOx index',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'nitrogen_index',
|
||||
'unique_id': '84fce612f5b8-nitrogen_index',
|
||||
@@ -476,6 +494,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient NOx index learning offset',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -499,6 +518,7 @@
|
||||
'original_name': 'NOx index learning offset',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'nox_learning_offset',
|
||||
'unique_id': '84fce612f5b8-nox_learning_offset',
|
||||
@@ -525,6 +545,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient PM0.3',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -550,6 +571,7 @@
|
||||
'original_name': 'PM0.3',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'pm003_count',
|
||||
'unique_id': '84fce612f5b8-pm003',
|
||||
@@ -576,6 +598,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient PM1',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -601,6 +624,7 @@
|
||||
'original_name': 'PM1',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '84fce612f5b8-pm01',
|
||||
@@ -628,6 +652,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient PM10',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -653,6 +678,7 @@
|
||||
'original_name': 'PM10',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '84fce612f5b8-pm10',
|
||||
@@ -680,6 +706,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient PM2.5',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -705,6 +732,7 @@
|
||||
'original_name': 'PM2.5',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '84fce612f5b8-pm02',
|
||||
@@ -732,6 +760,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Raw NOx',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -757,6 +786,7 @@
|
||||
'original_name': 'Raw NOx',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'raw_nitrogen',
|
||||
'unique_id': '84fce612f5b8-nox_raw',
|
||||
@@ -783,6 +813,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Raw PM2.5',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -808,6 +839,7 @@
|
||||
'original_name': 'Raw PM2.5',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'raw_pm02',
|
||||
'unique_id': '84fce612f5b8-pm02_raw',
|
||||
@@ -835,6 +867,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Raw VOC',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -860,6 +893,7 @@
|
||||
'original_name': 'Raw VOC',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'raw_total_volatile_organic_component',
|
||||
'unique_id': '84fce612f5b8-tvoc_raw',
|
||||
@@ -886,6 +920,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Signal strength',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -911,6 +946,7 @@
|
||||
'original_name': 'Signal strength',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '84fce612f5b8-signal_strength',
|
||||
@@ -938,6 +974,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Temperature',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -963,6 +1000,7 @@
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '84fce612f5b8-temperature',
|
||||
@@ -990,6 +1028,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient VOC index',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1015,6 +1054,7 @@
|
||||
'original_name': 'VOC index',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'total_volatile_organic_component_index',
|
||||
'unique_id': '84fce612f5b8-tvoc',
|
||||
@@ -1040,6 +1080,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient VOC index learning offset',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -1063,6 +1104,7 @@
|
||||
'original_name': 'VOC index learning offset',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'tvoc_learning_offset',
|
||||
'unique_id': '84fce612f5b8-tvoc_learning_offset',
|
||||
@@ -1089,6 +1131,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Carbon dioxide automatic baseline calibration',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -1112,6 +1155,7 @@
|
||||
'original_name': 'Carbon dioxide automatic baseline calibration',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'co2_automatic_baseline_calibration_days',
|
||||
'unique_id': '84fce612f5b8-co2_automatic_baseline_calibration_days',
|
||||
@@ -1138,6 +1182,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient NOx index',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1163,6 +1208,7 @@
|
||||
'original_name': 'NOx index',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'nitrogen_index',
|
||||
'unique_id': '84fce612f5b8-nitrogen_index',
|
||||
@@ -1188,6 +1234,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient NOx index learning offset',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -1211,6 +1258,7 @@
|
||||
'original_name': 'NOx index learning offset',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'nox_learning_offset',
|
||||
'unique_id': '84fce612f5b8-nox_learning_offset',
|
||||
@@ -1237,6 +1285,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Raw NOx',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1262,6 +1311,7 @@
|
||||
'original_name': 'Raw NOx',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'raw_nitrogen',
|
||||
'unique_id': '84fce612f5b8-nox_raw',
|
||||
@@ -1288,6 +1338,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Raw VOC',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1313,6 +1364,7 @@
|
||||
'original_name': 'Raw VOC',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'raw_total_volatile_organic_component',
|
||||
'unique_id': '84fce612f5b8-tvoc_raw',
|
||||
@@ -1339,6 +1391,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Signal strength',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1364,6 +1417,7 @@
|
||||
'original_name': 'Signal strength',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '84fce612f5b8-signal_strength',
|
||||
@@ -1391,6 +1445,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient VOC index',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1416,6 +1471,7 @@
|
||||
'original_name': 'VOC index',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'total_volatile_organic_component_index',
|
||||
'unique_id': '84fce612f5b8-tvoc',
|
||||
@@ -1441,6 +1497,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient VOC index learning offset',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -1464,6 +1521,7 @@
|
||||
'original_name': 'VOC index learning offset',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'tvoc_learning_offset',
|
||||
'unique_id': '84fce612f5b8-tvoc_learning_offset',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Post data to Airgradient',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': 'Post data to Airgradient',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'post_data_to_airgradient',
|
||||
'unique_id': '84fce612f5b8-post_data_to_airgradient',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airgradient Firmware',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': 'Firmware',
|
||||
'platform': 'airgradient',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '84fce612f5b8-update',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Home Carbon monoxide',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -32,6 +33,7 @@
|
||||
'original_name': 'Carbon monoxide',
|
||||
'platform': 'airly',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'co',
|
||||
'unique_id': '123-456-co',
|
||||
@@ -61,6 +63,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Home Common air quality index',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -87,6 +90,7 @@
|
||||
'original_name': 'Common air quality index',
|
||||
'platform': 'airly',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'caqi',
|
||||
'unique_id': '123-456-caqi',
|
||||
@@ -116,6 +120,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Home Humidity',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -144,6 +149,7 @@
|
||||
'original_name': 'Humidity',
|
||||
'platform': 'airly',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '123-456-humidity',
|
||||
@@ -172,6 +178,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Home Nitrogen dioxide',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -200,6 +207,7 @@
|
||||
'original_name': 'Nitrogen dioxide',
|
||||
'platform': 'airly',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '123-456-no2',
|
||||
@@ -230,6 +238,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Home Ozone',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -258,6 +267,7 @@
|
||||
'original_name': 'Ozone',
|
||||
'platform': 'airly',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '123-456-o3',
|
||||
@@ -288,6 +298,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Home PM1',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -316,6 +327,7 @@
|
||||
'original_name': 'PM1',
|
||||
'platform': 'airly',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '123-456-pm1',
|
||||
@@ -344,6 +356,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Home PM10',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -372,6 +385,7 @@
|
||||
'original_name': 'PM10',
|
||||
'platform': 'airly',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '123-456-pm10',
|
||||
@@ -402,6 +416,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Home PM2.5',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -430,6 +445,7 @@
|
||||
'original_name': 'PM2.5',
|
||||
'platform': 'airly',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '123-456-pm25',
|
||||
@@ -460,6 +476,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Home Pressure',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -488,6 +505,7 @@
|
||||
'original_name': 'Pressure',
|
||||
'platform': 'airly',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '123-456-pressure',
|
||||
@@ -516,6 +534,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Home Sulphur dioxide',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -544,6 +563,7 @@
|
||||
'original_name': 'Sulphur dioxide',
|
||||
'platform': 'airly',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '123-456-so2',
|
||||
@@ -574,6 +594,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Home Temperature',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -602,6 +623,7 @@
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'airly',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '123-456-temperature',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Zone 1 Damper',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': 'Damper',
|
||||
'platform': 'airtouch5',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': <CoverEntityFeature: 7>,
|
||||
'translation_key': 'damper',
|
||||
'unique_id': 'zone_1_open_percentage',
|
||||
@@ -54,6 +56,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Zone 2 Damper',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -77,6 +80,7 @@
|
||||
'original_name': 'Damper',
|
||||
'platform': 'airtouch5',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': <CoverEntityFeature: 7>,
|
||||
'translation_key': 'damper',
|
||||
'unique_id': 'zone_2_open_percentage',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airzone 2:1 Humidity',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -29,6 +30,7 @@
|
||||
'original_name': 'Humidity',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_2:1_humidity',
|
||||
@@ -56,6 +58,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airzone 2:1 Temperature',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -81,6 +84,7 @@
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_2:1_temp',
|
||||
@@ -108,6 +112,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airzone DHW Temperature',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -133,6 +138,7 @@
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_dhw_temp',
|
||||
@@ -160,6 +166,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Airzone WebServer RSSI',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -185,6 +192,7 @@
|
||||
'original_name': 'RSSI',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'rssi',
|
||||
'unique_id': 'airzone_unique_id_ws_wifi-rssi',
|
||||
@@ -212,6 +220,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Aux Heat Temperature',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -237,6 +246,7 @@
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_4:1_temp',
|
||||
@@ -264,6 +274,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Despacho Battery',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -289,6 +300,7 @@
|
||||
'original_name': 'Battery',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_1:4_thermostat-battery',
|
||||
@@ -316,6 +328,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Despacho Humidity',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -341,6 +354,7 @@
|
||||
'original_name': 'Humidity',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_1:4_humidity',
|
||||
@@ -368,6 +382,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Despacho Signal strength',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -393,6 +408,7 @@
|
||||
'original_name': 'Signal strength',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'thermostat_signal',
|
||||
'unique_id': 'airzone_unique_id_1:4_thermostat-signal',
|
||||
@@ -419,6 +435,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Despacho Temperature',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -444,6 +461,7 @@
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_1:4_temp',
|
||||
@@ -471,6 +489,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'DKN Plus Temperature',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -496,6 +515,7 @@
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_3:1_temp',
|
||||
@@ -523,6 +543,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Dorm #1 Battery',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -548,6 +569,7 @@
|
||||
'original_name': 'Battery',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_1:3_thermostat-battery',
|
||||
@@ -575,6 +597,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Dorm #1 Humidity',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -600,6 +623,7 @@
|
||||
'original_name': 'Humidity',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_1:3_humidity',
|
||||
@@ -627,6 +651,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Dorm #1 Signal strength',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -652,6 +677,7 @@
|
||||
'original_name': 'Signal strength',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'thermostat_signal',
|
||||
'unique_id': 'airzone_unique_id_1:3_thermostat-signal',
|
||||
@@ -678,6 +704,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Dorm #1 Temperature',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -703,6 +730,7 @@
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_1:3_temp',
|
||||
@@ -730,6 +758,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Dorm #2 Battery',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -755,6 +784,7 @@
|
||||
'original_name': 'Battery',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_1:5_thermostat-battery',
|
||||
@@ -782,6 +812,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Dorm #2 Humidity',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -807,6 +838,7 @@
|
||||
'original_name': 'Humidity',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_1:5_humidity',
|
||||
@@ -834,6 +866,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Dorm #2 Signal strength',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -859,6 +892,7 @@
|
||||
'original_name': 'Signal strength',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'thermostat_signal',
|
||||
'unique_id': 'airzone_unique_id_1:5_thermostat-signal',
|
||||
@@ -885,6 +919,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Dorm #2 Temperature',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -910,6 +945,7 @@
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_1:5_temp',
|
||||
@@ -937,6 +973,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Dorm Ppal Battery',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -962,6 +999,7 @@
|
||||
'original_name': 'Battery',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_1:2_thermostat-battery',
|
||||
@@ -989,6 +1027,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Dorm Ppal Humidity',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1014,6 +1053,7 @@
|
||||
'original_name': 'Humidity',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_1:2_humidity',
|
||||
@@ -1041,6 +1081,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Dorm Ppal Signal strength',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1066,6 +1107,7 @@
|
||||
'original_name': 'Signal strength',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'thermostat_signal',
|
||||
'unique_id': 'airzone_unique_id_1:2_thermostat-signal',
|
||||
@@ -1092,6 +1134,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Dorm Ppal Temperature',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1117,6 +1160,7 @@
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_1:2_temp',
|
||||
@@ -1144,6 +1188,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Salon Humidity',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1169,6 +1214,7 @@
|
||||
'original_name': 'Humidity',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_1:1_humidity',
|
||||
@@ -1196,6 +1242,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Salon Temperature',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1221,6 +1268,7 @@
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'airzone',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'airzone_unique_id_1:1_temp',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A Absolute pressure',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -35,6 +36,7 @@
|
||||
'original_name': 'Absolute pressure',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'absolute_pressure',
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_baromabsin',
|
||||
@@ -64,6 +66,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A Daily rain',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -95,6 +98,7 @@
|
||||
'original_name': 'Daily rain',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'daily_rain',
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_dailyrainin',
|
||||
@@ -124,6 +128,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A Dew point',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -152,6 +157,7 @@
|
||||
'original_name': 'Dew point',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'dew_point',
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_dewPoint',
|
||||
@@ -181,6 +187,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A Feels like',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -209,6 +216,7 @@
|
||||
'original_name': 'Feels like',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'feels_like',
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_feelsLike',
|
||||
@@ -238,6 +246,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A Hourly rain',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -269,6 +278,7 @@
|
||||
'original_name': 'Hourly rain',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'hourly_rain',
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_hourlyrainin',
|
||||
@@ -298,6 +308,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A Humidity',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -326,6 +337,7 @@
|
||||
'original_name': 'Humidity',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_humidity',
|
||||
@@ -355,6 +367,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A Irradiance',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -383,6 +396,7 @@
|
||||
'original_name': 'Irradiance',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_solarradiation',
|
||||
@@ -412,6 +426,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A Last rain',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -435,6 +450,7 @@
|
||||
'original_name': 'Last rain',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'last_rain',
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_lastRain',
|
||||
@@ -462,6 +478,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A Max daily gust',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -493,6 +510,7 @@
|
||||
'original_name': 'Max daily gust',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'max_daily_gust',
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_maxdailygust',
|
||||
@@ -522,6 +540,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A Monthly rain',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -553,6 +572,7 @@
|
||||
'original_name': 'Monthly rain',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'monthly_rain',
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_monthlyrainin',
|
||||
@@ -582,6 +602,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A Relative pressure',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -613,6 +634,7 @@
|
||||
'original_name': 'Relative pressure',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'relative_pressure',
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_baromrelin',
|
||||
@@ -642,6 +664,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A Temperature',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -670,6 +693,7 @@
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_tempf',
|
||||
@@ -699,6 +723,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A UV index',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -727,6 +752,7 @@
|
||||
'original_name': 'UV index',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'uv_index',
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_uv',
|
||||
@@ -755,6 +781,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A Weekly rain',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -786,6 +813,7 @@
|
||||
'original_name': 'Weekly rain',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'weekly_rain',
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_weeklyrainin',
|
||||
@@ -815,6 +843,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A Wind direction',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT_ANGLE: 'measurement_angle'>,
|
||||
}),
|
||||
@@ -843,6 +872,7 @@
|
||||
'original_name': 'Wind direction',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'wind_direction',
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_winddir',
|
||||
@@ -872,6 +902,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A Wind gust',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -903,6 +934,7 @@
|
||||
'original_name': 'Wind gust',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'wind_gust',
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_windgustmph',
|
||||
@@ -932,6 +964,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station A Wind speed',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -963,6 +996,7 @@
|
||||
'original_name': 'Wind speed',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'AA:AA:AA:AA:AA:AA_windspeedmph',
|
||||
@@ -992,6 +1026,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C Absolute pressure',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1023,6 +1058,7 @@
|
||||
'original_name': 'Absolute pressure',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'absolute_pressure',
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_baromabsin',
|
||||
@@ -1052,6 +1088,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C Daily rain',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -1083,6 +1120,7 @@
|
||||
'original_name': 'Daily rain',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'daily_rain',
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_dailyrainin',
|
||||
@@ -1112,6 +1150,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C Dew point',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1140,6 +1179,7 @@
|
||||
'original_name': 'Dew point',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'dew_point',
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_dewPoint',
|
||||
@@ -1169,6 +1209,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C Feels like',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1197,6 +1238,7 @@
|
||||
'original_name': 'Feels like',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'feels_like',
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_feelsLike',
|
||||
@@ -1226,6 +1268,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C Hourly rain',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1257,6 +1300,7 @@
|
||||
'original_name': 'Hourly rain',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'hourly_rain',
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_hourlyrainin',
|
||||
@@ -1286,6 +1330,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C Humidity',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1314,6 +1359,7 @@
|
||||
'original_name': 'Humidity',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_humidity',
|
||||
@@ -1343,6 +1389,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C Irradiance',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1371,6 +1418,7 @@
|
||||
'original_name': 'Irradiance',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_solarradiation',
|
||||
@@ -1400,6 +1448,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C Last rain',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -1423,6 +1472,7 @@
|
||||
'original_name': 'Last rain',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'last_rain',
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_lastRain',
|
||||
@@ -1450,6 +1500,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C Max daily gust',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1481,6 +1532,7 @@
|
||||
'original_name': 'Max daily gust',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'max_daily_gust',
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_maxdailygust',
|
||||
@@ -1510,6 +1562,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C Monthly rain',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -1541,6 +1594,7 @@
|
||||
'original_name': 'Monthly rain',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'monthly_rain',
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_monthlyrainin',
|
||||
@@ -1570,6 +1624,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C Relative pressure',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1601,6 +1656,7 @@
|
||||
'original_name': 'Relative pressure',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'relative_pressure',
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_baromrelin',
|
||||
@@ -1630,6 +1686,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C Temperature',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1658,6 +1715,7 @@
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_tempf',
|
||||
@@ -1687,6 +1745,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C UV index',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1715,6 +1774,7 @@
|
||||
'original_name': 'UV index',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'uv_index',
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_uv',
|
||||
@@ -1743,6 +1803,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C Weekly rain',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -1774,6 +1835,7 @@
|
||||
'original_name': 'Weekly rain',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'weekly_rain',
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_weeklyrainin',
|
||||
@@ -1803,6 +1865,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C Wind direction',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT_ANGLE: 'measurement_angle'>,
|
||||
}),
|
||||
@@ -1831,6 +1894,7 @@
|
||||
'original_name': 'Wind direction',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'wind_direction',
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_winddir',
|
||||
@@ -1860,6 +1924,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C Wind gust',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1891,6 +1956,7 @@
|
||||
'original_name': 'Wind gust',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'wind_gust',
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_windgustmph',
|
||||
@@ -1920,6 +1986,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station C Wind speed',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -1951,6 +2018,7 @@
|
||||
'original_name': 'Wind speed',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'CC:CC:CC:CC:CC:CC_windspeedmph',
|
||||
@@ -1980,6 +2048,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station D Absolute pressure',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -2011,6 +2080,7 @@
|
||||
'original_name': 'Absolute pressure',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'absolute_pressure',
|
||||
'unique_id': 'DD:DD:DD:DD:DD:DD_baromabsin',
|
||||
@@ -2039,6 +2109,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station D Daily rain',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -2070,6 +2141,7 @@
|
||||
'original_name': 'Daily rain',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'daily_rain',
|
||||
'unique_id': 'DD:DD:DD:DD:DD:DD_dailyrainin',
|
||||
@@ -2098,6 +2170,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station D Dew point',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -2126,6 +2199,7 @@
|
||||
'original_name': 'Dew point',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'dew_point',
|
||||
'unique_id': 'DD:DD:DD:DD:DD:DD_dewPoint',
|
||||
@@ -2154,6 +2228,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station D Feels like',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -2182,6 +2257,7 @@
|
||||
'original_name': 'Feels like',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'feels_like',
|
||||
'unique_id': 'DD:DD:DD:DD:DD:DD_feelsLike',
|
||||
@@ -2210,6 +2286,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station D Hourly rain',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -2241,6 +2318,7 @@
|
||||
'original_name': 'Hourly rain',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'hourly_rain',
|
||||
'unique_id': 'DD:DD:DD:DD:DD:DD_hourlyrainin',
|
||||
@@ -2269,6 +2347,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station D Humidity',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -2297,6 +2376,7 @@
|
||||
'original_name': 'Humidity',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'DD:DD:DD:DD:DD:DD_humidity',
|
||||
@@ -2325,6 +2405,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station D Irradiance',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -2353,6 +2434,7 @@
|
||||
'original_name': 'Irradiance',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'DD:DD:DD:DD:DD:DD_solarradiation',
|
||||
@@ -2381,6 +2463,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station D Max daily gust',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -2412,6 +2495,7 @@
|
||||
'original_name': 'Max daily gust',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'max_daily_gust',
|
||||
'unique_id': 'DD:DD:DD:DD:DD:DD_maxdailygust',
|
||||
@@ -2440,6 +2524,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station D Monthly rain',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -2471,6 +2556,7 @@
|
||||
'original_name': 'Monthly rain',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'monthly_rain',
|
||||
'unique_id': 'DD:DD:DD:DD:DD:DD_monthlyrainin',
|
||||
@@ -2499,6 +2585,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station D Relative pressure',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -2530,6 +2617,7 @@
|
||||
'original_name': 'Relative pressure',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'relative_pressure',
|
||||
'unique_id': 'DD:DD:DD:DD:DD:DD_baromrelin',
|
||||
@@ -2558,6 +2646,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station D Temperature',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -2586,6 +2675,7 @@
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'DD:DD:DD:DD:DD:DD_tempf',
|
||||
@@ -2614,6 +2704,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station D UV index',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -2642,6 +2733,7 @@
|
||||
'original_name': 'UV index',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'uv_index',
|
||||
'unique_id': 'DD:DD:DD:DD:DD:DD_uv',
|
||||
@@ -2669,6 +2761,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station D Weekly rain',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -2700,6 +2793,7 @@
|
||||
'original_name': 'Weekly rain',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'weekly_rain',
|
||||
'unique_id': 'DD:DD:DD:DD:DD:DD_weeklyrainin',
|
||||
@@ -2728,6 +2822,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station D Wind direction',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT_ANGLE: 'measurement_angle'>,
|
||||
}),
|
||||
@@ -2756,6 +2851,7 @@
|
||||
'original_name': 'Wind direction',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'wind_direction',
|
||||
'unique_id': 'DD:DD:DD:DD:DD:DD_winddir',
|
||||
@@ -2784,6 +2880,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station D Wind gust',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -2815,6 +2912,7 @@
|
||||
'original_name': 'Wind gust',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'wind_gust',
|
||||
'unique_id': 'DD:DD:DD:DD:DD:DD_windgustmph',
|
||||
@@ -2843,6 +2941,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Station D Wind speed',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -2874,6 +2973,7 @@
|
||||
'original_name': 'Wind speed',
|
||||
'platform': 'ambient_network',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'DD:DD:DD:DD:DD:DD_windspeedmph',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Homeassistant Analytics core_samba',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -29,6 +30,7 @@
|
||||
'original_name': 'core_samba',
|
||||
'platform': 'analytics_insights',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'addons',
|
||||
'unique_id': 'addon_core_samba_active_installations',
|
||||
@@ -55,6 +57,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Homeassistant Analytics hacs (custom)',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -80,6 +83,7 @@
|
||||
'original_name': 'hacs (custom)',
|
||||
'platform': 'analytics_insights',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'custom_integrations',
|
||||
'unique_id': 'custom_hacs_active_installations',
|
||||
@@ -106,6 +110,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Homeassistant Analytics myq',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -131,6 +136,7 @@
|
||||
'original_name': 'myq',
|
||||
'platform': 'analytics_insights',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'core_integrations',
|
||||
'unique_id': 'core_myq_active_installations',
|
||||
@@ -157,6 +163,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Homeassistant Analytics spotify',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -182,6 +189,7 @@
|
||||
'original_name': 'spotify',
|
||||
'platform': 'analytics_insights',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'core_integrations',
|
||||
'unique_id': 'core_spotify_active_installations',
|
||||
@@ -208,6 +216,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Homeassistant Analytics Total active installations',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -233,6 +242,7 @@
|
||||
'original_name': 'Total active installations',
|
||||
'platform': 'analytics_insights',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'total_active_installations',
|
||||
'unique_id': 'total_active_installations',
|
||||
@@ -259,6 +269,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Homeassistant Analytics Total reported integrations',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -284,6 +295,7 @@
|
||||
'original_name': 'Total reported integrations',
|
||||
'platform': 'analytics_insights',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'total_reports_integrations',
|
||||
'unique_id': 'total_reports_integrations',
|
||||
@@ -310,6 +322,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Homeassistant Analytics YouTube',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -335,6 +348,7 @@
|
||||
'original_name': 'YouTube',
|
||||
'platform': 'analytics_insights',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'core_integrations',
|
||||
'unique_id': 'core_youtube_active_installations',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'My water heater Energy usage',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
}),
|
||||
@@ -32,6 +33,7 @@
|
||||
'original_name': 'Energy usage',
|
||||
'platform': 'aosmith',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'energy_usage',
|
||||
'unique_id': 'energy_usage_junctionId',
|
||||
@@ -59,6 +61,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'My water heater Hot water availability',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -82,6 +85,7 @@
|
||||
'original_name': 'Hot water availability',
|
||||
'platform': 'aosmith',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'hot_water_availability',
|
||||
'unique_id': 'hot_water_availability_junctionId',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'My water heater',
|
||||
'capabilities': dict({
|
||||
'max_temp': 130,
|
||||
'min_temp': 95,
|
||||
@@ -30,6 +31,7 @@
|
||||
'original_name': None,
|
||||
'platform': 'aosmith',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': <WaterHeaterEntityFeature: 5>,
|
||||
'translation_key': None,
|
||||
'unique_id': 'junctionId',
|
||||
@@ -62,6 +64,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'My water heater',
|
||||
'capabilities': dict({
|
||||
'max_temp': 130,
|
||||
'min_temp': 95,
|
||||
@@ -93,6 +96,7 @@
|
||||
'original_name': None,
|
||||
'platform': 'aosmith',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': <WaterHeaterEntityFeature: 7>,
|
||||
'translation_key': None,
|
||||
'unique_id': 'junctionId',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Mock Title DC 1 short circuit error status',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': 'DC 1 short circuit error status',
|
||||
'platform': 'apsystems',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'dc_1_short_circuit_error_status',
|
||||
'unique_id': 'MY_SERIAL_NUMBER_dc_1_short_circuit_error_status',
|
||||
@@ -52,6 +54,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Mock Title DC 2 short circuit error status',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -75,6 +78,7 @@
|
||||
'original_name': 'DC 2 short circuit error status',
|
||||
'platform': 'apsystems',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'dc_2_short_circuit_error_status',
|
||||
'unique_id': 'MY_SERIAL_NUMBER_dc_2_short_circuit_error_status',
|
||||
@@ -100,6 +104,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Mock Title Off-grid status',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -123,6 +128,7 @@
|
||||
'original_name': 'Off-grid status',
|
||||
'platform': 'apsystems',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'off_grid_status',
|
||||
'unique_id': 'MY_SERIAL_NUMBER_off_grid_status',
|
||||
@@ -148,6 +154,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Mock Title Output fault status',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -171,6 +178,7 @@
|
||||
'original_name': 'Output fault status',
|
||||
'platform': 'apsystems',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'output_fault_status',
|
||||
'unique_id': 'MY_SERIAL_NUMBER_output_fault_status',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Mock Title Max output',
|
||||
'capabilities': dict({
|
||||
'max': 1000,
|
||||
'min': 0,
|
||||
@@ -32,6 +33,7 @@
|
||||
'original_name': 'Max output',
|
||||
'platform': 'apsystems',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'max_output',
|
||||
'unique_id': 'MY_SERIAL_NUMBER_output_limit',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Mock Title Lifetime production of P1',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
}),
|
||||
@@ -29,6 +30,7 @@
|
||||
'original_name': 'Lifetime production of P1',
|
||||
'platform': 'apsystems',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'lifetime_production_p1',
|
||||
'unique_id': 'MY_SERIAL_NUMBER_lifetime_production_p1',
|
||||
@@ -56,6 +58,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Mock Title Lifetime production of P2',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
}),
|
||||
@@ -81,6 +84,7 @@
|
||||
'original_name': 'Lifetime production of P2',
|
||||
'platform': 'apsystems',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'lifetime_production_p2',
|
||||
'unique_id': 'MY_SERIAL_NUMBER_lifetime_production_p2',
|
||||
@@ -108,6 +112,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Mock Title Power of P1',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -133,6 +138,7 @@
|
||||
'original_name': 'Power of P1',
|
||||
'platform': 'apsystems',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'total_power_p1',
|
||||
'unique_id': 'MY_SERIAL_NUMBER_total_power_p1',
|
||||
@@ -160,6 +166,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Mock Title Power of P2',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -185,6 +192,7 @@
|
||||
'original_name': 'Power of P2',
|
||||
'platform': 'apsystems',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'total_power_p2',
|
||||
'unique_id': 'MY_SERIAL_NUMBER_total_power_p2',
|
||||
@@ -212,6 +220,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Mock Title Production of today',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
}),
|
||||
@@ -237,6 +246,7 @@
|
||||
'original_name': 'Production of today',
|
||||
'platform': 'apsystems',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'today_production',
|
||||
'unique_id': 'MY_SERIAL_NUMBER_today_production',
|
||||
@@ -264,6 +274,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Mock Title Production of today from P1',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
}),
|
||||
@@ -289,6 +300,7 @@
|
||||
'original_name': 'Production of today from P1',
|
||||
'platform': 'apsystems',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'today_production_p1',
|
||||
'unique_id': 'MY_SERIAL_NUMBER_today_production_p1',
|
||||
@@ -316,6 +328,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Mock Title Production of today from P2',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
}),
|
||||
@@ -341,6 +354,7 @@
|
||||
'original_name': 'Production of today from P2',
|
||||
'platform': 'apsystems',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'today_production_p2',
|
||||
'unique_id': 'MY_SERIAL_NUMBER_today_production_p2',
|
||||
@@ -368,6 +382,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Mock Title Total lifetime production',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
}),
|
||||
@@ -393,6 +408,7 @@
|
||||
'original_name': 'Total lifetime production',
|
||||
'platform': 'apsystems',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'lifetime_production',
|
||||
'unique_id': 'MY_SERIAL_NUMBER_lifetime_production',
|
||||
@@ -420,6 +436,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Mock Title Total power',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -445,6 +462,7 @@
|
||||
'original_name': 'Total power',
|
||||
'platform': 'apsystems',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'total_power',
|
||||
'unique_id': 'MY_SERIAL_NUMBER_total_power',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Mock Title Inverter status',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': 'Inverter status',
|
||||
'platform': 'apsystems',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'inverter_status',
|
||||
'unique_id': 'MY_SERIAL_NUMBER_inverter_status',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'AquaCell name Battery',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': 'Battery',
|
||||
'platform': 'aquacell',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'DSN-battery',
|
||||
@@ -53,6 +55,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'AquaCell name Salt left side percentage',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -78,6 +81,7 @@
|
||||
'original_name': 'Salt left side percentage',
|
||||
'platform': 'aquacell',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'salt_left_side_percentage',
|
||||
'unique_id': 'DSN-salt_left_side_percentage',
|
||||
@@ -104,6 +108,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'AquaCell name Salt left side time remaining',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -127,6 +132,7 @@
|
||||
'original_name': 'Salt left side time remaining',
|
||||
'platform': 'aquacell',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'salt_left_side_time_remaining',
|
||||
'unique_id': 'DSN-salt_left_side_time_remaining',
|
||||
@@ -153,6 +159,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'AquaCell name Salt right side percentage',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -178,6 +185,7 @@
|
||||
'original_name': 'Salt right side percentage',
|
||||
'platform': 'aquacell',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'salt_right_side_percentage',
|
||||
'unique_id': 'DSN-salt_right_side_percentage',
|
||||
@@ -204,6 +212,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'AquaCell name Salt right side time remaining',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -227,6 +236,7 @@
|
||||
'original_name': 'Salt right side time remaining',
|
||||
'platform': 'aquacell',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'salt_right_side_time_remaining',
|
||||
'unique_id': 'DSN-salt_right_side_time_remaining',
|
||||
@@ -253,6 +263,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'AquaCell name Wi-Fi strength',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'high',
|
||||
@@ -282,6 +293,7 @@
|
||||
'original_name': 'Wi-Fi strength',
|
||||
'platform': 'aquacell',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'wi_fi_strength',
|
||||
'unique_id': 'DSN-wi_fi_strength',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Test Sensor Air quality index',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -29,6 +30,7 @@
|
||||
'original_name': 'Air quality index',
|
||||
'platform': 'arve',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'test-serial-number_AQI',
|
||||
@@ -40,6 +42,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Test Sensor Carbon dioxide',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -65,6 +68,7 @@
|
||||
'original_name': 'Carbon dioxide',
|
||||
'platform': 'arve',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'test-serial-number_CO2',
|
||||
@@ -76,6 +80,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Test Sensor Humidity',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -101,6 +106,7 @@
|
||||
'original_name': 'Humidity',
|
||||
'platform': 'arve',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'test-serial-number_Humidity',
|
||||
@@ -112,6 +118,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Test Sensor PM10',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -137,6 +144,7 @@
|
||||
'original_name': 'PM10',
|
||||
'platform': 'arve',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'test-serial-number_PM10',
|
||||
@@ -148,6 +156,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Test Sensor PM2.5',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -173,6 +182,7 @@
|
||||
'original_name': 'PM2.5',
|
||||
'platform': 'arve',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'test-serial-number_PM25',
|
||||
@@ -184,6 +194,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Test Sensor Temperature',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -209,6 +220,7 @@
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'arve',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'test-serial-number_Temperature',
|
||||
@@ -220,6 +232,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Test Sensor Total volatile organic compounds',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -245,6 +258,7 @@
|
||||
'original_name': 'Total volatile organic compounds',
|
||||
'platform': 'arve',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'tvoc',
|
||||
'unique_id': 'test-serial-number_TVOC',
|
||||
|
||||
@@ -37,7 +37,7 @@ from tests.common import (
|
||||
mock_platform,
|
||||
)
|
||||
from tests.components.stt.common import MockSTTProvider, MockSTTProviderEntity
|
||||
from tests.components.tts.common import MockTTSEntity, MockTTSProvider
|
||||
from tests.components.tts.common import MockTTSProvider
|
||||
|
||||
_TRANSCRIPT = "test transcript"
|
||||
|
||||
@@ -68,15 +68,6 @@ async def mock_tts_provider() -> MockTTSProvider:
|
||||
return provider
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_tts_entity() -> MockTTSEntity:
|
||||
"""Test TTS entity."""
|
||||
entity = MockTTSEntity("en")
|
||||
entity._attr_unique_id = "test_tts"
|
||||
entity._attr_supported_languages = ["en-US"]
|
||||
return entity
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def mock_stt_provider() -> MockSTTProvider:
|
||||
"""Mock STT provider."""
|
||||
@@ -207,7 +198,6 @@ async def init_supporting_components(
|
||||
mock_stt_provider: MockSTTProvider,
|
||||
mock_stt_provider_entity: MockSTTProviderEntity,
|
||||
mock_tts_provider: MockTTSProvider,
|
||||
mock_tts_entity: MockTTSEntity,
|
||||
mock_wake_word_provider_entity: MockWakeWordEntity,
|
||||
mock_wake_word_provider_entity2: MockWakeWordEntity2,
|
||||
config_flow_fixture,
|
||||
@@ -219,7 +209,7 @@ async def init_supporting_components(
|
||||
) -> bool:
|
||||
"""Set up test config entry."""
|
||||
await hass.config_entries.async_forward_entry_setups(
|
||||
config_entry, [Platform.STT, Platform.TTS, Platform.WAKE_WORD]
|
||||
config_entry, [Platform.STT, Platform.WAKE_WORD]
|
||||
)
|
||||
return True
|
||||
|
||||
@@ -240,14 +230,6 @@ async def init_supporting_components(
|
||||
"""Set up test stt platform via config entry."""
|
||||
async_add_entities([mock_stt_provider_entity])
|
||||
|
||||
async def async_setup_entry_tts_platform(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up test tts platform via config entry."""
|
||||
async_add_entities([mock_tts_entity])
|
||||
|
||||
async def async_setup_entry_wake_word_platform(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
@@ -271,7 +253,6 @@ async def init_supporting_components(
|
||||
"test.tts",
|
||||
MockTTSPlatform(
|
||||
async_get_engine=AsyncMock(return_value=mock_tts_provider),
|
||||
async_setup_entry=async_setup_entry_tts_platform,
|
||||
),
|
||||
)
|
||||
mock_platform(
|
||||
|
||||
@@ -74,17 +74,17 @@
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'engine': 'tts.test',
|
||||
'language': 'en_US',
|
||||
'engine': 'test',
|
||||
'language': 'en-US',
|
||||
'tts_input': "Sorry, I couldn't understand that",
|
||||
'voice': None,
|
||||
'voice': 'james_earl_jones',
|
||||
}),
|
||||
'type': <PipelineEventType.TTS_START: 'tts-start'>,
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'tts_output': dict({
|
||||
'media_id': "media-source://tts/tts.test?message=Sorry,+I+couldn't+understand+that&language=en_US&tts_options=%7B%7D",
|
||||
'media_id': "media-source://tts/test?message=Sorry,+I+couldn't+understand+that&language=en-US&tts_options=%7B%22voice%22:%22james_earl_jones%22%7D",
|
||||
'mime_type': 'audio/mpeg',
|
||||
'token': 'test_token.mp3',
|
||||
'url': '/api/tts_proxy/test_token.mp3',
|
||||
@@ -395,17 +395,17 @@
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'engine': 'tts.test',
|
||||
'language': 'en_US',
|
||||
'engine': 'test',
|
||||
'language': 'en-US',
|
||||
'tts_input': "Sorry, I couldn't understand that",
|
||||
'voice': None,
|
||||
'voice': 'james_earl_jones',
|
||||
}),
|
||||
'type': <PipelineEventType.TTS_START: 'tts-start'>,
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'tts_output': dict({
|
||||
'media_id': "media-source://tts/tts.test?message=Sorry,+I+couldn't+understand+that&language=en_US&tts_options=%7B%7D",
|
||||
'media_id': "media-source://tts/test?message=Sorry,+I+couldn't+understand+that&language=en-US&tts_options=%7B%22voice%22:%22james_earl_jones%22%7D",
|
||||
'mime_type': 'audio/mpeg',
|
||||
'token': 'test_token.mp3',
|
||||
'url': '/api/tts_proxy/test_token.mp3',
|
||||
|
||||
@@ -1,158 +1,4 @@
|
||||
# serializer version: 1
|
||||
# name: test_chat_log_tts_streaming[to_stream_tts0]
|
||||
list([
|
||||
dict({
|
||||
'data': dict({
|
||||
'conversation_id': 'mock-ulid',
|
||||
'language': 'en',
|
||||
'pipeline': <ANY>,
|
||||
'tts_output': dict({
|
||||
'mime_type': 'audio/mpeg',
|
||||
'token': 'mocked-token.mp3',
|
||||
'url': '/api/tts_proxy/mocked-token.mp3',
|
||||
}),
|
||||
}),
|
||||
'type': <PipelineEventType.RUN_START: 'run-start'>,
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'conversation_id': 'mock-ulid',
|
||||
'device_id': None,
|
||||
'engine': 'test-agent',
|
||||
'intent_input': 'Set a timer',
|
||||
'language': 'en',
|
||||
'prefer_local_intents': False,
|
||||
}),
|
||||
'type': <PipelineEventType.INTENT_START: 'intent-start'>,
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'chat_log_delta': dict({
|
||||
'role': 'assistant',
|
||||
}),
|
||||
}),
|
||||
'type': <PipelineEventType.INTENT_PROGRESS: 'intent-progress'>,
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'chat_log_delta': dict({
|
||||
'content': 'hello,',
|
||||
}),
|
||||
}),
|
||||
'type': <PipelineEventType.INTENT_PROGRESS: 'intent-progress'>,
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'chat_log_delta': dict({
|
||||
'content': ' ',
|
||||
}),
|
||||
}),
|
||||
'type': <PipelineEventType.INTENT_PROGRESS: 'intent-progress'>,
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'chat_log_delta': dict({
|
||||
'content': 'how',
|
||||
}),
|
||||
}),
|
||||
'type': <PipelineEventType.INTENT_PROGRESS: 'intent-progress'>,
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'chat_log_delta': dict({
|
||||
'content': ' ',
|
||||
}),
|
||||
}),
|
||||
'type': <PipelineEventType.INTENT_PROGRESS: 'intent-progress'>,
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'chat_log_delta': dict({
|
||||
'content': 'are',
|
||||
}),
|
||||
}),
|
||||
'type': <PipelineEventType.INTENT_PROGRESS: 'intent-progress'>,
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'chat_log_delta': dict({
|
||||
'content': ' ',
|
||||
}),
|
||||
}),
|
||||
'type': <PipelineEventType.INTENT_PROGRESS: 'intent-progress'>,
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'chat_log_delta': dict({
|
||||
'content': 'you',
|
||||
}),
|
||||
}),
|
||||
'type': <PipelineEventType.INTENT_PROGRESS: 'intent-progress'>,
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'chat_log_delta': dict({
|
||||
'content': '?',
|
||||
}),
|
||||
}),
|
||||
'type': <PipelineEventType.INTENT_PROGRESS: 'intent-progress'>,
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'intent_output': dict({
|
||||
'continue_conversation': True,
|
||||
'conversation_id': <ANY>,
|
||||
'response': dict({
|
||||
'card': dict({
|
||||
}),
|
||||
'data': dict({
|
||||
'failed': list([
|
||||
]),
|
||||
'success': list([
|
||||
]),
|
||||
'targets': list([
|
||||
]),
|
||||
}),
|
||||
'language': 'en',
|
||||
'response_type': 'action_done',
|
||||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'hello, how are you?',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'processed_locally': False,
|
||||
}),
|
||||
'type': <PipelineEventType.INTENT_END: 'intent-end'>,
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'engine': 'tts.test',
|
||||
'language': 'en_US',
|
||||
'tts_input': 'hello, how are you?',
|
||||
'voice': None,
|
||||
}),
|
||||
'type': <PipelineEventType.TTS_START: 'tts-start'>,
|
||||
}),
|
||||
dict({
|
||||
'data': dict({
|
||||
'tts_output': dict({
|
||||
'media_id': 'media-source://tts/tts.test?message=hello,+how+are+you?&language=en_US&tts_options=%7B%7D',
|
||||
'mime_type': 'audio/mpeg',
|
||||
'token': 'mocked-token.mp3',
|
||||
'url': '/api/tts_proxy/mocked-token.mp3',
|
||||
}),
|
||||
}),
|
||||
'type': <PipelineEventType.TTS_END: 'tts-end'>,
|
||||
}),
|
||||
dict({
|
||||
'data': None,
|
||||
'type': <PipelineEventType.RUN_END: 'run-end'>,
|
||||
}),
|
||||
])
|
||||
# ---
|
||||
# name: test_pipeline_language_used_instead_of_conversation_language
|
||||
list([
|
||||
dict({
|
||||
|
||||
@@ -71,16 +71,16 @@
|
||||
# ---
|
||||
# name: test_audio_pipeline.5
|
||||
dict({
|
||||
'engine': 'tts.test',
|
||||
'language': 'en_US',
|
||||
'engine': 'test',
|
||||
'language': 'en-US',
|
||||
'tts_input': "Sorry, I couldn't understand that",
|
||||
'voice': None,
|
||||
'voice': 'james_earl_jones',
|
||||
})
|
||||
# ---
|
||||
# name: test_audio_pipeline.6
|
||||
dict({
|
||||
'tts_output': dict({
|
||||
'media_id': "media-source://tts/tts.test?message=Sorry,+I+couldn't+understand+that&language=en_US&tts_options=%7B%7D",
|
||||
'media_id': "media-source://tts/test?message=Sorry,+I+couldn't+understand+that&language=en-US&tts_options=%7B%22voice%22:%22james_earl_jones%22%7D",
|
||||
'mime_type': 'audio/mpeg',
|
||||
'token': 'test_token.mp3',
|
||||
'url': '/api/tts_proxy/test_token.mp3',
|
||||
@@ -162,16 +162,16 @@
|
||||
# ---
|
||||
# name: test_audio_pipeline_debug.5
|
||||
dict({
|
||||
'engine': 'tts.test',
|
||||
'language': 'en_US',
|
||||
'engine': 'test',
|
||||
'language': 'en-US',
|
||||
'tts_input': "Sorry, I couldn't understand that",
|
||||
'voice': None,
|
||||
'voice': 'james_earl_jones',
|
||||
})
|
||||
# ---
|
||||
# name: test_audio_pipeline_debug.6
|
||||
dict({
|
||||
'tts_output': dict({
|
||||
'media_id': "media-source://tts/tts.test?message=Sorry,+I+couldn't+understand+that&language=en_US&tts_options=%7B%7D",
|
||||
'media_id': "media-source://tts/test?message=Sorry,+I+couldn't+understand+that&language=en-US&tts_options=%7B%22voice%22:%22james_earl_jones%22%7D",
|
||||
'mime_type': 'audio/mpeg',
|
||||
'token': 'test_token.mp3',
|
||||
'url': '/api/tts_proxy/test_token.mp3',
|
||||
@@ -265,16 +265,16 @@
|
||||
# ---
|
||||
# name: test_audio_pipeline_with_enhancements.5
|
||||
dict({
|
||||
'engine': 'tts.test',
|
||||
'language': 'en_US',
|
||||
'engine': 'test',
|
||||
'language': 'en-US',
|
||||
'tts_input': "Sorry, I couldn't understand that",
|
||||
'voice': None,
|
||||
'voice': 'james_earl_jones',
|
||||
})
|
||||
# ---
|
||||
# name: test_audio_pipeline_with_enhancements.6
|
||||
dict({
|
||||
'tts_output': dict({
|
||||
'media_id': "media-source://tts/tts.test?message=Sorry,+I+couldn't+understand+that&language=en_US&tts_options=%7B%7D",
|
||||
'media_id': "media-source://tts/test?message=Sorry,+I+couldn't+understand+that&language=en-US&tts_options=%7B%22voice%22:%22james_earl_jones%22%7D",
|
||||
'mime_type': 'audio/mpeg',
|
||||
'token': 'test_token.mp3',
|
||||
'url': '/api/tts_proxy/test_token.mp3',
|
||||
@@ -378,16 +378,16 @@
|
||||
# ---
|
||||
# name: test_audio_pipeline_with_wake_word_no_timeout.7
|
||||
dict({
|
||||
'engine': 'tts.test',
|
||||
'language': 'en_US',
|
||||
'engine': 'test',
|
||||
'language': 'en-US',
|
||||
'tts_input': "Sorry, I couldn't understand that",
|
||||
'voice': None,
|
||||
'voice': 'james_earl_jones',
|
||||
})
|
||||
# ---
|
||||
# name: test_audio_pipeline_with_wake_word_no_timeout.8
|
||||
dict({
|
||||
'tts_output': dict({
|
||||
'media_id': "media-source://tts/tts.test?message=Sorry,+I+couldn't+understand+that&language=en_US&tts_options=%7B%7D",
|
||||
'media_id': "media-source://tts/test?message=Sorry,+I+couldn't+understand+that&language=en-US&tts_options=%7B%22voice%22:%22james_earl_jones%22%7D",
|
||||
'mime_type': 'audio/mpeg',
|
||||
'token': 'test_token.mp3',
|
||||
'url': '/api/tts_proxy/test_token.mp3',
|
||||
|
||||
@@ -40,7 +40,6 @@ from . import MANY_LANGUAGES, process_events
|
||||
from .conftest import (
|
||||
MockSTTProvider,
|
||||
MockSTTProviderEntity,
|
||||
MockTTSEntity,
|
||||
MockTTSProvider,
|
||||
MockWakeWordEntity,
|
||||
make_10ms_chunk,
|
||||
@@ -63,12 +62,6 @@ async def load_homeassistant(hass: HomeAssistant) -> None:
|
||||
assert await async_setup_component(hass, "homeassistant", {})
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def disable_tts_entity(mock_tts_entity: tts.TextToSpeechEntity) -> None:
|
||||
"""Disable the TTS entity."""
|
||||
mock_tts_entity._attr_entity_registry_enabled_default = False
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_components")
|
||||
async def test_load_pipelines(hass: HomeAssistant) -> None:
|
||||
"""Make sure that we can load/save data correctly."""
|
||||
@@ -290,7 +283,6 @@ async def test_migrate_pipeline_store(
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_supporting_components")
|
||||
@pytest.mark.usefixtures("disable_tts_entity")
|
||||
async def test_create_default_pipeline(hass: HomeAssistant) -> None:
|
||||
"""Test async_create_default_pipeline."""
|
||||
assert await async_setup_component(hass, "assist_pipeline", {})
|
||||
@@ -438,7 +430,6 @@ async def test_default_pipeline_no_stt_tts(
|
||||
],
|
||||
)
|
||||
@pytest.mark.usefixtures("init_supporting_components")
|
||||
@pytest.mark.usefixtures("disable_tts_entity")
|
||||
async def test_default_pipeline(
|
||||
hass: HomeAssistant,
|
||||
mock_stt_provider_entity: MockSTTProviderEntity,
|
||||
@@ -483,7 +474,6 @@ async def test_default_pipeline(
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_supporting_components")
|
||||
@pytest.mark.usefixtures("disable_tts_entity")
|
||||
async def test_default_pipeline_unsupported_stt_language(
|
||||
hass: HomeAssistant, mock_stt_provider_entity: MockSTTProviderEntity
|
||||
) -> None:
|
||||
@@ -514,7 +504,6 @@ async def test_default_pipeline_unsupported_stt_language(
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_supporting_components")
|
||||
@pytest.mark.usefixtures("disable_tts_entity")
|
||||
async def test_default_pipeline_unsupported_tts_language(
|
||||
hass: HomeAssistant, mock_tts_provider: MockTTSProvider
|
||||
) -> None:
|
||||
@@ -836,7 +825,7 @@ def test_pipeline_run_equality(hass: HomeAssistant, init_components) -> None:
|
||||
async def test_tts_audio_output(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
mock_tts_entity: MockTTSProvider,
|
||||
mock_tts_provider: MockTTSProvider,
|
||||
init_components,
|
||||
pipeline_data: assist_pipeline.pipeline.PipelineData,
|
||||
mock_chat_session: chat_session.ChatSession,
|
||||
@@ -880,7 +869,7 @@ async def test_tts_audio_output(
|
||||
== 1
|
||||
)
|
||||
|
||||
with patch.object(mock_tts_entity, "get_tts_audio") as mock_get_tts_audio:
|
||||
with patch.object(mock_tts_provider, "get_tts_audio") as mock_get_tts_audio:
|
||||
await pipeline_input.execute()
|
||||
|
||||
for event in events:
|
||||
@@ -892,14 +881,14 @@ async def test_tts_audio_output(
|
||||
# Ensure that no unsupported options were passed in
|
||||
assert mock_get_tts_audio.called
|
||||
options = mock_get_tts_audio.call_args_list[0].kwargs["options"]
|
||||
extra_options = set(options).difference(mock_tts_entity.supported_options)
|
||||
extra_options = set(options).difference(mock_tts_provider.supported_options)
|
||||
assert len(extra_options) == 0, extra_options
|
||||
|
||||
|
||||
async def test_tts_wav_preferred_format(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
mock_tts_entity: MockTTSEntity,
|
||||
mock_tts_provider: MockTTSProvider,
|
||||
init_components,
|
||||
mock_chat_session: chat_session.ChatSession,
|
||||
pipeline_data: assist_pipeline.pipeline.PipelineData,
|
||||
@@ -931,7 +920,7 @@ async def test_tts_wav_preferred_format(
|
||||
await pipeline_input.validate()
|
||||
|
||||
# Make the TTS provider support preferred format options
|
||||
supported_options = list(mock_tts_entity.supported_options or [])
|
||||
supported_options = list(mock_tts_provider.supported_options or [])
|
||||
supported_options.extend(
|
||||
[
|
||||
tts.ATTR_PREFERRED_FORMAT,
|
||||
@@ -942,8 +931,8 @@ async def test_tts_wav_preferred_format(
|
||||
)
|
||||
|
||||
with (
|
||||
patch.object(mock_tts_entity, "_supported_options", supported_options),
|
||||
patch.object(mock_tts_entity, "get_tts_audio") as mock_get_tts_audio,
|
||||
patch.object(mock_tts_provider, "_supported_options", supported_options),
|
||||
patch.object(mock_tts_provider, "get_tts_audio") as mock_get_tts_audio,
|
||||
):
|
||||
await pipeline_input.execute()
|
||||
|
||||
@@ -966,7 +955,7 @@ async def test_tts_wav_preferred_format(
|
||||
async def test_tts_dict_preferred_format(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
mock_tts_entity: MockTTSEntity,
|
||||
mock_tts_provider: MockTTSProvider,
|
||||
init_components,
|
||||
mock_chat_session: chat_session.ChatSession,
|
||||
pipeline_data: assist_pipeline.pipeline.PipelineData,
|
||||
@@ -1003,7 +992,7 @@ async def test_tts_dict_preferred_format(
|
||||
await pipeline_input.validate()
|
||||
|
||||
# Make the TTS provider support preferred format options
|
||||
supported_options = list(mock_tts_entity.supported_options or [])
|
||||
supported_options = list(mock_tts_provider.supported_options or [])
|
||||
supported_options.extend(
|
||||
[
|
||||
tts.ATTR_PREFERRED_FORMAT,
|
||||
@@ -1014,8 +1003,8 @@ async def test_tts_dict_preferred_format(
|
||||
)
|
||||
|
||||
with (
|
||||
patch.object(mock_tts_entity, "_supported_options", supported_options),
|
||||
patch.object(mock_tts_entity, "get_tts_audio") as mock_get_tts_audio,
|
||||
patch.object(mock_tts_provider, "_supported_options", supported_options),
|
||||
patch.object(mock_tts_provider, "get_tts_audio") as mock_get_tts_audio,
|
||||
):
|
||||
await pipeline_input.execute()
|
||||
|
||||
@@ -1556,143 +1545,3 @@ async def test_pipeline_language_used_instead_of_conversation_language(
|
||||
mock_async_converse.call_args_list[0].kwargs.get("language")
|
||||
== pipeline.language
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"to_stream_tts",
|
||||
[
|
||||
[
|
||||
"hello,",
|
||||
" ",
|
||||
"how",
|
||||
" ",
|
||||
"are",
|
||||
" ",
|
||||
"you",
|
||||
"?",
|
||||
]
|
||||
],
|
||||
)
|
||||
async def test_chat_log_tts_streaming(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
init_components,
|
||||
mock_chat_session: chat_session.ChatSession,
|
||||
snapshot: SnapshotAssertion,
|
||||
mock_tts_entity: MockTTSEntity,
|
||||
pipeline_data: assist_pipeline.pipeline.PipelineData,
|
||||
to_stream_tts: list[str],
|
||||
) -> None:
|
||||
"""Test that chat log events are streamed to the TTS entity."""
|
||||
events: list[assist_pipeline.PipelineEvent] = []
|
||||
|
||||
pipeline_store = pipeline_data.pipeline_store
|
||||
pipeline_id = pipeline_store.async_get_preferred_item()
|
||||
pipeline = assist_pipeline.pipeline.async_get_pipeline(hass, pipeline_id)
|
||||
await assist_pipeline.pipeline.async_update_pipeline(
|
||||
hass, pipeline, conversation_engine="test-agent"
|
||||
)
|
||||
pipeline = assist_pipeline.pipeline.async_get_pipeline(hass, pipeline_id)
|
||||
|
||||
pipeline_input = assist_pipeline.pipeline.PipelineInput(
|
||||
intent_input="Set a timer",
|
||||
session=mock_chat_session,
|
||||
run=assist_pipeline.pipeline.PipelineRun(
|
||||
hass,
|
||||
context=Context(),
|
||||
pipeline=pipeline,
|
||||
start_stage=assist_pipeline.PipelineStage.INTENT,
|
||||
end_stage=assist_pipeline.PipelineStage.TTS,
|
||||
event_callback=events.append,
|
||||
),
|
||||
)
|
||||
|
||||
received_tts = []
|
||||
|
||||
async def async_stream_tts_audio(
|
||||
request: tts.TTSAudioRequest,
|
||||
) -> tts.TTSAudioResponse:
|
||||
"""Mock stream TTS audio."""
|
||||
|
||||
async def gen_data():
|
||||
async for msg in request.message_gen:
|
||||
received_tts.append(msg)
|
||||
yield msg.encode()
|
||||
|
||||
return tts.TTSAudioResponse(
|
||||
extension="mp3",
|
||||
data_gen=gen_data(),
|
||||
)
|
||||
|
||||
mock_tts_entity.async_stream_tts_audio = async_stream_tts_audio
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.assist_pipeline.pipeline.conversation.async_get_agent_info",
|
||||
return_value=conversation.AgentInfo(id="test-agent", name="Test Agent"),
|
||||
):
|
||||
await pipeline_input.validate()
|
||||
|
||||
async def mock_converse(
|
||||
hass: HomeAssistant,
|
||||
text: str,
|
||||
conversation_id: str | None,
|
||||
context: Context,
|
||||
language: str | None = None,
|
||||
agent_id: str | None = None,
|
||||
device_id: str | None = None,
|
||||
extra_system_prompt: str | None = None,
|
||||
):
|
||||
"""Mock converse."""
|
||||
conversation_input = conversation.ConversationInput(
|
||||
text=text,
|
||||
context=context,
|
||||
conversation_id=conversation_id,
|
||||
device_id=device_id,
|
||||
language=language,
|
||||
agent_id=agent_id,
|
||||
extra_system_prompt=extra_system_prompt,
|
||||
)
|
||||
|
||||
async def stream_llm_response():
|
||||
yield {"role": "assistant"}
|
||||
for chunk in to_stream_tts:
|
||||
yield {"content": chunk}
|
||||
|
||||
with (
|
||||
chat_session.async_get_chat_session(hass, conversation_id) as session,
|
||||
conversation.async_get_chat_log(
|
||||
hass,
|
||||
session,
|
||||
conversation_input,
|
||||
) as chat_log,
|
||||
):
|
||||
async for _content in chat_log.async_add_delta_content_stream(
|
||||
agent_id, stream_llm_response()
|
||||
):
|
||||
pass
|
||||
intent_response = intent.IntentResponse(language)
|
||||
intent_response.async_set_speech("".join(to_stream_tts))
|
||||
return conversation.ConversationResult(
|
||||
response=intent_response,
|
||||
conversation_id=chat_log.conversation_id,
|
||||
continue_conversation=chat_log.continue_conversation,
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.assist_pipeline.pipeline.conversation.async_converse",
|
||||
mock_converse,
|
||||
):
|
||||
await pipeline_input.execute()
|
||||
|
||||
stream = tts.async_get_stream(hass, events[0].data["tts_output"]["token"])
|
||||
assert stream is not None
|
||||
tts_result = "".join(
|
||||
[chunk.decode() async for chunk in stream.async_stream_result()]
|
||||
)
|
||||
|
||||
streamed_text = "".join(to_stream_tts)
|
||||
assert tts_result == streamed_text
|
||||
assert len(received_tts) == 1
|
||||
assert "".join(received_tts) == streamed_text
|
||||
|
||||
assert process_events(events) == snapshot
|
||||
|
||||
@@ -1153,9 +1153,9 @@ async def test_get_pipeline(
|
||||
"name": "Home Assistant",
|
||||
"stt_engine": "stt.mock_stt",
|
||||
"stt_language": "en-US",
|
||||
"tts_engine": "tts.test",
|
||||
"tts_language": "en_US",
|
||||
"tts_voice": None,
|
||||
"tts_engine": "test",
|
||||
"tts_language": "en-US",
|
||||
"tts_voice": "james_earl_jones",
|
||||
"wake_word_entity": None,
|
||||
"wake_word_id": None,
|
||||
"prefer_local_intents": False,
|
||||
@@ -1179,9 +1179,9 @@ async def test_get_pipeline(
|
||||
# It found these defaults
|
||||
"stt_engine": "stt.mock_stt",
|
||||
"stt_language": "en-US",
|
||||
"tts_engine": "tts.test",
|
||||
"tts_language": "en_US",
|
||||
"tts_voice": None,
|
||||
"tts_engine": "test",
|
||||
"tts_language": "en-US",
|
||||
"tts_voice": "james_earl_jones",
|
||||
"wake_word_entity": None,
|
||||
"wake_word_id": None,
|
||||
"prefer_local_intents": False,
|
||||
@@ -1266,9 +1266,9 @@ async def test_list_pipelines(
|
||||
"name": "Home Assistant",
|
||||
"stt_engine": "stt.mock_stt",
|
||||
"stt_language": "en-US",
|
||||
"tts_engine": "tts.test",
|
||||
"tts_language": "en_US",
|
||||
"tts_voice": None,
|
||||
"tts_engine": "test",
|
||||
"tts_language": "en-US",
|
||||
"tts_voice": "james_earl_jones",
|
||||
"wake_word_entity": None,
|
||||
"wake_word_id": None,
|
||||
"prefer_local_intents": False,
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Battery Charged month',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -29,6 +30,7 @@
|
||||
'original_name': 'Charged month',
|
||||
'platform': 'autarco',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'charged_month',
|
||||
'unique_id': '1_battery_charged_month',
|
||||
@@ -56,6 +58,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Battery Charged today',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -81,6 +84,7 @@
|
||||
'original_name': 'Charged today',
|
||||
'platform': 'autarco',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'charged_today',
|
||||
'unique_id': '1_battery_charged_today',
|
||||
@@ -108,6 +112,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Battery Charged total',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
}),
|
||||
@@ -133,6 +138,7 @@
|
||||
'original_name': 'Charged total',
|
||||
'platform': 'autarco',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'charged_total',
|
||||
'unique_id': '1_battery_charged_total',
|
||||
@@ -160,6 +166,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Battery Discharged month',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -185,6 +192,7 @@
|
||||
'original_name': 'Discharged month',
|
||||
'platform': 'autarco',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'discharged_month',
|
||||
'unique_id': '1_battery_discharged_month',
|
||||
@@ -212,6 +220,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Battery Discharged today',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -237,6 +246,7 @@
|
||||
'original_name': 'Discharged today',
|
||||
'platform': 'autarco',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'discharged_today',
|
||||
'unique_id': '1_battery_discharged_today',
|
||||
@@ -264,6 +274,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Battery Discharged total',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
}),
|
||||
@@ -289,6 +300,7 @@
|
||||
'original_name': 'Discharged total',
|
||||
'platform': 'autarco',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'discharged_total',
|
||||
'unique_id': '1_battery_discharged_total',
|
||||
@@ -316,6 +328,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Battery Flow now',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -341,6 +354,7 @@
|
||||
'original_name': 'Flow now',
|
||||
'platform': 'autarco',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'flow_now',
|
||||
'unique_id': '1_battery_flow_now',
|
||||
@@ -368,6 +382,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Battery State of charge',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -393,6 +408,7 @@
|
||||
'original_name': 'State of charge',
|
||||
'platform': 'autarco',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'state_of_charge',
|
||||
'unique_id': '1_battery_state_of_charge',
|
||||
@@ -420,6 +436,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Inverter test-serial-1 Energy AC output total',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
}),
|
||||
@@ -445,6 +462,7 @@
|
||||
'original_name': 'Energy AC output total',
|
||||
'platform': 'autarco',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'out_ac_energy_total',
|
||||
'unique_id': 'test-serial-1_out_ac_energy_total',
|
||||
@@ -472,6 +490,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Inverter test-serial-1 Power AC output',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -497,6 +516,7 @@
|
||||
'original_name': 'Power AC output',
|
||||
'platform': 'autarco',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'out_ac_power',
|
||||
'unique_id': 'test-serial-1_out_ac_power',
|
||||
@@ -524,6 +544,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Inverter test-serial-2 Energy AC output total',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
}),
|
||||
@@ -549,6 +570,7 @@
|
||||
'original_name': 'Energy AC output total',
|
||||
'platform': 'autarco',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'out_ac_energy_total',
|
||||
'unique_id': 'test-serial-2_out_ac_energy_total',
|
||||
@@ -576,6 +598,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Inverter test-serial-2 Power AC output',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -601,6 +624,7 @@
|
||||
'original_name': 'Power AC output',
|
||||
'platform': 'autarco',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'out_ac_power',
|
||||
'unique_id': 'test-serial-2_out_ac_power',
|
||||
@@ -628,6 +652,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Solar Energy production month',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -653,6 +678,7 @@
|
||||
'original_name': 'Energy production month',
|
||||
'platform': 'autarco',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'energy_production_month',
|
||||
'unique_id': '1_solar_energy_production_month',
|
||||
@@ -680,6 +706,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Solar Energy production today',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
@@ -705,6 +732,7 @@
|
||||
'original_name': 'Energy production today',
|
||||
'platform': 'autarco',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'energy_production_today',
|
||||
'unique_id': '1_solar_energy_production_today',
|
||||
@@ -732,6 +760,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Solar Energy production total',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
}),
|
||||
@@ -757,6 +786,7 @@
|
||||
'original_name': 'Energy production total',
|
||||
'platform': 'autarco',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'energy_production_total',
|
||||
'unique_id': '1_solar_energy_production_total',
|
||||
@@ -784,6 +814,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Solar Power production',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -809,6 +840,7 @@
|
||||
'original_name': 'Power production',
|
||||
'platform': 'autarco',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'power_production',
|
||||
'unique_id': '1_solar_power_production',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home DayNight 1',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': 'DayNight 1',
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-tns1:VideoSource/tnsaxis:DayNightVision-1',
|
||||
@@ -52,6 +54,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home Object Analytics Device1Scenario8',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -75,6 +78,7 @@
|
||||
'original_name': 'Object Analytics Device1Scenario8',
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-tnsaxis:CameraApplicationPlatform/ObjectAnalytics/Device1Scenario8-Device1Scenario8',
|
||||
@@ -100,6 +104,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home Sound 1',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -123,6 +128,7 @@
|
||||
'original_name': 'Sound 1',
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-tns1:AudioSource/tnsaxis:TriggerLevel-1',
|
||||
@@ -148,6 +154,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home PIR sensor',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -171,6 +178,7 @@
|
||||
'original_name': 'PIR sensor',
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-tns1:Device/tnsaxis:IO/Port-0',
|
||||
@@ -196,6 +204,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home PIR 0',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -219,6 +228,7 @@
|
||||
'original_name': 'PIR 0',
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-tns1:Device/tnsaxis:Sensor/PIR-0',
|
||||
@@ -244,6 +254,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home Fence Guard Profile 1',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -267,6 +278,7 @@
|
||||
'original_name': 'Fence Guard Profile 1',
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-tnsaxis:CameraApplicationPlatform/FenceGuard/Camera1Profile1-Camera1Profile1',
|
||||
@@ -292,6 +304,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home Motion Guard Profile 1',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -315,6 +328,7 @@
|
||||
'original_name': 'Motion Guard Profile 1',
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-tnsaxis:CameraApplicationPlatform/MotionGuard/Camera1Profile1-Camera1Profile1',
|
||||
@@ -340,6 +354,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home Loitering Guard Profile 1',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -363,6 +378,7 @@
|
||||
'original_name': 'Loitering Guard Profile 1',
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-tnsaxis:CameraApplicationPlatform/LoiteringGuard/Camera1Profile1-Camera1Profile1',
|
||||
@@ -388,6 +404,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home VMD4 Profile 1',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -411,6 +428,7 @@
|
||||
'original_name': 'VMD4 Profile 1',
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-tnsaxis:CameraApplicationPlatform/VMD/Camera1Profile1-Camera1Profile1',
|
||||
@@ -436,6 +454,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home Object Analytics Scenario 1',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -459,6 +478,7 @@
|
||||
'original_name': 'Object Analytics Scenario 1',
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-tnsaxis:CameraApplicationPlatform/ObjectAnalytics/Device1Scenario1-Device1Scenario1',
|
||||
@@ -484,6 +504,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home VMD4 Camera1Profile9',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -507,6 +528,7 @@
|
||||
'original_name': 'VMD4 Camera1Profile9',
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-tnsaxis:CameraApplicationPlatform/VMD/Camera1Profile9-Camera1Profile9',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': None,
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': <CameraEntityFeature: 2>,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-camera',
|
||||
@@ -54,6 +56,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -77,6 +80,7 @@
|
||||
'original_name': None,
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': <CameraEntityFeature: 2>,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-camera',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home IR Light 0',
|
||||
'capabilities': dict({
|
||||
'supported_color_modes': list([
|
||||
<ColorMode.BRIGHTNESS: 'brightness'>,
|
||||
@@ -31,6 +32,7 @@
|
||||
'original_name': 'IR Light 0',
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-tns1:Device/tnsaxis:Light/Status-0',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home Doorbell',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': 'Doorbell',
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-tns1:Device/Trigger/Relay-0',
|
||||
@@ -52,6 +54,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home Relay 1',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -75,6 +78,7 @@
|
||||
'original_name': 'Relay 1',
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-tns1:Device/Trigger/Relay-1',
|
||||
@@ -100,6 +104,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home Doorbell',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -123,6 +128,7 @@
|
||||
'original_name': 'Doorbell',
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-tns1:Device/Trigger/Relay-0',
|
||||
@@ -148,6 +154,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'home Relay 1',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -171,6 +178,7 @@
|
||||
'original_name': 'Relay 1',
|
||||
'platform': 'axis',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:40:8c:12:34:56-tns1:Device/Trigger/Relay-1',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'testproject CI latest build',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': 'CI latest build',
|
||||
'platform': 'azure_devops',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'latest_build',
|
||||
'unique_id': 'testorg_1234_9876_latest_build',
|
||||
@@ -63,6 +65,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'testproject CI latest build finish time',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -86,6 +89,7 @@
|
||||
'original_name': 'CI latest build finish time',
|
||||
'platform': 'azure_devops',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'finish_time',
|
||||
'unique_id': 'testorg_1234_9876_finish_time',
|
||||
@@ -111,6 +115,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'testproject CI latest build ID',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -134,6 +139,7 @@
|
||||
'original_name': 'CI latest build ID',
|
||||
'platform': 'azure_devops',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'build_id',
|
||||
'unique_id': 'testorg_1234_9876_build_id',
|
||||
@@ -158,6 +164,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'testproject CI latest build queue time',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -181,6 +188,7 @@
|
||||
'original_name': 'CI latest build queue time',
|
||||
'platform': 'azure_devops',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'queue_time',
|
||||
'unique_id': 'testorg_1234_9876_queue_time',
|
||||
@@ -206,6 +214,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'testproject CI latest build reason',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -229,6 +238,7 @@
|
||||
'original_name': 'CI latest build reason',
|
||||
'platform': 'azure_devops',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'reason',
|
||||
'unique_id': 'testorg_1234_9876_reason',
|
||||
@@ -253,6 +263,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'testproject CI latest build result',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -276,6 +287,7 @@
|
||||
'original_name': 'CI latest build result',
|
||||
'platform': 'azure_devops',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'result',
|
||||
'unique_id': 'testorg_1234_9876_result',
|
||||
@@ -300,6 +312,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'testproject CI latest build source branch',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -323,6 +336,7 @@
|
||||
'original_name': 'CI latest build source branch',
|
||||
'platform': 'azure_devops',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'source_branch',
|
||||
'unique_id': 'testorg_1234_9876_source_branch',
|
||||
@@ -347,6 +361,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'testproject CI latest build source version',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -370,6 +385,7 @@
|
||||
'original_name': 'CI latest build source version',
|
||||
'platform': 'azure_devops',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'source_version',
|
||||
'unique_id': 'testorg_1234_9876_source_version',
|
||||
@@ -394,6 +410,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'testproject CI latest build start time',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -417,6 +434,7 @@
|
||||
'original_name': 'CI latest build start time',
|
||||
'platform': 'azure_devops',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'start_time',
|
||||
'unique_id': 'testorg_1234_9876_start_time',
|
||||
@@ -442,6 +460,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'testproject CI latest build URL',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -465,6 +484,7 @@
|
||||
'original_name': 'CI latest build URL',
|
||||
'platform': 'azure_devops',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'url',
|
||||
'unique_id': 'testorg_1234_9876_url',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Backup Backup Manager state',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'idle',
|
||||
@@ -35,6 +36,7 @@
|
||||
'original_name': 'Backup Manager state',
|
||||
'platform': 'backup',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'backup_manager_state',
|
||||
'unique_id': 'backup_manager_state',
|
||||
@@ -67,6 +69,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Backup Last attempted automatic backup',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -90,6 +93,7 @@
|
||||
'original_name': 'Last attempted automatic backup',
|
||||
'platform': 'backup',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'last_attempted_automatic_backup',
|
||||
'unique_id': 'last_attempted_automatic_backup',
|
||||
@@ -115,6 +119,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Backup Last successful automatic backup',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -138,6 +143,7 @@
|
||||
'original_name': 'Last successful automatic backup',
|
||||
'platform': 'backup',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'last_successful_automatic_backup',
|
||||
'unique_id': 'last_successful_automatic_backup',
|
||||
@@ -163,6 +169,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Backup Next scheduled automatic backup',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -186,6 +193,7 @@
|
||||
'original_name': 'Next scheduled automatic backup',
|
||||
'platform': 'backup',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'next_scheduled_automatic_backup',
|
||||
'unique_id': 'next_scheduled_automatic_backup',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'FakeSpa Circulation pump',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': 'Circulation pump',
|
||||
'platform': 'balboa',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'circ_pump',
|
||||
'unique_id': 'FakeSpa-Circ Pump-c0ffee',
|
||||
@@ -52,6 +54,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'FakeSpa Filter cycle 1',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -75,6 +78,7 @@
|
||||
'original_name': 'Filter cycle 1',
|
||||
'platform': 'balboa',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'filter_1',
|
||||
'unique_id': 'FakeSpa-Filter1-c0ffee',
|
||||
@@ -100,6 +104,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'FakeSpa Filter cycle 2',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -123,6 +128,7 @@
|
||||
'original_name': 'Filter cycle 2',
|
||||
'platform': 'balboa',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'filter_2',
|
||||
'unique_id': 'FakeSpa-Filter2-c0ffee',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'FakeSpa',
|
||||
'capabilities': dict({
|
||||
'hvac_modes': list([
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
@@ -38,6 +39,7 @@
|
||||
'original_name': None,
|
||||
'platform': 'balboa',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': <ClimateEntityFeature: 401>,
|
||||
'translation_key': 'balboa',
|
||||
'unique_id': 'FakeSpa-Climate-c0ffee',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'FakeSpa Fault',
|
||||
'capabilities': dict({
|
||||
'event_types': list([
|
||||
'clock_failed',
|
||||
@@ -48,6 +49,7 @@
|
||||
'original_name': 'Fault',
|
||||
'platform': 'balboa',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'fault',
|
||||
'unique_id': 'FakeSpa-fault-c0ffee',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'FakeSpa Pump 1',
|
||||
'capabilities': dict({
|
||||
'preset_modes': None,
|
||||
}),
|
||||
@@ -29,6 +30,7 @@
|
||||
'original_name': 'Pump 1',
|
||||
'platform': 'balboa',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': <FanEntityFeature: 49>,
|
||||
'translation_key': 'pump',
|
||||
'unique_id': 'FakeSpa-Pump 1-c0ffee',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'FakeSpa Light',
|
||||
'capabilities': dict({
|
||||
'supported_color_modes': list([
|
||||
<ColorMode.ONOFF: 'onoff'>,
|
||||
@@ -31,6 +32,7 @@
|
||||
'original_name': 'Light',
|
||||
'platform': 'balboa',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'only_light',
|
||||
'unique_id': 'FakeSpa-Light-c0ffee',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'FakeSpa Temperature range',
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'low',
|
||||
@@ -32,6 +33,7 @@
|
||||
'original_name': 'Temperature range',
|
||||
'platform': 'balboa',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'temperature_range',
|
||||
'unique_id': 'FakeSpa-TempHiLow-c0ffee',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'FakeSpa Filter cycle 2 enabled',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': 'Filter cycle 2 enabled',
|
||||
'platform': 'balboa',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'filter_cycle_2_enabled',
|
||||
'unique_id': 'FakeSpa-filter_cycle_2_enabled-c0ffee',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'FakeSpa Filter cycle 1 end',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': 'Filter cycle 1 end',
|
||||
'platform': 'balboa',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'filter_cycle_end',
|
||||
'unique_id': 'FakeSpa-filter_cycle_1_end-c0ffee',
|
||||
@@ -51,6 +53,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'FakeSpa Filter cycle 1 start',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -74,6 +77,7 @@
|
||||
'original_name': 'Filter cycle 1 start',
|
||||
'platform': 'balboa',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'filter_cycle_start',
|
||||
'unique_id': 'FakeSpa-filter_cycle_1_start-c0ffee',
|
||||
@@ -98,6 +102,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'FakeSpa Filter cycle 2 end',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -121,6 +126,7 @@
|
||||
'original_name': 'Filter cycle 2 end',
|
||||
'platform': 'balboa',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'filter_cycle_end',
|
||||
'unique_id': 'FakeSpa-filter_cycle_2_end-c0ffee',
|
||||
@@ -145,6 +151,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'FakeSpa Filter cycle 2 start',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -168,6 +175,7 @@
|
||||
'original_name': 'Filter cycle 2 start',
|
||||
'platform': 'balboa',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'filter_cycle_start',
|
||||
'unique_id': 'FakeSpa-filter_cycle_2_start-c0ffee',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Tempo Disc THD EEFF Battery',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -29,6 +30,7 @@
|
||||
'original_name': 'Battery',
|
||||
'platform': 'bluemaestro',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'aa:bb:cc:dd:ee:ff-battery',
|
||||
@@ -56,6 +58,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Tempo Disc THD EEFF Dew point',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -81,6 +84,7 @@
|
||||
'original_name': 'Dew point',
|
||||
'platform': 'bluemaestro',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'dew_point',
|
||||
'unique_id': 'aa:bb:cc:dd:ee:ff-dew_point',
|
||||
@@ -108,6 +112,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Tempo Disc THD EEFF Humidity',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -133,6 +138,7 @@
|
||||
'original_name': 'Humidity',
|
||||
'platform': 'bluemaestro',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'aa:bb:cc:dd:ee:ff-humidity',
|
||||
@@ -160,6 +166,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Tempo Disc THD EEFF Signal strength',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -185,6 +192,7 @@
|
||||
'original_name': 'Signal strength',
|
||||
'platform': 'bluemaestro',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'aa:bb:cc:dd:ee:ff-signal_strength',
|
||||
@@ -212,6 +220,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'Tempo Disc THD EEFF Temperature',
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
@@ -237,6 +246,7 @@
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'bluemaestro',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'aa:bb:cc:dd:ee:ff-temperature',
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'i3 (+ REX) Charging status',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -27,6 +28,7 @@
|
||||
'original_name': 'Charging status',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'charging_status',
|
||||
'unique_id': 'WBY00000000REXI01-charging_status',
|
||||
@@ -52,6 +54,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'i3 (+ REX) Check control messages',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -75,6 +78,7 @@
|
||||
'original_name': 'Check control messages',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'check_control_messages',
|
||||
'unique_id': 'WBY00000000REXI01-check_control_messages',
|
||||
@@ -100,6 +104,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'i3 (+ REX) Condition-based services',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -123,6 +128,7 @@
|
||||
'original_name': 'Condition-based services',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'condition_based_services',
|
||||
'unique_id': 'WBY00000000REXI01-condition_based_services',
|
||||
@@ -154,6 +160,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'i3 (+ REX) Connection status',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -177,6 +184,7 @@
|
||||
'original_name': 'Connection status',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'connection_status',
|
||||
'unique_id': 'WBY00000000REXI01-connection_status',
|
||||
@@ -202,6 +210,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'i3 (+ REX) Door lock state',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -225,6 +234,7 @@
|
||||
'original_name': 'Door lock state',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'door_lock_state',
|
||||
'unique_id': 'WBY00000000REXI01-door_lock_state',
|
||||
@@ -251,6 +261,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'i3 (+ REX) Lids',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -274,6 +285,7 @@
|
||||
'original_name': 'Lids',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'lids',
|
||||
'unique_id': 'WBY00000000REXI01-lids',
|
||||
@@ -306,6 +318,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'i3 (+ REX) Pre-entry climatization',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -329,6 +342,7 @@
|
||||
'original_name': 'Pre-entry climatization',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'is_pre_entry_climatization_enabled',
|
||||
'unique_id': 'WBY00000000REXI01-is_pre_entry_climatization_enabled',
|
||||
@@ -353,6 +367,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'i3 (+ REX) Windows',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -376,6 +391,7 @@
|
||||
'original_name': 'Windows',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'windows',
|
||||
'unique_id': 'WBY00000000REXI01-windows',
|
||||
@@ -403,6 +419,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'i4 eDrive40 Charging status',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -426,6 +443,7 @@
|
||||
'original_name': 'Charging status',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'charging_status',
|
||||
'unique_id': 'WBA00000000DEMO02-charging_status',
|
||||
@@ -451,6 +469,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'i4 eDrive40 Check control messages',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -474,6 +493,7 @@
|
||||
'original_name': 'Check control messages',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'check_control_messages',
|
||||
'unique_id': 'WBA00000000DEMO02-check_control_messages',
|
||||
@@ -500,6 +520,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'i4 eDrive40 Condition-based services',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -523,6 +544,7 @@
|
||||
'original_name': 'Condition-based services',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'condition_based_services',
|
||||
'unique_id': 'WBA00000000DEMO02-condition_based_services',
|
||||
@@ -559,6 +581,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'i4 eDrive40 Connection status',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -582,6 +605,7 @@
|
||||
'original_name': 'Connection status',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'connection_status',
|
||||
'unique_id': 'WBA00000000DEMO02-connection_status',
|
||||
@@ -607,6 +631,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'i4 eDrive40 Door lock state',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -630,6 +655,7 @@
|
||||
'original_name': 'Door lock state',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'door_lock_state',
|
||||
'unique_id': 'WBA00000000DEMO02-door_lock_state',
|
||||
@@ -656,6 +682,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'i4 eDrive40 Lids',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -679,6 +706,7 @@
|
||||
'original_name': 'Lids',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'lids',
|
||||
'unique_id': 'WBA00000000DEMO02-lids',
|
||||
@@ -710,6 +738,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'i4 eDrive40 Pre-entry climatization',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -733,6 +762,7 @@
|
||||
'original_name': 'Pre-entry climatization',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'is_pre_entry_climatization_enabled',
|
||||
'unique_id': 'WBA00000000DEMO02-is_pre_entry_climatization_enabled',
|
||||
@@ -757,6 +787,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'i4 eDrive40 Windows',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -780,6 +811,7 @@
|
||||
'original_name': 'Windows',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'windows',
|
||||
'unique_id': 'WBA00000000DEMO02-windows',
|
||||
@@ -810,6 +842,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'iX xDrive50 Charging status',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -833,6 +866,7 @@
|
||||
'original_name': 'Charging status',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'charging_status',
|
||||
'unique_id': 'WBA00000000DEMO01-charging_status',
|
||||
@@ -858,6 +892,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'iX xDrive50 Check control messages',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -881,6 +916,7 @@
|
||||
'original_name': 'Check control messages',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'check_control_messages',
|
||||
'unique_id': 'WBA00000000DEMO01-check_control_messages',
|
||||
@@ -907,6 +943,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'iX xDrive50 Condition-based services',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -930,6 +967,7 @@
|
||||
'original_name': 'Condition-based services',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'condition_based_services',
|
||||
'unique_id': 'WBA00000000DEMO01-condition_based_services',
|
||||
@@ -966,6 +1004,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'iX xDrive50 Connection status',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -989,6 +1028,7 @@
|
||||
'original_name': 'Connection status',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'connection_status',
|
||||
'unique_id': 'WBA00000000DEMO01-connection_status',
|
||||
@@ -1014,6 +1054,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'iX xDrive50 Door lock state',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -1037,6 +1078,7 @@
|
||||
'original_name': 'Door lock state',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'door_lock_state',
|
||||
'unique_id': 'WBA00000000DEMO01-door_lock_state',
|
||||
@@ -1063,6 +1105,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'iX xDrive50 Lids',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -1086,6 +1129,7 @@
|
||||
'original_name': 'Lids',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'lids',
|
||||
'unique_id': 'WBA00000000DEMO01-lids',
|
||||
@@ -1118,6 +1162,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'iX xDrive50 Pre-entry climatization',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -1141,6 +1186,7 @@
|
||||
'original_name': 'Pre-entry climatization',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'is_pre_entry_climatization_enabled',
|
||||
'unique_id': 'WBA00000000DEMO01-is_pre_entry_climatization_enabled',
|
||||
@@ -1165,6 +1211,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'iX xDrive50 Windows',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -1188,6 +1235,7 @@
|
||||
'original_name': 'Windows',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'windows',
|
||||
'unique_id': 'WBA00000000DEMO01-windows',
|
||||
@@ -1218,6 +1266,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'M340i xDrive Check control messages',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -1241,6 +1290,7 @@
|
||||
'original_name': 'Check control messages',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'check_control_messages',
|
||||
'unique_id': 'WBA00000000DEMO03-check_control_messages',
|
||||
@@ -1268,6 +1318,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'M340i xDrive Condition-based services',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -1291,6 +1342,7 @@
|
||||
'original_name': 'Condition-based services',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'condition_based_services',
|
||||
'unique_id': 'WBA00000000DEMO03-condition_based_services',
|
||||
@@ -1330,6 +1382,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'M340i xDrive Door lock state',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -1353,6 +1406,7 @@
|
||||
'original_name': 'Door lock state',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'door_lock_state',
|
||||
'unique_id': 'WBA00000000DEMO03-door_lock_state',
|
||||
@@ -1379,6 +1433,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'M340i xDrive Lids',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -1402,6 +1457,7 @@
|
||||
'original_name': 'Lids',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'lids',
|
||||
'unique_id': 'WBA00000000DEMO03-lids',
|
||||
@@ -1433,6 +1489,7 @@
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'calculated_object_id': 'M340i xDrive Windows',
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
@@ -1456,6 +1513,7 @@
|
||||
'original_name': 'Windows',
|
||||
'platform': 'bmw_connected_drive',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'windows',
|
||||
'unique_id': 'WBA00000000DEMO03-windows',
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user