mirror of
https://github.com/home-assistant/core.git
synced 2026-08-24 10:13:52 -05:00
Fix line length violations in components c-e (#170540)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: frenck <195327+frenck@users.noreply.github.com>
This commit is contained in:
co-authored by
copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
frenck
parent
2ec51ef113
commit
bb964ccd95
@@ -102,7 +102,8 @@ class CalDavUpdateCoordinator(DataUpdateCoordinator[CalendarEvent | None]):
|
||||
)
|
||||
|
||||
# Create new events for each recurrence of an event that happens today.
|
||||
# For recurring events, some servers return the original event with recurrence rules
|
||||
# For recurring events, some servers return the original
|
||||
# event with recurrence rules
|
||||
# and they would not be properly parsed using their original start/end dates.
|
||||
new_events = []
|
||||
for event in results:
|
||||
|
||||
@@ -150,7 +150,8 @@ def _has_min_duration(
|
||||
duration = end - start
|
||||
if duration < min_duration:
|
||||
raise vol.Invalid(
|
||||
f"Expected minimum event duration of {min_duration} ({start}, {end})"
|
||||
"Expected minimum event duration"
|
||||
f" of {min_duration} ({start}, {end})"
|
||||
)
|
||||
return obj
|
||||
|
||||
@@ -1056,11 +1057,14 @@ async def handle_calendar_event_subscribe(
|
||||
def _validate_timespan(
|
||||
values: dict[str, Any],
|
||||
) -> tuple[datetime.datetime | datetime.date, datetime.datetime | datetime.date]:
|
||||
"""Parse a create event service call and convert the args ofr a create event entity call.
|
||||
"""Parse a create event service call.
|
||||
|
||||
This converts the input service arguments into a `start` and `end` date or date time. This
|
||||
exists because service calls use `start_date` and `start_date_time` whereas the
|
||||
normal entity methods can take either a `datetime` or `date` as a single `start` argument.
|
||||
Convert the args for a create event entity call.
|
||||
This converts the input service arguments into a
|
||||
`start` and `end` date or date time. This exists because
|
||||
service calls use `start_date` and `start_date_time`
|
||||
whereas the normal entity methods can take either a
|
||||
`datetime` or `date` as a single `start` argument.
|
||||
It also handles the other service call variations like "in days" as well.
|
||||
"""
|
||||
|
||||
|
||||
@@ -327,7 +327,7 @@ class TargetCalendarEventListener(TargetEntityChangeTracker):
|
||||
|
||||
@callback
|
||||
def _handle_entities_update(self, tracked_entities: set[str]) -> None:
|
||||
"""Restart the listeners when the list of entities of the tracked targets is updated."""
|
||||
"""Restart listeners when tracked target entities update."""
|
||||
if self._pending_listener_task:
|
||||
self._pending_listener_task.cancel()
|
||||
self._pending_listener_task = self._hass.async_create_task(
|
||||
|
||||
@@ -545,10 +545,13 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
) -> None:
|
||||
"""Handle the async WebRTC offer.
|
||||
|
||||
Async means that it could take some time to process the offer and responses/message
|
||||
will be sent with the send_message callback.
|
||||
This method is used by cameras with CameraEntityFeature.STREAM.
|
||||
An integration overriding this method must also implement async_on_webrtc_candidate.
|
||||
Async means that it could take some time to process
|
||||
the offer and responses/message will be sent with the
|
||||
send_message callback.
|
||||
This method is used by cameras with
|
||||
CameraEntityFeature.STREAM.
|
||||
An integration overriding this method must also
|
||||
implement async_on_webrtc_candidate.
|
||||
|
||||
Integrations can override with a native WebRTC implementation.
|
||||
"""
|
||||
@@ -707,7 +710,10 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
@final
|
||||
@callback
|
||||
def async_get_webrtc_client_configuration(self) -> WebRTCClientConfiguration:
|
||||
"""Return the WebRTC client configuration and extend it with the registered ice servers."""
|
||||
"""Return the WebRTC client configuration.
|
||||
|
||||
Extend it with the registered ice servers.
|
||||
"""
|
||||
config = self._async_get_webrtc_client_configuration()
|
||||
|
||||
ice_servers = async_get_ice_servers(self.hass)
|
||||
@@ -999,7 +1005,9 @@ async def async_handle_snapshot_service(
|
||||
# check if we allow to access to that file
|
||||
if not hass.config.is_allowed_path(snapshot_file):
|
||||
raise HomeAssistantError(
|
||||
f"Cannot write `{snapshot_file}`, no access to path; `allowlist_external_dirs` may need to be adjusted in `configuration.yaml`"
|
||||
f"Cannot write `{snapshot_file}`, no access to path;"
|
||||
" `allowlist_external_dirs` may need to be adjusted"
|
||||
" in `configuration.yaml`"
|
||||
)
|
||||
|
||||
try:
|
||||
|
||||
@@ -91,7 +91,8 @@ class TurboJPEGSingleton:
|
||||
TurboJPEGSingleton.__instance = TurboJPEG()
|
||||
except Exception:
|
||||
_LOGGER.exception(
|
||||
"Error loading libturbojpeg; Camera snapshot performance will be sub-optimal"
|
||||
"Error loading libturbojpeg;"
|
||||
" Camera snapshot performance will be sub-optimal"
|
||||
)
|
||||
TurboJPEGSingleton.__instance = False
|
||||
|
||||
|
||||
@@ -203,7 +203,8 @@ class CastDevice:
|
||||
self.hass, SIGNAL_CAST_REMOVED, self._async_cast_removed
|
||||
)
|
||||
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, self._async_stop)
|
||||
# async_create_background_task is used to avoid delaying startup wrapup if the device
|
||||
# async_create_background_task is used to avoid delaying
|
||||
# startup wrapup if the device
|
||||
# is discovered already during startup but then fails to respond
|
||||
self.hass.async_create_background_task(
|
||||
async_create_catching_coro(self._async_connect_to_chromecast()),
|
||||
|
||||
@@ -21,8 +21,10 @@ from .const import DOMAIN
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
COORDINATOR_NAME = f"{DOMAIN} Coordinator"
|
||||
# Maximum update frequency is every 6 hours. The API will return 429 Too Many Requests if polled frequently.
|
||||
# The device updates its data every 8-12 hours, so there's no need to poll more frequently.
|
||||
# Maximum update frequency is every 6 hours. The API will
|
||||
# return 429 Too Many Requests if polled frequently.
|
||||
# The device updates its data every 8-12 hours, so there's
|
||||
# no need to poll more frequently.
|
||||
UPDATE_INTERVAL = timedelta(hours=6)
|
||||
|
||||
type CentriConnectConfigEntry = ConfigEntry[CentriConnectCoordinator]
|
||||
|
||||
@@ -50,7 +50,7 @@ class ChaconDioCover(ChaconDioEntity, CoverEntity):
|
||||
)
|
||||
|
||||
def _update_attr(self, data: dict[str, Any]) -> None:
|
||||
"""Recomputes the attributes values either at init or when the device state changes."""
|
||||
"""Recompute the attribute values on init or state change."""
|
||||
self._attr_available = data["connected"]
|
||||
self._attr_current_cover_position = data["openlevel"]
|
||||
self._attr_is_closing = data["movement"] == ShutterMoveEnum.DOWN.value
|
||||
@@ -60,7 +60,8 @@ class ChaconDioCover(ChaconDioEntity, CoverEntity):
|
||||
async def async_close_cover(self, **kwargs: Any) -> None:
|
||||
"""Close the cover.
|
||||
|
||||
Closed status is effective after the server callback that triggers callback_device_state.
|
||||
Closed status is effective after the server callback
|
||||
that triggers callback_device_state.
|
||||
"""
|
||||
|
||||
_LOGGER.debug(
|
||||
@@ -82,7 +83,8 @@ class ChaconDioCover(ChaconDioEntity, CoverEntity):
|
||||
async def async_open_cover(self, **kwargs: Any) -> None:
|
||||
"""Open the cover.
|
||||
|
||||
Opened status is effective after the server callback that triggers callback_device_state.
|
||||
Opened status is effective after the server callback
|
||||
that triggers callback_device_state.
|
||||
"""
|
||||
|
||||
_LOGGER.debug(
|
||||
@@ -113,7 +115,8 @@ class ChaconDioCover(ChaconDioEntity, CoverEntity):
|
||||
async def async_set_cover_position(self, **kwargs: Any) -> None:
|
||||
"""Set the cover open position in percentage.
|
||||
|
||||
Closing or opening status is effective after the server callback that triggers callback_device_state.
|
||||
Closing or opening status is effective after the server
|
||||
callback that triggers callback_device_state.
|
||||
"""
|
||||
position: int = kwargs[ATTR_POSITION]
|
||||
|
||||
|
||||
@@ -39,14 +39,15 @@ class ChaconDioSwitch(ChaconDioEntity, SwitchEntity):
|
||||
_attr_name = None
|
||||
|
||||
def _update_attr(self, data: dict[str, Any]) -> None:
|
||||
"""Recomputes the attributes values either at init or when the device state changes."""
|
||||
"""Recompute the attribute values on init or state change."""
|
||||
self._attr_available = data["connected"]
|
||||
self._attr_is_on = data["is_on"]
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn on the switch.
|
||||
|
||||
Turned on status is effective after the server callback that triggers callback_device_state.
|
||||
Turned on status is effective after the server callback
|
||||
that triggers callback_device_state.
|
||||
"""
|
||||
|
||||
_LOGGER.debug(
|
||||
@@ -61,7 +62,8 @@ class ChaconDioSwitch(ChaconDioEntity, SwitchEntity):
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn off the switch.
|
||||
|
||||
Turned on status is effective after the server callback that triggers callback_device_state.
|
||||
Turned on status is effective after the server callback
|
||||
that triggers callback_device_state.
|
||||
"""
|
||||
|
||||
_LOGGER.debug(
|
||||
|
||||
@@ -111,7 +111,8 @@ class CieloClimate(CieloDeviceEntity, ClimateEntity):
|
||||
def temperature_unit(self) -> str:
|
||||
"""Return the unit of temperature in Home Assistant format.
|
||||
|
||||
It can change over time based on the device settings, so we fetch it dynamically from the client.
|
||||
It can change over time based on the device settings,
|
||||
so we fetch it dynamically from the client.
|
||||
"""
|
||||
unit = self.client.temperature_unit()
|
||||
|
||||
|
||||
@@ -51,7 +51,9 @@ class CieloDataUpdateCoordinator(DataUpdateCoordinator[CieloData]):
|
||||
name=DOMAIN,
|
||||
config_entry=entry,
|
||||
update_interval=timedelta(seconds=DEFAULT_SCAN_INTERVAL),
|
||||
# The debouncer prevents multiple rapid refresh requests from triggering repeated full data fetches from the backend.
|
||||
# The debouncer prevents multiple rapid refresh
|
||||
# requests from triggering repeated full data
|
||||
# fetches from the backend.
|
||||
request_refresh_debouncer=Debouncer(
|
||||
hass, LOGGER, cooldown=REQUEST_REFRESH_DELAY, immediate=False
|
||||
),
|
||||
|
||||
@@ -120,7 +120,9 @@ TRIGGERS: dict[str, type[Trigger]] = {
|
||||
"target_humidity_changed": ClimateTargetHumidityChangedTrigger,
|
||||
"target_humidity_crossed_threshold": ClimateTargetHumidityCrossedThresholdTrigger,
|
||||
"target_temperature_changed": ClimateTargetTemperatureChangedTrigger,
|
||||
"target_temperature_crossed_threshold": ClimateTargetTemperatureCrossedThresholdTrigger,
|
||||
"target_temperature_crossed_threshold": (
|
||||
ClimateTargetTemperatureCrossedThresholdTrigger
|
||||
),
|
||||
"turned_off": make_entity_target_state_trigger(DOMAIN, HVACMode.OFF),
|
||||
"turned_on": make_entity_transition_trigger(
|
||||
DOMAIN,
|
||||
|
||||
@@ -253,7 +253,10 @@ def async_listen_cloudhook_change(
|
||||
webhook_id: str,
|
||||
on_change: Callable[[dict[str, Any] | None], None],
|
||||
) -> Callable[[], None]:
|
||||
"""Listen for cloudhook changes for the given webhook and notify when modified or deleted."""
|
||||
"""Listen for cloudhook changes for the given webhook.
|
||||
|
||||
Notify when modified or deleted.
|
||||
"""
|
||||
|
||||
@callback
|
||||
def _handle_cloudhooks_updated(cloudhooks: dict[str, Any]) -> None:
|
||||
|
||||
@@ -128,8 +128,10 @@ class CloudOAuth2Implementation(config_entry_oauth2_flow.AbstractOAuth2Implement
|
||||
flow_id=flow_id, user_input=tokens
|
||||
)
|
||||
|
||||
# It's a background task because it should be cancelled on shutdown and there's nothing else
|
||||
# we can do in such case. There's also no need to wait for this during setup.
|
||||
# It's a background task because it should be cancelled
|
||||
# on shutdown and there's nothing else we can do in
|
||||
# such case. There's also no need to wait for this
|
||||
# during setup.
|
||||
self.hass.async_create_background_task(
|
||||
await_tokens(), name="Awaiting OAuth tokens"
|
||||
)
|
||||
|
||||
@@ -230,7 +230,8 @@ class CloudAlexaConfig(alexa_config.AbstractConfig):
|
||||
ALEXA_SETTINGS_VERSION,
|
||||
)
|
||||
if self._prefs.alexa_settings_version < 2 or (
|
||||
# Recover from a bug we had in 2023.5.0 where entities didn't get exposed
|
||||
# Recover from a bug we had in 2023.5.0
|
||||
# where entities didn't get exposed
|
||||
self._prefs.alexa_settings_version < 3
|
||||
and not any(
|
||||
settings.get("should_expose", False)
|
||||
|
||||
@@ -372,7 +372,11 @@ class CloudClient(Interface):
|
||||
method=payload["method"],
|
||||
query_string=payload["query"],
|
||||
mock_source=DOMAIN,
|
||||
remote=None, # Remote will be used for the local_only check, but since this is from the cloud we want it to be None to mark it as non-local and bypass the ip parsing and remote checks
|
||||
# Remote will be used for the local_only check, but
|
||||
# since this is from the cloud we want it to be None
|
||||
# to mark it as non-local and bypass the ip parsing
|
||||
# and remote checks
|
||||
remote=None,
|
||||
)
|
||||
|
||||
response = await webhook.async_handle_webhook(
|
||||
|
||||
@@ -596,13 +596,15 @@ class BaseCloudLLMEntity(Entity):
|
||||
_convert_content_to_param(
|
||||
[
|
||||
content
|
||||
async for content in chat_log.async_add_delta_content_stream(
|
||||
self.entity_id,
|
||||
_transform_stream(
|
||||
chat_log,
|
||||
raw_stream,
|
||||
True,
|
||||
),
|
||||
async for content in (
|
||||
chat_log.async_add_delta_content_stream(
|
||||
self.entity_id,
|
||||
_transform_stream(
|
||||
chat_log,
|
||||
raw_stream,
|
||||
True,
|
||||
),
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
@@ -171,7 +171,7 @@ class CloudGoogleConfig(AbstractConfig):
|
||||
return self.enabled and self._prefs.google_report_state
|
||||
|
||||
def get_local_webhook_id(self, agent_user_id: Any) -> str:
|
||||
"""Return the webhook ID to be used for actions for a given agent user id via the local SDK."""
|
||||
"""Return the webhook ID for actions for an agent user id via the local SDK."""
|
||||
return self._prefs.google_local_webhook_id
|
||||
|
||||
def get_local_user_id(self, webhook_id: Any) -> str:
|
||||
@@ -226,7 +226,8 @@ class CloudGoogleConfig(AbstractConfig):
|
||||
GOOGLE_SETTINGS_VERSION,
|
||||
)
|
||||
if self._prefs.google_settings_version < 2 or (
|
||||
# Recover from a bug we had in 2023.5.0 where entities didn't get exposed
|
||||
# Recover from a bug we had in 2023.5.0
|
||||
# where entities didn't get exposed
|
||||
self._prefs.google_settings_version < 3
|
||||
and not any(
|
||||
settings.get("should_expose", False)
|
||||
|
||||
@@ -138,7 +138,8 @@ def async_setup(hass: HomeAssistant) -> None:
|
||||
),
|
||||
MFAExpiredOrNotStarted: (
|
||||
HTTPStatus.BAD_REQUEST,
|
||||
"Multi-factor authentication expired, or not started. Please try again.",
|
||||
"Multi-factor authentication expired,"
|
||||
" or not started. Please try again.",
|
||||
),
|
||||
AlreadyConnectedError: (
|
||||
HTTPStatus.CONFLICT,
|
||||
@@ -561,7 +562,12 @@ class DownloadSupportPackageView(HomeAssistantView):
|
||||
markdown += "--- | --- | --- | ---\n"
|
||||
for integration in integration_info["custom_integrations"]:
|
||||
doc_url = integration.get("documentation") or "N/A"
|
||||
markdown += f"{integration['domain']} | {integration['name']} | {integration['version']} | {doc_url}\n"
|
||||
markdown += (
|
||||
f"{integration['domain']} | "
|
||||
f"{integration['name']} | "
|
||||
f"{integration['version']} | "
|
||||
f"{doc_url}\n"
|
||||
)
|
||||
markdown += "\n</details>\n\n"
|
||||
|
||||
for domain, domain_info in domains_info.items():
|
||||
|
||||
@@ -284,7 +284,8 @@ class CloudPreferences:
|
||||
def alexa_default_expose(self) -> list[str] | None:
|
||||
"""Return array of entity domains that are exposed by default to Alexa.
|
||||
|
||||
Can return None, in which case for backwards should be interpreted as allow all domains.
|
||||
Can return None, in which case for backwards
|
||||
should be interpreted as allow all domains.
|
||||
"""
|
||||
return self._prefs.get(PREF_ALEXA_DEFAULT_EXPOSE)
|
||||
|
||||
@@ -342,7 +343,8 @@ class CloudPreferences:
|
||||
def google_default_expose(self) -> list[str] | None:
|
||||
"""Return array of entity domains that are exposed by default to Google.
|
||||
|
||||
Can return None, in which case for backwards should be interpreted as allow all domains.
|
||||
Can return None, in which case for backwards
|
||||
should be interpreted as allow all domains.
|
||||
"""
|
||||
return self._prefs.get(PREF_GOOGLE_DEFAULT_EXPOSE)
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ async def async_subscription_info(cloud: Cloud[CloudClient]) -> SubscriptionInfo
|
||||
_LOGGER.error("Failed to fetch subscription information - %s", exception)
|
||||
except TimeoutError:
|
||||
_LOGGER.error(
|
||||
"A timeout of %s was reached while trying to fetch subscription information",
|
||||
"A timeout of %s was reached while trying to"
|
||||
" fetch subscription information",
|
||||
REQUEST_TIMEOUT,
|
||||
)
|
||||
return None
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Contains the Coordinator for updating the IP addresses of your Cloudflare DNS records."""
|
||||
"""Coordinator for updating IP addresses of Cloudflare DNS records."""
|
||||
|
||||
import asyncio
|
||||
from datetime import timedelta
|
||||
|
||||
@@ -240,8 +240,10 @@ class R2BackupAgent(BackupAgent):
|
||||
finally:
|
||||
view.release()
|
||||
|
||||
# Compact the buffer if the consumed offset has grown large enough. This
|
||||
# avoids unnecessary memory copies when compacting after every part upload.
|
||||
# Compact the buffer if the consumed offset
|
||||
# has grown large enough. This avoids
|
||||
# unnecessary memory copies when compacting
|
||||
# after every part upload.
|
||||
if offset and offset >= MULTIPART_MIN_PART_SIZE_BYTES:
|
||||
buffer = bytearray(buffer[offset:])
|
||||
offset = 0
|
||||
|
||||
@@ -63,7 +63,8 @@ def create_and_update_instance(entry: CoinbaseConfigEntry) -> CoinbaseData:
|
||||
raise ConfigEntryAuthFailed(
|
||||
"Your Coinbase API key appears to be for the deprecated v2 API. "
|
||||
"Please reconfigure with a new API key created for the v3 API. "
|
||||
"Visit https://www.coinbase.com/developer-platform to create new credentials."
|
||||
"Visit https://www.coinbase.com/developer-platform"
|
||||
" to create new credentials."
|
||||
)
|
||||
|
||||
client = RESTClient(
|
||||
|
||||
@@ -300,4 +300,4 @@ class CurrencyUnavailable(HomeAssistantError):
|
||||
|
||||
|
||||
class ExchangeRateUnavailable(HomeAssistantError):
|
||||
"""Error to indicate the requested exchange rate resource is not provided by the API."""
|
||||
"""Error to indicate the requested exchange rate is not provided by the API."""
|
||||
|
||||
@@ -157,7 +157,9 @@ class AccountSensor(SensorEntity):
|
||||
def extra_state_attributes(self) -> dict[str, str]:
|
||||
"""Return the state attributes of the sensor."""
|
||||
return {
|
||||
ATTR_NATIVE_BALANCE: f"{self._native_balance} {self._coinbase_data.exchange_base}",
|
||||
ATTR_NATIVE_BALANCE: (
|
||||
f"{self._native_balance} {self._coinbase_data.exchange_base}"
|
||||
),
|
||||
}
|
||||
|
||||
def update(self) -> None:
|
||||
|
||||
@@ -125,7 +125,8 @@ class CommandBinarySensor(ManualTriggerEntity, BinarySensorEntity):
|
||||
self._process_updates = asyncio.Lock()
|
||||
if self._process_updates.locked():
|
||||
LOGGER.warning(
|
||||
"Updating Command Line Binary Sensor %s took longer than the scheduled update interval %s",
|
||||
"Updating Command Line Binary Sensor %s took longer"
|
||||
" than the scheduled update interval %s",
|
||||
self.name,
|
||||
self._scan_interval,
|
||||
)
|
||||
|
||||
@@ -157,7 +157,8 @@ class CommandCover(ManualTriggerEntity, CoverEntity):
|
||||
self._process_updates = asyncio.Lock()
|
||||
if self._process_updates.locked():
|
||||
LOGGER.warning(
|
||||
"Updating Command Line Cover %s took longer than the scheduled update interval %s",
|
||||
"Updating Command Line Cover %s took longer than"
|
||||
" the scheduled update interval %s",
|
||||
self.name,
|
||||
self._scan_interval,
|
||||
)
|
||||
|
||||
@@ -134,7 +134,8 @@ class CommandSensor(ManualTriggerSensorEntity):
|
||||
|
||||
if self._process_updates.locked():
|
||||
LOGGER.warning(
|
||||
"Updating Command Line Sensor %s took longer than the scheduled update interval %s",
|
||||
"Updating Command Line Sensor %s took longer than"
|
||||
" the scheduled update interval %s",
|
||||
self.name,
|
||||
self._scan_interval,
|
||||
)
|
||||
|
||||
@@ -163,7 +163,8 @@ class CommandSwitch(ManualTriggerEntity, SwitchEntity):
|
||||
self._process_updates = asyncio.Lock()
|
||||
if self._process_updates.locked():
|
||||
LOGGER.warning(
|
||||
"Updating Command Line Switch %s took longer than the scheduled update interval %s",
|
||||
"Updating Command Line Switch %s took longer than"
|
||||
" the scheduled update interval %s",
|
||||
self.name,
|
||||
self._scan_interval,
|
||||
)
|
||||
|
||||
@@ -155,7 +155,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: Control4ConfigEntry) ->
|
||||
config[CONF_HOST],
|
||||
)
|
||||
raise ConfigEntryNotReady(
|
||||
f"Timeout getting UI configuration from Control4 controller at {config[CONF_HOST]}"
|
||||
"Timeout getting UI configuration from"
|
||||
f" Control4 controller at {config[CONF_HOST]}"
|
||||
) from err
|
||||
|
||||
ui_configuration = json.loads(ui_config_raw)
|
||||
|
||||
@@ -202,7 +202,8 @@ class Control4Climate(Control4Entity, ClimateEntity):
|
||||
def _create_api_object(self) -> C4Climate:
|
||||
"""Create a pyControl4 device object.
|
||||
|
||||
This exists so the director token used is always the latest one, without needing to re-init the entire entity.
|
||||
This exists so the director token used is always the
|
||||
latest one, without needing to re-init the entire entity.
|
||||
"""
|
||||
return C4Climate(self.runtime_data.director, self._idx)
|
||||
|
||||
|
||||
@@ -182,7 +182,8 @@ class Control4Light(Control4Entity, LightEntity):
|
||||
def _create_api_object(self):
|
||||
"""Create a pyControl4 device object.
|
||||
|
||||
This exists so the director token used is always the latest one, without needing to re-init the entire entity.
|
||||
This exists so the director token used is always the
|
||||
latest one, without needing to re-init the entire entity.
|
||||
"""
|
||||
return C4Light(self.runtime_data.director, self._idx)
|
||||
|
||||
|
||||
@@ -222,7 +222,8 @@ class Control4Room(Control4Entity, MediaPlayerEntity):
|
||||
def _create_api_object(self) -> C4Room:
|
||||
"""Create a pyControl4 device object.
|
||||
|
||||
This exists so the director token used is always the latest one, without needing to re-init the entire entity.
|
||||
This exists so the director token used is always the
|
||||
latest one, without needing to re-init the entire entity.
|
||||
"""
|
||||
return C4Room(self.runtime_data.director, self._idx)
|
||||
|
||||
|
||||
@@ -421,9 +421,11 @@ class ChatLog:
|
||||
) -> AsyncGenerator[ToolResultContent]:
|
||||
"""Add assistant content and execute tool calls.
|
||||
|
||||
tool_call_tasks can contains tasks for tool calls that are already in progress.
|
||||
tool_call_tasks can contain tasks for tool calls
|
||||
that are already in progress.
|
||||
|
||||
This method is an async generator and will yield the tool results as they come in.
|
||||
This method is an async generator and will yield
|
||||
the tool results as they come in.
|
||||
"""
|
||||
LOGGER.debug("Adding assistant content: %s", content)
|
||||
self.content.append(content)
|
||||
@@ -487,14 +489,17 @@ class ChatLog:
|
||||
) -> AsyncGenerator[AssistantContent | ToolResultContent]:
|
||||
"""Stream content into the chat log.
|
||||
|
||||
Returns a generator with all content that was added to the chat log.
|
||||
Returns a generator with all content that was added
|
||||
to the chat log.
|
||||
|
||||
stream iterates over dictionaries with optional keys role, content and tool_calls.
|
||||
stream iterates over dictionaries with optional keys
|
||||
role, content and tool_calls.
|
||||
|
||||
When a delta contains a role key, the current message is considered complete and
|
||||
a new message is started.
|
||||
When a delta contains a role key, the current message
|
||||
is considered complete and a new message is started.
|
||||
|
||||
The keys content and tool_calls will be concatenated if they appear multiple times.
|
||||
The keys content and tool_calls will be concatenated
|
||||
if they appear multiple times.
|
||||
"""
|
||||
current_content = ""
|
||||
current_thinking_content = ""
|
||||
@@ -730,7 +735,8 @@ class ChatLog:
|
||||
if llm_api:
|
||||
prompt_parts.append(llm_api.api_prompt)
|
||||
|
||||
# Append current date and time to the prompt if the corresponding tool is not provided
|
||||
# Append current date and time to the prompt if the
|
||||
# corresponding tool is not provided
|
||||
llm_tools: list[llm.Tool] = llm_api.tools if llm_api else []
|
||||
if not any(tool.name.endswith("GetDateTime") for tool in llm_tools):
|
||||
prompt_parts.append(
|
||||
|
||||
@@ -171,7 +171,7 @@ class IntentCache:
|
||||
return self.cache[key]
|
||||
|
||||
def put(self, key: IntentCacheKey, value: IntentCacheValue) -> None:
|
||||
"""Put a value in the cache, evicting the least recently used item if necessary."""
|
||||
"""Put a value in the cache, evicting the LRU item if necessary."""
|
||||
if key in self.cache:
|
||||
# Update value and mark as recently used
|
||||
self.cache.move_to_end(key)
|
||||
@@ -1072,7 +1072,8 @@ class DefaultAgent(ConversationEntity):
|
||||
dict,
|
||||
):
|
||||
_LOGGER.warning(
|
||||
"Custom sentences file does not match expected format path=%s",
|
||||
"Custom sentences file does not match"
|
||||
" expected format path=%s",
|
||||
custom_sentences_file.name,
|
||||
)
|
||||
continue
|
||||
@@ -1474,7 +1475,7 @@ def _make_error_result(
|
||||
|
||||
|
||||
def _get_unmatched_response(result: RecognizeResult) -> tuple[ErrorKey, dict[str, Any]]:
|
||||
"""Get key and template arguments for error when there are unmatched intent entities/slots."""
|
||||
"""Get key and template args for unmatched intent entities/slots error."""
|
||||
|
||||
# Filter out non-text and missing context entities
|
||||
unmatched_text: dict[str, str] = {
|
||||
|
||||
@@ -182,7 +182,7 @@ async def websocket_list_sentences(
|
||||
async def websocket_hass_agent_debug(
|
||||
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict
|
||||
) -> None:
|
||||
"""Return intents that would be matched by the default agent for a list of sentences."""
|
||||
"""Return intents matched by the default agent for a list of sentences."""
|
||||
agent = get_agent_manager(hass).default_agent
|
||||
assert agent is not None
|
||||
|
||||
|
||||
@@ -31,7 +31,8 @@ def async_get_result_from_chat_log(
|
||||
|
||||
if not isinstance((last_content := chat_log.content[-1]), AssistantContent):
|
||||
_LOGGER.error(
|
||||
"Last content in chat log is not an AssistantContent: %s. This could be due to the model not returning a valid response",
|
||||
"Last content in chat log is not an AssistantContent: %s."
|
||||
" This could be due to the model not returning a valid response",
|
||||
last_content,
|
||||
)
|
||||
raise HomeAssistantError("Unable to get response")
|
||||
|
||||
@@ -94,7 +94,8 @@ class CookidooDataUpdateCoordinator(DataUpdateCoordinator[CookidooData]):
|
||||
},
|
||||
) from exc
|
||||
_LOGGER.debug(
|
||||
"Authentication failed but re-authentication was successful, trying again later"
|
||||
"Authentication failed but re-authentication"
|
||||
" was successful, trying again later"
|
||||
)
|
||||
return self.data
|
||||
except CookidooException as e:
|
||||
|
||||
@@ -73,7 +73,10 @@ class CookidooIngredientsTodoListEntity(CookidooBaseEntity, TodoListEntity):
|
||||
async def async_update_todo_item(self, item: TodoItem) -> None:
|
||||
"""Update an ingredient to the To-do list.
|
||||
|
||||
Cookidoo ingredients can be changed in state, but not in summary or description. This is currently not possible to distinguish in home assistant and just fails silently.
|
||||
Cookidoo ingredients can be changed in state, but not
|
||||
in summary or description. This is currently not
|
||||
possible to distinguish in Home Assistant and just
|
||||
fails silently.
|
||||
"""
|
||||
try:
|
||||
if TYPE_CHECKING:
|
||||
@@ -99,7 +102,7 @@ class CookidooIngredientsTodoListEntity(CookidooBaseEntity, TodoListEntity):
|
||||
|
||||
|
||||
class CookidooAdditionalItemTodoListEntity(CookidooBaseEntity, TodoListEntity):
|
||||
"""A To-do List representation of the additional items in the Cookidoo Shopping List."""
|
||||
"""A To-do List representation of additional Cookidoo Shopping List items."""
|
||||
|
||||
_attr_translation_key = "additional_item_list"
|
||||
_attr_supported_features = (
|
||||
|
||||
@@ -68,7 +68,8 @@ class CoolmasterClimate(CoolmasterEntity, ClimateEntity):
|
||||
|
||||
_attr_name = None
|
||||
|
||||
# TODO(2026.7.0): When support for unknown fan speeds is removed, delete this variable.
|
||||
# TODO(2026.7.0): When support for unknown fan speeds is
|
||||
# removed, delete this variable.
|
||||
# Holds unknown fan speeds we have already warned about.
|
||||
warned_unknown_fan_speeds: set[str] = set()
|
||||
|
||||
|
||||
@@ -54,7 +54,9 @@ class CoolmasterDataUpdateCoordinator(
|
||||
except OSError as error:
|
||||
if retries_left == 0:
|
||||
raise UpdateFailed(
|
||||
f"Error communicating with Coolmaster (aborting after {MAX_RETRIES} retries): {error}"
|
||||
"Error communicating with Coolmaster"
|
||||
f" (aborting after {MAX_RETRIES}"
|
||||
f" retries): {error}"
|
||||
) from error
|
||||
_LOGGER.debug(
|
||||
"Error communicating with coolmaster (%d retries left): %s",
|
||||
@@ -66,7 +68,8 @@ class CoolmasterDataUpdateCoordinator(
|
||||
return status
|
||||
|
||||
_LOGGER.debug(
|
||||
"Error communicating with coolmaster: empty status received (%d retries left)",
|
||||
"Error communicating with coolmaster:"
|
||||
" empty status received (%d retries left)",
|
||||
retries_left,
|
||||
)
|
||||
|
||||
@@ -74,5 +77,7 @@ class CoolmasterDataUpdateCoordinator(
|
||||
await asyncio.sleep(backoff)
|
||||
|
||||
raise UpdateFailed(
|
||||
f"Error communicating with Coolmaster (aborting after {MAX_RETRIES} retries): empty status received"
|
||||
"Error communicating with Coolmaster"
|
||||
f" (aborting after {MAX_RETRIES} retries):"
|
||||
" empty status received"
|
||||
)
|
||||
|
||||
@@ -254,17 +254,20 @@ class Counter(collection.CollectionEntity, RestoreEntity):
|
||||
"""Set counter to value."""
|
||||
if (maximum := self._config.get(CONF_MAXIMUM)) is not None and value > maximum:
|
||||
raise ValueError(
|
||||
f"Value {value} for {self.entity_id} exceeding the maximum value of {maximum}"
|
||||
f"Value {value} for {self.entity_id}"
|
||||
f" exceeding the maximum value of {maximum}"
|
||||
)
|
||||
|
||||
if (minimum := self._config.get(CONF_MINIMUM)) is not None and value < minimum:
|
||||
raise ValueError(
|
||||
f"Value {value} for {self.entity_id} exceeding the minimum value of {minimum}"
|
||||
f"Value {value} for {self.entity_id}"
|
||||
f" exceeding the minimum value of {minimum}"
|
||||
)
|
||||
|
||||
if (step := self._config.get(CONF_STEP)) is not None and value % step != 0:
|
||||
raise ValueError(
|
||||
f"Value {value} for {self.entity_id} is not a multiple of the step size {step}"
|
||||
f"Value {value} for {self.entity_id}"
|
||||
f" is not a multiple of the step size {step}"
|
||||
)
|
||||
|
||||
self._state = value
|
||||
|
||||
@@ -428,9 +428,13 @@ class CoverEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
# * fully open but do not report `current_cover_position`
|
||||
# * stopped partially open
|
||||
# * either opening or closing, but do not report them
|
||||
# If we previously reported opening/closing, we should move in the opposite direction.
|
||||
# Otherwise, we must assume we are (partially) open and should always close.
|
||||
# Note: _cover_is_last_toggle_direction_open will always remain True if we never report opening/closing.
|
||||
# If we previously reported opening/closing, we should
|
||||
# move in the opposite direction.
|
||||
# Otherwise, we must assume we are (partially) open
|
||||
# and should always close.
|
||||
# Note: _cover_is_last_toggle_direction_open will
|
||||
# always remain True if we never report
|
||||
# opening/closing.
|
||||
return (
|
||||
fns["close"] if self._cover_is_last_toggle_direction_open else fns["open"]
|
||||
)
|
||||
|
||||
@@ -79,7 +79,8 @@ class CrownstoneEntryManager:
|
||||
_LOGGER.error("Unknown error during login")
|
||||
raise ConfigEntryNotReady from unknown_err
|
||||
|
||||
# A new clientsession is created because the default one does not cleanup on unload
|
||||
# A new clientsession is created because the default
|
||||
# one does not cleanup on unload
|
||||
self.sse = CrownstoneSSEAsync(
|
||||
email=email,
|
||||
password=password,
|
||||
@@ -98,7 +99,8 @@ class CrownstoneEntryManager:
|
||||
await self.async_setup_usb()
|
||||
|
||||
# Save the sphere where the USB is located
|
||||
# Makes HA aware of the Crownstone environment HA is placed in, a user can have multiple
|
||||
# Makes HA aware of the Crownstone environment HA is
|
||||
# placed in, a user can have multiple
|
||||
self.usb_sphere_id = self.config_entry.options[CONF_USB_SPHERE]
|
||||
|
||||
return True
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
"""Listeners for updating data in the Crownstone integration.
|
||||
|
||||
For data updates, Cloud Push is used in form of an SSE server that sends out events.
|
||||
For fast device switching Local Push is used in form of a USB dongle that hooks into a BLE mesh.
|
||||
For data updates, Cloud Push is used in form of an SSE server
|
||||
that sends out events.
|
||||
For fast device switching Local Push is used in form of a USB
|
||||
dongle that hooks into a BLE mesh.
|
||||
"""
|
||||
|
||||
from functools import partial
|
||||
|
||||
@@ -88,7 +88,7 @@ class CyncConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
async def async_step_reauth_confirm(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Dialog that informs the user that reauth is required and prompts for their Cync credentials."""
|
||||
"""Inform the user that reauth is required and prompt for Cync credentials."""
|
||||
errors: dict[str, str] = {}
|
||||
|
||||
reauth_entry = self._get_reauth_entry()
|
||||
|
||||
@@ -51,7 +51,7 @@ class CyncCoordinator(DataUpdateCoordinator[dict[int, CyncDevice]]):
|
||||
await self._update_config_cync_credentials(logged_in_user)
|
||||
|
||||
async def _async_update_data(self) -> dict[int, CyncDevice]:
|
||||
"""First, refresh the user's auth token if it is set to expire in less than one hour.
|
||||
"""Refresh the user's auth token if it expires within one hour.
|
||||
|
||||
Then, fetch all current device states.
|
||||
"""
|
||||
|
||||
@@ -173,7 +173,10 @@ async def async_setup_entry(
|
||||
|
||||
|
||||
def format_target_temperature(target_temperature: float) -> str:
|
||||
"""Format target temperature to be sent to the Daikin unit, rounding to nearest half degree."""
|
||||
"""Format target temperature to be sent to the Daikin unit.
|
||||
|
||||
Rounds to nearest half degree.
|
||||
"""
|
||||
return str(round(float(target_temperature) * 2, 0) / 2).rstrip("0").rstrip(".")
|
||||
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: DeakoConfigEntry) -> boo
|
||||
await connection.disconnect()
|
||||
raise ConfigEntryNotReady(exc) from exc
|
||||
|
||||
# If deako devices are advertising on mdns, we should be able to get at least one device
|
||||
# If deako devices are advertising on mdns, we should be
|
||||
# able to get at least one device
|
||||
devices = connection.get_devices()
|
||||
if len(devices) == 0:
|
||||
await connection.disconnect()
|
||||
|
||||
@@ -13,14 +13,19 @@ LOGGER = logging.getLogger(__package__)
|
||||
|
||||
|
||||
class DelugeGetSessionStatusKeys(enum.Enum):
|
||||
"""Enum representing the keys that get passed into the Deluge RPC `core.get_session_status` xml rpc method.
|
||||
"""Keys passed into the Deluge RPC `core.get_session_status`.
|
||||
|
||||
You can call `core.get_session_status` with no keys (so an empty list in deluge-client.DelugeRPCClient.call)
|
||||
to get the full list of possible keys, but it seems to basically be a all of the session statistics
|
||||
listed on this page: https://www.rasterbar.com/products/libtorrent/manual-ref.html#session-statistics
|
||||
You can call `core.get_session_status` with no keys
|
||||
(so an empty list in
|
||||
deluge-client.DelugeRPCClient.call)
|
||||
to get the full list of possible keys, but it seems to
|
||||
basically be all of the session statistics listed on
|
||||
this page:
|
||||
https://www.rasterbar.com/products/libtorrent/manual-ref.html#session-statistics
|
||||
and a few others
|
||||
|
||||
there is also a list of deprecated keys that deluge will translate for you and issue a warning in the log:
|
||||
there is also a list of deprecated keys that deluge
|
||||
will translate for you and issue a warning in the log:
|
||||
https://github.com/deluge-torrent/deluge/blob/7f3f7f69ee78610e95bea07d99f699e9310c4e08/deluge/core/core.py#L58
|
||||
|
||||
"""
|
||||
@@ -32,10 +37,11 @@ class DelugeGetSessionStatusKeys(enum.Enum):
|
||||
|
||||
|
||||
class DelugeSensorType(enum.StrEnum):
|
||||
"""Enum that distinguishes the different sensor types that the Deluge integration has.
|
||||
"""Sensor types for the Deluge integration.
|
||||
|
||||
This is mainly used to avoid passing strings around and to distinguish between similarly
|
||||
named strings in `DelugeGetSessionStatusKeys`.
|
||||
This is mainly used to avoid passing strings around
|
||||
and to distinguish between similarly named strings
|
||||
in `DelugeGetSessionStatusKeys`.
|
||||
"""
|
||||
|
||||
CURRENT_STATUS_SENSOR = "current_status"
|
||||
|
||||
@@ -27,7 +27,8 @@ def get_state(data: dict[str, float], key: str) -> str | float:
|
||||
protocol_upload = data[DelugeGetSessionStatusKeys.DHT_UPLOAD_RATE.value]
|
||||
protocol_download = data[DelugeGetSessionStatusKeys.DHT_DOWNLOAD_RATE.value]
|
||||
|
||||
# if key is CURRENT_STATUS, we just return whether we are uploading / downloading / idle
|
||||
# if key is CURRENT_STATUS, we just return whether
|
||||
# we are uploading / downloading / idle
|
||||
if key == DelugeSensorType.CURRENT_STATUS_SENSOR:
|
||||
if upload > 0 and download > 0:
|
||||
return "seeding_and_downloading"
|
||||
|
||||
@@ -252,13 +252,15 @@ class DenonDevice(MediaPlayerEntity):
|
||||
|
||||
def _telnet_callback(self, zone: str, event: str, parameter: str) -> None:
|
||||
"""Process a telnet command callback."""
|
||||
# There are multiple checks implemented which reduce unnecessary updates of the ha state machine
|
||||
# There are multiple checks implemented which reduce
|
||||
# unnecessary updates of the ha state machine
|
||||
if zone not in (self._receiver.zone, ALL_ZONES):
|
||||
return
|
||||
if event not in TELNET_EVENTS:
|
||||
return
|
||||
# Some updates trigger multiple events like one for artist and one for title for one change
|
||||
# We skip every event except the last one
|
||||
# Some updates trigger multiple events like one for
|
||||
# artist and one for title for one change.
|
||||
# We skip every event except the last one.
|
||||
if event == "NSE" and not parameter.startswith("4"):
|
||||
return
|
||||
if event == "TA" and not parameter.startswith("ANNAME"):
|
||||
|
||||
@@ -63,7 +63,8 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
|
||||
new_options = {**config_entry.options}
|
||||
|
||||
if new_options.get("unit_prefix") == "none":
|
||||
# Before we had support for optional selectors, "none" was used for selecting nothing
|
||||
# Before we had support for optional selectors,
|
||||
# "none" was used for selecting nothing
|
||||
del new_options["unit_prefix"]
|
||||
|
||||
hass.config_entries.async_update_entry(
|
||||
|
||||
@@ -275,7 +275,8 @@ class DerivativeSensor(RestoreSensor, SensorEntity):
|
||||
|
||||
if original_unit != self._attr_native_unit_of_measurement:
|
||||
_LOGGER.debug(
|
||||
"%s: Derivative sensor switched UoM from %s to %s, resetting state to 0",
|
||||
"%s: Derivative sensor switched UoM from"
|
||||
" %s to %s, resetting state to 0",
|
||||
self.entity_id,
|
||||
original_unit,
|
||||
self._attr_native_unit_of_measurement,
|
||||
@@ -327,7 +328,8 @@ class DerivativeSensor(RestoreSensor, SensorEntity):
|
||||
)
|
||||
|
||||
def _handle_invalid_source_state(self, state: State | None) -> bool:
|
||||
# Check the source state for unknown/unavailable condition. If unusable, write unknown/unavailable state and return false.
|
||||
# Check the source state for unknown/unavailable condition.
|
||||
# If unusable, write unknown/unavailable state and return false.
|
||||
if not state or state.state == STATE_UNAVAILABLE:
|
||||
self._attr_available = False
|
||||
self.async_write_ha_state()
|
||||
@@ -376,10 +378,12 @@ class DerivativeSensor(RestoreSensor, SensorEntity):
|
||||
def schedule_max_sub_interval_exceeded(source_state: State | None) -> None:
|
||||
"""Schedule calculation using the source state and max_sub_interval.
|
||||
|
||||
The callback reference is stored for possible cancellation if the source state
|
||||
reports a change before max_sub_interval has passed.
|
||||
If the callback is executed, meaning there was no state change reported, the
|
||||
source_state is assumed constant and calculation is done using its value.
|
||||
The callback reference is stored for possible
|
||||
cancellation if the source state reports a change
|
||||
before max_sub_interval has passed.
|
||||
If the callback is executed, meaning there was no
|
||||
state change reported, the source_state is assumed
|
||||
constant and calculation is done using its value.
|
||||
"""
|
||||
if (
|
||||
self._max_sub_interval is not None
|
||||
@@ -394,14 +398,17 @@ class DerivativeSensor(RestoreSensor, SensorEntity):
|
||||
"""Calculate derivative based on time and reschedule."""
|
||||
|
||||
_LOGGER.debug(
|
||||
"%s: Recalculating derivative due to max_sub_interval time elapsed",
|
||||
"%s: Recalculating derivative due to"
|
||||
" max_sub_interval time elapsed",
|
||||
self.entity_id,
|
||||
)
|
||||
self._prune_state_list(now)
|
||||
derivative = self._calc_derivative_from_state_list(now)
|
||||
self._write_native_value(derivative)
|
||||
|
||||
# If derivative is now zero, don't schedule another timeout callback, as it will have no effect
|
||||
# If derivative is now zero, don't schedule
|
||||
# another timeout callback, as it will have
|
||||
# no effect
|
||||
if derivative != 0:
|
||||
schedule_max_sub_interval_exceeded(source_state)
|
||||
|
||||
@@ -483,7 +490,8 @@ class DerivativeSensor(RestoreSensor, SensorEntity):
|
||||
old_value = self._last_valid_state_time[0]
|
||||
old_timestamp = self._last_valid_state_time[1]
|
||||
else:
|
||||
# Sensor becomes valid for the first time, just keep the restored value
|
||||
# Sensor becomes valid for the first time,
|
||||
# just keep the restored value
|
||||
self.async_write_ha_state()
|
||||
return
|
||||
|
||||
@@ -525,7 +533,8 @@ class DerivativeSensor(RestoreSensor, SensorEntity):
|
||||
"%s: Could not calculate derivative: %s", self.entity_id, err
|
||||
)
|
||||
|
||||
# For total inreasing sensors, the value is expected to continuously increase.
|
||||
# For total increasing sensors, the value is
|
||||
# expected to continuously increase.
|
||||
# A negative derivative for a total increasing sensor likely indicates the
|
||||
# sensor has been reset. To prevent inaccurate data, discard this sample.
|
||||
if (
|
||||
@@ -546,8 +555,10 @@ class DerivativeSensor(RestoreSensor, SensorEntity):
|
||||
new_timestamp,
|
||||
)
|
||||
|
||||
# If outside of time window just report derivative (is the same as modeling it in the window),
|
||||
# otherwise take the weighted average with the previous derivatives
|
||||
# If outside of time window just report derivative
|
||||
# (is the same as modeling it in the window),
|
||||
# otherwise take the weighted average with the
|
||||
# previous derivatives
|
||||
if elapsed_time > self._time_window:
|
||||
derivative = new_derivative
|
||||
else:
|
||||
|
||||
@@ -162,7 +162,8 @@ async def async_get_device_automation_platform(
|
||||
) -> DeviceAutomationPlatformType:
|
||||
"""Load device automation platform for integration.
|
||||
|
||||
Throws InvalidDeviceAutomationConfig if the integration is not found or does not support device automation.
|
||||
Throws InvalidDeviceAutomationConfig if the integration is not found
|
||||
or does not support device automation.
|
||||
"""
|
||||
platform_name = automation_type.value.section
|
||||
try:
|
||||
|
||||
@@ -106,7 +106,10 @@ def configure_mydevolo(conf: Mapping[str, Any]) -> Mydevolo:
|
||||
|
||||
|
||||
def check_mydevolo_and_get_gateway_ids(mydevolo: Mydevolo) -> list[str]:
|
||||
"""Check if the credentials are valid and return user's gateway IDs as long as mydevolo is not in maintenance mode."""
|
||||
"""Check credentials and return user's gateway IDs.
|
||||
|
||||
Raises if mydevolo is in maintenance mode.
|
||||
"""
|
||||
if not mydevolo.credentials_valid():
|
||||
raise ConfigEntryAuthFailed(
|
||||
translation_domain=DOMAIN,
|
||||
|
||||
@@ -29,7 +29,7 @@ async def async_setup_entry(
|
||||
entry: DevoloHomeControlConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Get all binary sensor and multi level sensor devices and setup them via config entry."""
|
||||
"""Get all binary sensor and multi level sensor devices."""
|
||||
entities: list[BinarySensorEntity] = []
|
||||
|
||||
for gateway in entry.runtime_data:
|
||||
|
||||
@@ -75,7 +75,9 @@ class DevoloClimateDeviceEntity(DevoloMultiLevelSwitchDeviceEntity, ClimateEntit
|
||||
return next(
|
||||
(
|
||||
multi_level_sensor.value
|
||||
for multi_level_sensor in self._device_instance.multi_level_sensor_property.values()
|
||||
for multi_level_sensor in (
|
||||
self._device_instance.multi_level_sensor_property.values()
|
||||
)
|
||||
if multi_level_sensor.sensor_type == "temperature"
|
||||
),
|
||||
None,
|
||||
|
||||
@@ -117,7 +117,9 @@ class DevoloHomeControlFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
)
|
||||
|
||||
if self.unique_id != uuid:
|
||||
# The old user and the new user are not the same. This could mess-up everything as all unique IDs might change.
|
||||
# The old user and the new user are not the same.
|
||||
# This could mess-up everything as all
|
||||
# unique IDs might change.
|
||||
raise UuidChanged
|
||||
|
||||
reauth_entry = self._get_reauth_entry()
|
||||
|
||||
@@ -115,7 +115,10 @@ class DevoloDeviceEntity(Entity):
|
||||
|
||||
|
||||
class DevoloMultiLevelSwitchDeviceEntity(DevoloDeviceEntity):
|
||||
"""Representation of a multi level switch device within devolo Home Control. Something like a dimmer or a thermostat."""
|
||||
"""Representation of a multi level switch device within devolo Home Control.
|
||||
|
||||
Something like a dimmer or a thermostat.
|
||||
"""
|
||||
|
||||
_attr_name = None
|
||||
|
||||
|
||||
@@ -70,7 +70,8 @@ class DevoloLightDeviceEntity(DevoloMultiLevelSwitchDeviceEntity, LightEntity):
|
||||
round(kwargs[ATTR_BRIGHTNESS] / 255 * 100)
|
||||
)
|
||||
elif self._binary_switch_property is not None:
|
||||
# Turn on the light device to the latest known value. The value is known by the device itself.
|
||||
# Turn on the light device to the latest known
|
||||
# value. The value is known by the device itself.
|
||||
self._binary_switch_property.set(True)
|
||||
else:
|
||||
# If there is no binary switch attached to the device, turn it on to 100 %.
|
||||
|
||||
@@ -18,7 +18,7 @@ async def async_setup_entry(
|
||||
entry: DevoloHomeControlConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Get all binary sensor and multi level sensor devices and setup them via config entry."""
|
||||
"""Get all binary sensor and multi level sensor devices."""
|
||||
|
||||
async_add_entities(
|
||||
DevoloSirenDeviceEntity(
|
||||
|
||||
@@ -40,9 +40,11 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str,
|
||||
|
||||
await device.async_connect(session_instance=async_client)
|
||||
|
||||
# Try a password protected, non-writing device API call that raises, if the password is wrong.
|
||||
# If only the plcnet API is available, we can continue without trying a password as the plcnet
|
||||
# API does not require a password.
|
||||
# Try a password protected, non-writing device API
|
||||
# call that raises, if the password is wrong.
|
||||
# If only the plcnet API is available, we can continue
|
||||
# without trying a password as the plcnet API does not
|
||||
# require a password.
|
||||
if device.device:
|
||||
await device.device.async_uptime()
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ class DevoloDataUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT]):
|
||||
|
||||
@callback
|
||||
def update_sw_version(self) -> None:
|
||||
"""Update device registry with new firmware version, if it changed at runtime."""
|
||||
"""Update device registry with new firmware version."""
|
||||
device_registry = dr.async_get(self.hass)
|
||||
if (
|
||||
device_entry := device_registry.async_get_device(
|
||||
|
||||
@@ -35,7 +35,11 @@ PARALLEL_UPDATES = 0
|
||||
|
||||
|
||||
def _last_restart(runtime: int) -> datetime:
|
||||
"""Calculate uptime. As fetching the data might also take some time, let's floor to the nearest 5 seconds."""
|
||||
"""Calculate uptime.
|
||||
|
||||
As fetching the data might also take some time,
|
||||
let's floor to the nearest 5 seconds.
|
||||
"""
|
||||
now = utcnow()
|
||||
return (
|
||||
now
|
||||
|
||||
@@ -130,7 +130,8 @@ class DiscogsSensor(SensorEntity):
|
||||
"cat_no": self._attrs["labels"][0]["catno"],
|
||||
"cover_image": self._attrs["cover_image"],
|
||||
"format": (
|
||||
f"{self._attrs['formats'][0]['name']} ({self._attrs['formats'][0]['descriptions'][0]})"
|
||||
f"{self._attrs['formats'][0]['name']}"
|
||||
f" ({self._attrs['formats'][0]['descriptions'][0]})"
|
||||
),
|
||||
"label": self._attrs["labels"][0]["name"],
|
||||
"released": self._attrs["year"],
|
||||
|
||||
@@ -25,7 +25,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: DiscovergyConfigEntry) -
|
||||
)
|
||||
|
||||
try:
|
||||
# try to get meters from api to check if credentials are still valid and for later use
|
||||
# try to get meters from api to check if credentials
|
||||
# are still valid and for later use;
|
||||
# if no exception is raised everything is fine to go
|
||||
meters = await client.meters()
|
||||
except discovergyError.InvalidLogin as err:
|
||||
|
||||
@@ -173,7 +173,8 @@ async def async_setup_entry(
|
||||
for coordinator in entry.runtime_data:
|
||||
sensors: tuple[DiscovergySensorEntityDescription, ...] = ()
|
||||
|
||||
# select sensor descriptions based on meter type and combine with additional sensors
|
||||
# select sensor descriptions based on meter type
|
||||
# and combine with additional sensors
|
||||
if coordinator.meter.measurement_type == "ELECTRICITY":
|
||||
sensors = ELECTRICITY_SENSORS + ADDITIONAL_SENSORS
|
||||
elif coordinator.meter.measurement_type == "GAS":
|
||||
@@ -213,7 +214,11 @@ class DiscovergySensor(CoordinatorEntity[DiscovergyUpdateCoordinator], SensorEnt
|
||||
self._attr_unique_id = f"{meter.full_serial_number}-{data_key}"
|
||||
self._attr_device_info = DeviceInfo(
|
||||
identifiers={(DOMAIN, meter.meter_id)},
|
||||
name=f"{meter.measurement_type.capitalize()} {meter.location.street} {meter.location.street_number}",
|
||||
name=(
|
||||
f"{meter.measurement_type.capitalize()}"
|
||||
f" {meter.location.street}"
|
||||
f" {meter.location.street_number}"
|
||||
),
|
||||
model=meter.meter_type,
|
||||
manufacturer=MANUFACTURER,
|
||||
serial_number=meter.full_serial_number,
|
||||
|
||||
@@ -116,7 +116,8 @@ class DoorBirdConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
|
||||
This method performs the following verification steps:
|
||||
1. Ensures that the stored credentials work before updating the entry.
|
||||
2. Verifies that the device at the discovered IP address has the expected MAC address.
|
||||
2. Verifies that the device at the discovered IP
|
||||
address has the expected MAC address.
|
||||
"""
|
||||
info, errors = await self._async_validate_or_error(
|
||||
{
|
||||
|
||||
@@ -19,7 +19,10 @@ async def async_setup_entry(
|
||||
config_entry: DremelConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up a MJPEG IP Camera for the 3D45 Model. The 3D20 and 3D40 models don't have built in cameras."""
|
||||
"""Set up a MJPEG IP Camera for the 3D45 Model.
|
||||
|
||||
The 3D20 and 3D40 models don't have built in cameras.
|
||||
"""
|
||||
async_add_entities([Dremel3D45Camera(config_entry.runtime_data, CAMERA_TYPE)])
|
||||
|
||||
|
||||
|
||||
@@ -54,8 +54,9 @@ class FlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
f"{self._drop_discovery.hub_id}_{self._drop_discovery.device_id}"
|
||||
)
|
||||
if existing_entry is not None:
|
||||
# Note: returning "invalid_discovery_info" here instead of "already_configured"
|
||||
# allows discovery of additional device types.
|
||||
# Note: returning "invalid_discovery_info" here
|
||||
# instead of "already_configured" allows discovery
|
||||
# of additional device types.
|
||||
return self.async_abort(reason="invalid_discovery_info")
|
||||
|
||||
self.context.update({"title_placeholders": {"name": self._drop_discovery.name}})
|
||||
|
||||
@@ -25,7 +25,10 @@ async def async_get_auth_implementation(
|
||||
|
||||
|
||||
class DropboxOAuth2Implementation(LocalOAuth2ImplementationWithPkce):
|
||||
"""Custom Dropbox OAuth2 implementation to add the necessary authorize url parameters."""
|
||||
"""Custom Dropbox OAuth2 implementation.
|
||||
|
||||
Adds the necessary authorize url parameters.
|
||||
"""
|
||||
|
||||
@property
|
||||
def extra_authorize_data(self) -> dict:
|
||||
|
||||
@@ -126,7 +126,9 @@ class DSMRConnection:
|
||||
async with asyncio.timeout(30):
|
||||
await protocol.wait_closed()
|
||||
except TimeoutError:
|
||||
# Timeout (no data received), close transport and return True (if telegram is empty, will result in CannotCommunicate error)
|
||||
# Timeout (no data received), close transport
|
||||
# and return True (if telegram is empty, will
|
||||
# result in CannotCommunicate error)
|
||||
transport.close()
|
||||
await protocol.wait_closed()
|
||||
return True
|
||||
|
||||
@@ -16,7 +16,10 @@ async def _async_has_devices(_: HomeAssistant) -> bool:
|
||||
|
||||
|
||||
class DsmrReaderFlowHandler(DiscoveryFlowHandler[Awaitable[bool]], domain=DOMAIN):
|
||||
"""Handle DSMR Reader config flow. The MQTT step is inherited from the parent class."""
|
||||
"""Handle DSMR Reader config flow.
|
||||
|
||||
The MQTT step is inherited from the parent class.
|
||||
"""
|
||||
|
||||
VERSION = 1
|
||||
|
||||
|
||||
@@ -34,7 +34,8 @@ async def async_get_config_entry_diagnostics(
|
||||
coordinator = entry.runtime_data
|
||||
|
||||
board = asdict(coordinator.board_info)
|
||||
# `time` is a Unix epoch timestamp of the last board info fetch; not useful for support triage.
|
||||
# `time` is a Unix epoch timestamp of the last board
|
||||
# info fetch; not useful for support triage.
|
||||
board.pop("time")
|
||||
if board["public_api_version"] is None:
|
||||
board.pop("public_api_version")
|
||||
|
||||
@@ -62,7 +62,8 @@ async def async_setup_entry(
|
||||
"""Set up Duco fan entities."""
|
||||
coordinator = entry.runtime_data
|
||||
|
||||
# BOX is always node 1 and is never dynamically added or removed, so no listener needed.
|
||||
# BOX is always node 1 and is never dynamically added
|
||||
# or removed, so no listener needed.
|
||||
async_add_entities(
|
||||
DucoVentilationFanEntity(coordinator, node)
|
||||
for node in coordinator.data.nodes.values()
|
||||
|
||||
@@ -30,7 +30,8 @@ def get_position_data(
|
||||
longitude = entity.attributes.get(ATTR_LONGITUDE)
|
||||
if not longitude:
|
||||
raise AttributeError(
|
||||
f"Failed to find attribute '{ATTR_LONGITUDE}' in {registry_entry.entity_id}",
|
||||
f"Failed to find attribute '{ATTR_LONGITUDE}'"
|
||||
f" in {registry_entry.entity_id}",
|
||||
ATTR_LONGITUDE,
|
||||
)
|
||||
|
||||
|
||||
@@ -64,7 +64,9 @@ class DynaliteBridge:
|
||||
def update_device(self, device: DynaliteBaseDevice | None = None) -> None:
|
||||
"""Call when a device or all devices should be updated."""
|
||||
if not device:
|
||||
# This is used to signal connection or disconnection, so all devices may become available or not.
|
||||
# This is used to signal connection or
|
||||
# disconnection, so all devices may become
|
||||
# available or not.
|
||||
log_string = (
|
||||
"Connected" if self.dynalite_devices.connected else "Disconnected"
|
||||
)
|
||||
@@ -102,7 +104,10 @@ class DynaliteBridge:
|
||||
self.async_add_devices[platform](self.waiting_devices[platform])
|
||||
|
||||
def add_devices_when_registered(self, devices: list[DynaliteBaseDevice]) -> None:
|
||||
"""Add the devices to HA if the add devices callback was registered, otherwise queue until it is."""
|
||||
"""Add the devices to HA if the add devices callback was registered.
|
||||
|
||||
Otherwise queue until it is.
|
||||
"""
|
||||
for platform in PLATFORMS:
|
||||
platform_devices = [
|
||||
device for device in devices if device.category == platform
|
||||
|
||||
@@ -20,7 +20,7 @@ async def async_setup_entry(
|
||||
config_entry: DynaliteConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Record the async_add_entities function to add them later when received from Dynalite."""
|
||||
"""Record the async_add_entities function to add them later."""
|
||||
|
||||
@callback
|
||||
def cover_from_device(device: Any, bridge: DynaliteBridge) -> CoverEntity:
|
||||
@@ -86,7 +86,7 @@ class DynaliteCover(DynaliteBase, CoverEntity):
|
||||
|
||||
|
||||
class DynaliteCoverWithTilt(DynaliteCover):
|
||||
"""Representation of a Dynalite Channel as a Home Assistant Cover that uses up and down for tilt."""
|
||||
"""Representation of a Dynalite Channel as a Cover with tilt."""
|
||||
|
||||
@property
|
||||
def current_cover_tilt_position(self) -> int:
|
||||
|
||||
@@ -21,7 +21,7 @@ def async_setup_entry_base(
|
||||
platform: str,
|
||||
entity_from_device: Callable,
|
||||
) -> None:
|
||||
"""Record the async_add_entities function to add them later when received from Dynalite."""
|
||||
"""Record the async_add_entities function to add them later."""
|
||||
LOGGER.debug("Setting up %s entry = %s", platform, config_entry.data)
|
||||
bridge = config_entry.runtime_data
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ async def async_setup_entry(
|
||||
config_entry: DynaliteConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Record the async_add_entities function to add them later when received from Dynalite."""
|
||||
"""Record the async_add_entities function to add them later."""
|
||||
async_setup_entry_base(
|
||||
hass, config_entry, async_add_entities, "light", DynaliteLight
|
||||
)
|
||||
|
||||
@@ -90,7 +90,7 @@ TEMPLATE_SCHEMA = vol.Schema({str: TEMPLATE_DATA_SCHEMA})
|
||||
|
||||
|
||||
def validate_area(config: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Validate that template parameters are only used if area is using the relevant template."""
|
||||
"""Validate template params are only used with relevant template."""
|
||||
conf_set = set()
|
||||
for configs in DEFAULT_TEMPLATES.values():
|
||||
for conf in configs:
|
||||
|
||||
@@ -16,7 +16,7 @@ async def async_setup_entry(
|
||||
config_entry: DynaliteConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Record the async_add_entities function to add them later when received from Dynalite."""
|
||||
"""Record the async_add_entities function to add them later."""
|
||||
async_setup_entry_base(
|
||||
hass, config_entry, async_add_entities, "switch", DynaliteSwitch
|
||||
)
|
||||
|
||||
@@ -114,7 +114,8 @@ class Measurement(CoordinatorEntity, SensorEntity):
|
||||
if "latestReading" not in self.coordinator.data["measures"][self.key]:
|
||||
return False
|
||||
|
||||
# Sometimes lastestReading key is present but actually a URL rather than a piece of data
|
||||
# Sometimes lastestReading key is present but actually
|
||||
# a URL rather than a piece of data.
|
||||
# This is usually because the sensor has been archived
|
||||
if not isinstance(
|
||||
self.coordinator.data["measures"][self.key]["latestReading"], dict
|
||||
|
||||
@@ -244,7 +244,10 @@ class EasyEnergySensorEntity(
|
||||
self.entity_id = (
|
||||
f"{SENSOR_DOMAIN}.{DOMAIN}_{description.service_type}_{description.key}"
|
||||
)
|
||||
self._attr_unique_id = f"{coordinator.config_entry.entry_id}_{description.service_type}_{description.key}"
|
||||
self._attr_unique_id = (
|
||||
f"{coordinator.config_entry.entry_id}"
|
||||
f"_{description.service_type}_{description.key}"
|
||||
)
|
||||
self._attr_device_info = DeviceInfo(
|
||||
entry_type=DeviceEntryType.SERVICE,
|
||||
identifiers={
|
||||
|
||||
@@ -463,7 +463,7 @@ class Thermostat(ClimateEntity):
|
||||
|
||||
@property
|
||||
def has_humidifier_control(self) -> bool:
|
||||
"""Return true if humidifier connected to thermostat and set to manual/on mode."""
|
||||
"""Return true if humidifier connected to thermostat and manual/on."""
|
||||
return (
|
||||
bool(self.settings.get("hasHumidifier"))
|
||||
and self.settings.get("humidifierMode") == HUMIDIFIER_MANUAL_MODE
|
||||
@@ -888,7 +888,8 @@ class Thermostat(ClimateEntity):
|
||||
current_sensors_in_climate = self._sensors_in_preset_mode(preset_mode)
|
||||
if set(sensor_names) == set(current_sensors_in_climate):
|
||||
_LOGGER.debug(
|
||||
"This action would not be an update, current sensors on climate (%s) are: %s",
|
||||
"This action would not be an update, current sensors"
|
||||
" on climate (%s) are: %s",
|
||||
preset_mode,
|
||||
", ".join(current_sensors_in_climate),
|
||||
)
|
||||
|
||||
@@ -71,7 +71,7 @@ class EcobeeFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
async def async_step_authorize(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Present the user with the PIN so that the app can be authorized on ecobee.com."""
|
||||
"""Present the user with the PIN to authorize on ecobee.com."""
|
||||
errors = {}
|
||||
|
||||
if user_input is not None:
|
||||
|
||||
@@ -78,7 +78,7 @@ async def async_setup_entry(
|
||||
|
||||
|
||||
class EcobeeVentilatorMinTime(EcobeeBaseEntity, NumberEntity):
|
||||
"""A number class, representing min time for an ecobee thermostat with ventilator attached."""
|
||||
"""Represent min time for an ecobee thermostat with ventilator."""
|
||||
|
||||
entity_description: EcobeeNumberEntityDescription
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ async def async_setup_entry(
|
||||
|
||||
|
||||
class EcobeeVentilator20MinSwitch(EcobeeBaseEntity, SwitchEntity):
|
||||
"""A Switch class, representing 20 min timer for an ecobee thermostat with ventilator attached."""
|
||||
"""Represent 20 min timer for an ecobee thermostat with ventilator."""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
_attr_name = "Ventilator 20m Timer"
|
||||
|
||||
@@ -26,9 +26,10 @@ def ecobee_time(time_string):
|
||||
|
||||
|
||||
def is_indefinite_hold(start_date_string: str, end_date_string: str) -> bool:
|
||||
"""Determine if the given start and end dates from the ecobee API represent an indefinite hold.
|
||||
"""Determine if the ecobee API dates represent an indefinite hold.
|
||||
|
||||
This is not documented in the API, so a rough heuristic is used where a hold over 1 year is considered indefinite.
|
||||
This is not documented in the API, so a rough heuristic is
|
||||
used where a hold over 1 year is considered indefinite.
|
||||
"""
|
||||
return date.fromisoformat(end_date_string) - date.fromisoformat(
|
||||
start_date_string
|
||||
|
||||
@@ -174,7 +174,8 @@ class EcovacsActiveMapSelectEntity(
|
||||
if self._attr_current_option not in self._option_to_id:
|
||||
self._attr_current_option = None
|
||||
|
||||
# Sort named maps first, then numeric IDs (unnamed maps during building) in ascending order.
|
||||
# Sort named maps first, then numeric IDs
|
||||
# (unnamed maps during building) in ascending order.
|
||||
self._attr_options = sorted(
|
||||
self._option_to_id.keys(), key=lambda x: (x.isdigit(), x.lower())
|
||||
)
|
||||
|
||||
@@ -413,9 +413,11 @@ class EcovacsVacuum(
|
||||
"""Get the segments that can be cleaned."""
|
||||
last_seen = self.last_seen_segments or []
|
||||
if self._room_event is None or not self._maps:
|
||||
# If we don't have the necessary information to determine segments, return the last
|
||||
# seen segments to avoid temporarily losing all segments until we get the necessary
|
||||
# information, which could cause unnecessary issues to be created
|
||||
# If we don't have the necessary information to
|
||||
# determine segments, return the last seen segments to
|
||||
# avoid temporarily losing all segments until we get
|
||||
# the necessary information, which could cause
|
||||
# unnecessary issues to be created
|
||||
return last_seen
|
||||
|
||||
map_id = self._room_event.map_id
|
||||
@@ -429,8 +431,9 @@ class EcovacsVacuum(
|
||||
for map_obj in self._maps.values()
|
||||
if map_obj.id != self._room_event.map_id
|
||||
}
|
||||
# Include segments from the current map and any segments from other maps that were
|
||||
# previously seen, as we want to continue showing segments from other maps for
|
||||
# Include segments from the current map and any segments
|
||||
# from other maps that were previously seen, as we want
|
||||
# to continue showing segments from other maps for
|
||||
# mapping purposes
|
||||
segments = [
|
||||
seg for seg in last_seen if _split_composite_id(seg.id)[0] in other_map_ids
|
||||
@@ -486,7 +489,8 @@ class EcovacsVacuum(
|
||||
|
||||
if not valid_room_ids:
|
||||
_LOGGER.warning(
|
||||
"No valid segments to clean after validation, skipping clean segments command"
|
||||
"No valid segments to clean after validation,"
|
||||
" skipping clean segments command"
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
@@ -76,7 +76,9 @@ class EgaugeDataCoordinator(DataUpdateCoordinator[EgaugeData]):
|
||||
EgaugePermissionError,
|
||||
EgaugeException,
|
||||
) as err:
|
||||
# EgaugeAuthenticationError and EgaugePermissionError will raise ConfigEntryAuthFailed once reauth is implemented
|
||||
# EgaugeAuthenticationError and
|
||||
# EgaugePermissionError will raise
|
||||
# ConfigEntryAuthFailed once reauth is implemented
|
||||
raise ConfigEntryError from err
|
||||
except ConnectError as err:
|
||||
raise UpdateFailed(f"Error fetching device info: {err}") from err
|
||||
|
||||
@@ -60,7 +60,7 @@ SENSORS: tuple[EgaugeSensorEntityDescription, ...] = (
|
||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||
native_value_fn=lambda data, register: data.measurements[register],
|
||||
available_fn=lambda data, register: register in data.measurements,
|
||||
supported_fn=lambda register_info: register_info.type == RegisterType.VOLTAGE,
|
||||
supported_fn=(lambda register_info: register_info.type == RegisterType.VOLTAGE),
|
||||
),
|
||||
EgaugeSensorEntityDescription(
|
||||
key="current",
|
||||
@@ -69,7 +69,7 @@ SENSORS: tuple[EgaugeSensorEntityDescription, ...] = (
|
||||
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||
native_value_fn=lambda data, register: data.measurements[register],
|
||||
available_fn=lambda data, register: register in data.measurements,
|
||||
supported_fn=lambda register_info: register_info.type == RegisterType.CURRENT,
|
||||
supported_fn=(lambda register_info: register_info.type == RegisterType.CURRENT),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ async def async_setup_entry(
|
||||
entry: EheimDigitalConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the callbacks for the coordinator so binary sensors can be added as devices are found."""
|
||||
"""Set up callbacks to add binary sensors as devices are found."""
|
||||
coordinator = entry.runtime_data
|
||||
|
||||
def async_setup_device_entities(
|
||||
|
||||
@@ -35,7 +35,7 @@ async def async_setup_entry(
|
||||
entry: EheimDigitalConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the callbacks for the coordinator so climate entities can be added as devices are found."""
|
||||
"""Set up callbacks to add climate entities as devices are found."""
|
||||
coordinator = entry.runtime_data
|
||||
|
||||
def async_setup_device_entities(
|
||||
|
||||
@@ -30,7 +30,8 @@ class EheimDigitalEntity[_DeviceT: EheimDigitalDevice](
|
||||
"""Initialize a EHEIM Digital entity."""
|
||||
super().__init__(coordinator)
|
||||
if TYPE_CHECKING:
|
||||
# At this point at least one device is found and so there is always a main device set
|
||||
# At this point at least one device is found
|
||||
# and so there is always a main device set
|
||||
assert isinstance(coordinator.hub.main, EheimDigitalDevice)
|
||||
self._attr_device_info = DeviceInfo(
|
||||
configuration_url=f"http://{coordinator.config_entry.data[CONF_HOST]}",
|
||||
|
||||
@@ -33,7 +33,7 @@ async def async_setup_entry(
|
||||
entry: EheimDigitalConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the callbacks for the coordinator so lights can be added as devices are found."""
|
||||
"""Set up callbacks for the coordinator to add lights as devices are found."""
|
||||
coordinator = entry.runtime_data
|
||||
|
||||
def async_setup_device_entities(
|
||||
|
||||
@@ -201,7 +201,7 @@ async def async_setup_entry(
|
||||
entry: EheimDigitalConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the callbacks for the coordinator so numbers can be added as devices are found."""
|
||||
"""Set up callbacks for the coordinator to add numbers as devices are found."""
|
||||
coordinator = entry.runtime_data
|
||||
|
||||
def async_setup_device_entities(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user