From daffc8c2ceb12d3a893e9ac10eaf7b2edf75fd09 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Thu, 14 May 2026 23:01:09 +0200 Subject: [PATCH] Fix line length violations in components s (#170722) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: frenck <195327+frenck@users.noreply.github.com> --- homeassistant/components/samsungtv/entity.py | 3 +- .../components/satel_integra/__init__.py | 6 +- .../components/satel_integra/client.py | 3 +- .../components/satel_integra/config_flow.py | 34 ++++-- homeassistant/components/schedule/__init__.py | 6 +- homeassistant/components/scrape/__init__.py | 3 +- .../components/scrape/coordinator.py | 6 +- .../components/screenlogic/__init__.py | 6 +- .../components/screenlogic/entity.py | 3 +- homeassistant/components/search/__init__.py | 3 +- homeassistant/components/sensor/__init__.py | 62 ++++++---- homeassistant/components/sensor/const.py | 36 ++++-- homeassistant/components/sensor/recorder.py | 21 ++-- homeassistant/components/senz/api.py | 2 +- .../components/sftp_storage/__init__.py | 10 +- .../components/sftp_storage/backup.py | 3 +- .../components/sftp_storage/client.py | 22 ++-- .../components/sftp_storage/config_flow.py | 16 ++- .../components/sharkiq/config_flow.py | 4 +- homeassistant/components/sharkiq/vacuum.py | 7 +- .../components/shelly/config_flow.py | 21 ++-- .../components/shelly/coordinator.py | 5 +- homeassistant/components/shelly/event.py | 3 +- homeassistant/components/shelly/logbook.py | 5 +- .../components/shopping_list/intent.py | 4 +- homeassistant/components/sia/config_flow.py | 5 +- homeassistant/components/sia/entity.py | 2 +- homeassistant/components/sia/hub.py | 24 ++-- .../components/signal_messenger/notify.py | 2 +- .../components/simplefin/coordinator.py | 4 +- homeassistant/components/slack/notify.py | 7 +- homeassistant/components/slack/utils.py | 6 +- homeassistant/components/sleepiq/number.py | 4 +- .../components/slide_local/coordinator.py | 3 +- homeassistant/components/sma/config_flow.py | 3 +- .../components/smappee/config_flow.py | 9 +- .../components/smartthings/__init__.py | 37 ++++-- .../components/smartthings/binary_sensor.py | 5 +- .../components/smartthings/button.py | 6 +- .../components/smartthings/climate.py | 5 +- homeassistant/components/smartthings/const.py | 4 +- .../components/smartthings/number.py | 21 +++- .../components/smartthings/select.py | 23 ++-- .../components/smartthings/sensor.py | 10 +- .../components/smartthings/switch.py | 107 +++++++++++------- homeassistant/components/smartthings/time.py | 11 +- .../components/smarttub/binary_sensor.py | 5 +- homeassistant/components/smarttub/entity.py | 2 +- homeassistant/components/smhi/__init__.py | 5 +- homeassistant/components/smlight/entity.py | 5 +- .../components/snapcast/media_player.py | 8 +- .../components/snmp/device_tracker.py | 6 +- .../components/solaredge/coordinator.py | 15 ++- .../components/solarlog/coordinator.py | 7 +- homeassistant/components/solarlog/entity.py | 3 +- homeassistant/components/solarlog/sensor.py | 8 +- homeassistant/components/soma/cover.py | 3 +- homeassistant/components/sonarr/helpers.py | 14 ++- .../components/songpal/media_player.py | 3 +- homeassistant/components/sonos/__init__.py | 22 ++-- homeassistant/components/sonos/alarms.py | 12 +- homeassistant/components/sonos/entity.py | 2 +- homeassistant/components/sonos/helpers.py | 2 +- .../components/sonos/household_coordinator.py | 5 +- .../components/sonos/media_browser.py | 16 ++- .../components/sonos/media_player.py | 10 +- homeassistant/components/sonos/speaker.py | 16 ++- homeassistant/components/sonos/switch.py | 5 +- .../components/soundtouch/media_player.py | 2 +- .../components/spotify/coordinator.py | 5 +- homeassistant/components/sql/util.py | 3 +- .../components/squeezebox/__init__.py | 3 +- .../components/squeezebox/browse_media.py | 6 +- .../components/squeezebox/config_flow.py | 10 +- .../components/squeezebox/coordinator.py | 3 +- homeassistant/components/squeezebox/entity.py | 8 +- .../components/squeezebox/media_player.py | 10 +- homeassistant/components/squeezebox/switch.py | 6 +- homeassistant/components/squeezebox/update.py | 6 +- homeassistant/components/ssdp/scanner.py | 3 +- homeassistant/components/ssdp/server.py | 6 +- homeassistant/components/starline/sensor.py | 3 +- .../components/starlink/coordinator.py | 3 +- homeassistant/components/starlink/sensor.py | 2 +- homeassistant/components/statistics/sensor.py | 11 +- homeassistant/components/stream/__init__.py | 27 +++-- homeassistant/components/stream/core.py | 14 ++- homeassistant/components/stream/hls.py | 12 +- homeassistant/components/stream/recorder.py | 8 +- homeassistant/components/stream/worker.py | 16 ++- .../components/subaru/coordinator.py | 3 +- homeassistant/components/subaru/lock.py | 4 +- .../swiss_public_transport/__init__.py | 7 +- homeassistant/components/switchbee/entity.py | 5 +- homeassistant/components/switchbee/switch.py | 5 +- .../components/switchbot/__init__.py | 12 +- homeassistant/components/switchbot/button.py | 5 +- homeassistant/components/switchbot/const.py | 4 +- homeassistant/components/switchbot/entity.py | 3 +- .../components/switcher_kis/__init__.py | 3 +- .../components/synology_dsm/config_flow.py | 3 +- .../components/systemnexa2/coordinator.py | 4 +- 102 files changed, 664 insertions(+), 327 deletions(-) diff --git a/homeassistant/components/samsungtv/entity.py b/homeassistant/components/samsungtv/entity.py index a788ecae157..8c980f27964 100644 --- a/homeassistant/components/samsungtv/entity.py +++ b/homeassistant/components/samsungtv/entity.py @@ -37,7 +37,8 @@ class SamsungTVEntity(CoordinatorEntity[SamsungTVDataUpdateCoordinator], Entity) config_entry = coordinator.config_entry self._mac: str | None = config_entry.data.get(CONF_MAC) self._host: str | None = config_entry.data.get(CONF_HOST) - # Fallback for legacy models that doesn't have a API to retrieve MAC or SerialNumber + # Fallback for legacy models that doesn't have a API + # to retrieve MAC or SerialNumber self._attr_unique_id = config_entry.unique_id or config_entry.entry_id self._attr_device_info = DeviceInfo( manufacturer=config_entry.data.get(CONF_MANUFACTURER), diff --git a/homeassistant/components/satel_integra/__init__.py b/homeassistant/components/satel_integra/__init__.py index ea9a109e1a3..dc07df405da 100644 --- a/homeassistant/components/satel_integra/__init__.py +++ b/homeassistant/components/satel_integra/__init__.py @@ -135,7 +135,8 @@ async def async_migrate_entry( SUBENTRY_TYPE_SWITCHABLE_OUTPUT: CONF_SWITCHABLE_OUTPUT_NUMBER, } - new_title = f"{subentry.title} ({subentry.data[property_map[subentry.subentry_type]]})" + prop = property_map[subentry.subentry_type] + new_title = f"{subentry.title} ({subentry.data[prop]})" hass.config_entries.async_update_subentry( config_entry, subentry, title=new_title @@ -143,7 +144,8 @@ async def async_migrate_entry( hass.config_entries.async_update_entry(config_entry, minor_version=2) - # 2.1 Migrate all entity unique IDs to replace "satel" prefix with config entry ID, allows multiple entries to be configured + # 2.1 Migrate all entity unique IDs to replace "satel" prefix + # with config entry ID, allows multiple entries to be configured if config_entry.version == 1: @callback diff --git a/homeassistant/components/satel_integra/client.py b/homeassistant/components/satel_integra/client.py index d9124f1b0d5..bffb99ecd13 100644 --- a/homeassistant/components/satel_integra/client.py +++ b/homeassistant/components/satel_integra/client.py @@ -41,7 +41,8 @@ class SatelClient: host = entry.data[CONF_HOST] port = entry.data[CONF_PORT] - # Make sure we initialize the Satel controller with the configured entries to monitor + # Make sure we initialize the Satel controller + # with the configured entries to monitor partitions = [ subentry.data[CONF_PARTITION_NUMBER] for subentry in entry.subentries.values() diff --git a/homeassistant/components/satel_integra/config_flow.py b/homeassistant/components/satel_integra/config_flow.py index 6b47b0f54b5..fe20a510560 100644 --- a/homeassistant/components/satel_integra/config_flow.py +++ b/homeassistant/components/satel_integra/config_flow.py @@ -312,7 +312,9 @@ class PartitionSubentryFlowHandler(ConfigSubentryFlow): if not errors: return self.async_create_entry( - title=f"{user_input[CONF_NAME]} ({user_input[CONF_PARTITION_NUMBER]})", + title=( + f"{user_input[CONF_NAME]} ({user_input[CONF_PARTITION_NUMBER]})" + ), data=user_input, unique_id=unique_id, ) @@ -339,7 +341,10 @@ class PartitionSubentryFlowHandler(ConfigSubentryFlow): return self.async_update_and_abort( self._get_entry(), subconfig_entry, - title=f"{user_input[CONF_NAME]} ({subconfig_entry.data[CONF_PARTITION_NUMBER]})", + title=( + f"{user_input[CONF_NAME]}" + f" ({subconfig_entry.data[CONF_PARTITION_NUMBER]})" + ), data_updates=user_input, ) @@ -425,7 +430,10 @@ class ZoneSubentryFlowHandler(ConfigSubentryFlow): return self.async_update_and_abort( self._get_entry(), subconfig_entry, - title=f"{user_input[CONF_NAME]} ({subconfig_entry.data[CONF_ZONE_NUMBER]})", + title=( + f"{user_input[CONF_NAME]}" + f" ({subconfig_entry.data[CONF_ZONE_NUMBER]})" + ), data_updates=user_input, ) @@ -491,7 +499,10 @@ class OutputSubentryFlowHandler(ConfigSubentryFlow): return self.async_update_and_abort( self._get_entry(), subconfig_entry, - title=f"{user_input[CONF_NAME]} ({subconfig_entry.data[CONF_OUTPUT_NUMBER]})", + title=( + f"{user_input[CONF_NAME]}" + f" ({subconfig_entry.data[CONF_OUTPUT_NUMBER]})" + ), data_updates=user_input, ) @@ -516,7 +527,10 @@ class SwitchableOutputSubentryFlowHandler(ConfigSubentryFlow): errors: dict[str, str] = {} if user_input is not None: - unique_id = f"{SUBENTRY_TYPE_SWITCHABLE_OUTPUT}_{user_input[CONF_SWITCHABLE_OUTPUT_NUMBER]}" + unique_id = ( + f"{SUBENTRY_TYPE_SWITCHABLE_OUTPUT}" + f"_{user_input[CONF_SWITCHABLE_OUTPUT_NUMBER]}" + ) for existing_subentry in self._get_entry().subentries.values(): if existing_subentry.unique_id == unique_id: @@ -524,7 +538,10 @@ class SwitchableOutputSubentryFlowHandler(ConfigSubentryFlow): if not errors: return self.async_create_entry( - title=f"{user_input[CONF_NAME]} ({user_input[CONF_SWITCHABLE_OUTPUT_NUMBER]})", + title=( + f"{user_input[CONF_NAME]}" + f" ({user_input[CONF_SWITCHABLE_OUTPUT_NUMBER]})" + ), data=user_input, unique_id=unique_id, ) @@ -551,7 +568,10 @@ class SwitchableOutputSubentryFlowHandler(ConfigSubentryFlow): return self.async_update_and_abort( self._get_entry(), subconfig_entry, - title=f"{user_input[CONF_NAME]} ({subconfig_entry.data[CONF_SWITCHABLE_OUTPUT_NUMBER]})", + title=( + f"{user_input[CONF_NAME]}" + f" ({subconfig_entry.data[CONF_SWITCHABLE_OUTPUT_NUMBER]})" + ), data_updates=user_input, ) diff --git a/homeassistant/components/schedule/__init__.py b/homeassistant/components/schedule/__init__.py index 7fcd2df56fd..3d60c005bd6 100644 --- a/homeassistant/components/schedule/__init__.py +++ b/homeassistant/components/schedule/__init__.py @@ -68,7 +68,8 @@ def valid_schedule(schedule: list[dict[str, str]]) -> list[dict[str, str]]: # Sort the schedule by start times schedule = sorted(schedule, key=lambda time_range: time_range[CONF_FROM]) - # Check if the start time of the next event is before the end time of the previous event + # Check if the start time of the next event is before + # the end time of the previous event previous_to = None for time_range in schedule: if time_range[CONF_FROM] >= time_range[CONF_TO]: @@ -269,7 +270,8 @@ class Schedule(CollectionEntity): self._attr_name = self._config[CONF_NAME] self._attr_unique_id = self._config[CONF_ID] - # Exclude any custom attributes that may be present on time ranges from recording. + # Exclude any custom attributes that may be present + # on time ranges from recording. self._unrecorded_attributes = self.all_custom_data_keys() self._Entity__combined_unrecorded_attributes = ( self._entity_component_unrecorded_attributes | self._unrecorded_attributes diff --git a/homeassistant/components/scrape/__init__.py b/homeassistant/components/scrape/__init__.py index 07838090523..740b80a54e3 100644 --- a/homeassistant/components/scrape/__init__.py +++ b/homeassistant/components/scrape/__init__.py @@ -190,7 +190,8 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ScrapeConfigEntry) -> unique_id=None, ) _LOGGER.debug( - "Migrating sensor %s with unique id %s to sub config entry id %s, old data %s, new data %s", + "Migrating sensor %s with unique id %s to sub config" + " entry id %s, old data %s, new data %s", title, old_unique_id, new_sub_entry.subentry_id, diff --git a/homeassistant/components/scrape/coordinator.py b/homeassistant/components/scrape/coordinator.py index f7bfaee56e4..e594f1ff1b9 100644 --- a/homeassistant/components/scrape/coordinator.py +++ b/homeassistant/components/scrape/coordinator.py @@ -59,7 +59,8 @@ class ScrapeCoordinator(DataUpdateCoordinator[BeautifulSoup]): raise UpdateFailed("REST data is not available") # Detect if content is XML and use appropriate parser - # Check Content-Type header first (most reliable), then fall back to content detection + # Check Content-Type header first (most reliable), + # then fall back to content detection parser = "lxml" headers = self._rest.headers content_type = headers.get("Content-Type", "") if headers else "" @@ -76,7 +77,8 @@ class ScrapeCoordinator(DataUpdateCoordinator[BeautifulSoup]): after_xml_lower = after_xml.lower() is_html = after_xml_lower.startswith((" None: """Handle updated data from the coordinator.""" - # For push entities, only take updates from the coordinator if availability changes. + # For push entities, only take updates from the + # coordinator if availability changes. if self.coordinator.last_update_success != self._last_update_success: self._async_data_updated() diff --git a/homeassistant/components/search/__init__.py b/homeassistant/components/search/__init__.py index 514008aa1e4..214da9aacb1 100644 --- a/homeassistant/components/search/__init__.py +++ b/homeassistant/components/search/__init__.py @@ -135,7 +135,8 @@ class Searcher: # Scripts referencing this area self._add(ItemType.SCRIPT, script.scripts_with_area(self.hass, area_id)) - # Entity in this area, will extend this with the entities of the devices in this area + # Entity in this area, will extend this with + # the entities of the devices in this area entity_entries = er.async_entries_for_area(self._entity_registry, area_id) # Devices in this area diff --git a/homeassistant/components/sensor/__init__.py b/homeassistant/components/sensor/__init__.py index de6e2355c20..9cb3e55bf0a 100644 --- a/homeassistant/components/sensor/__init__.py +++ b/homeassistant/components/sensor/__init__.py @@ -300,7 +300,8 @@ class SensorEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): await super().async_internal_added_to_hass() if self.entity_category == EntityCategory.CONFIG: raise HomeAssistantError( - f"Entity {self.entity_id} cannot be added as the entity category is set to config" + f"Entity {self.entity_id} cannot be added as" + " the entity category is set to config" ) if not self.registry_entry: @@ -417,8 +418,10 @@ class SensorEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): if suggested_unit_of_measurement is None and ( unit_converter := UNIT_CONVERTERS.get(self.device_class) ): - # If the device class is not known by the unit system but has a unit converter, - # fall back to the unit suggested by the unit converter's unit class. + # If the device class is not known by the unit + # system but has a unit converter, fall back to + # the unit suggested by the unit converter's + # unit class. suggested_unit_of_measurement = self.hass.config.units.get_converted_unit( unit_converter.UNIT_CLASS, self.__native_unit_of_measurement_compat ) @@ -458,9 +461,12 @@ class SensorEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): state_class = self.state_class if state_class != SensorStateClass.TOTAL: raise ValueError( - f"Entity {self.entity_id} ({type(self)}) with state_class {state_class}" - " has set last_reset. Setting last_reset for entities with state_class" - " other than 'total' is not supported. Please update your configuration" + f"Entity {self.entity_id} ({type(self)})" + f" with state_class {state_class}" + " has set last_reset. Setting last_reset" + " for entities with state_class" + " other than 'total' is not supported." + " Please update your configuration" " if state_class is manually configured." ) @@ -567,9 +573,13 @@ class SensorEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): ): if native_unit_of_measurement is not None: raise ValueError( - f"Sensor {type(self)} from integration '{self.platform.platform_name}' " - f"has a translation key for unit_of_measurement '{unit_of_measurement}', " - f"but also has a native_unit_of_measurement '{native_unit_of_measurement}'" + f"Sensor {type(self)} from integration" + f" '{self.platform.platform_name}' " + "has a translation key for" + f" unit_of_measurement '{unit_of_measurement}'" + ", but also has a" + " native_unit_of_measurement" + f" '{native_unit_of_measurement}'" ) return unit_of_measurement @@ -654,8 +664,10 @@ class SensorEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): return value.isoformat(timespec="seconds") except (AttributeError, OverflowError, TypeError) as err: raise ValueError( - f"Invalid datetime: {self.entity_id} has {device_class.value} device class " - f"but provides state {value}:{type(value)} resulting in '{err}'" + f"Invalid datetime: {self.entity_id}" + f" has {device_class.value} device class" + f" but provides state {value}:{type(value)}" + f" resulting in '{err}'" ) from err # Received a date value @@ -773,9 +785,12 @@ class SensorEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): and native_unit_of_measurement not in units ): raise ValueError( - f"Sensor {self.entity_id} ({type(self)}) is using native unit of " - f"measurement '{native_unit_of_measurement}' which is not a valid unit " - f"for the state class ('{state_class}') it is using; expected one of {units};" + f"Sensor {self.entity_id} ({type(self)}) is" + " using native unit of measurement" + f" '{native_unit_of_measurement}' which is" + " not a valid unit for the state class" + f" ('{state_class}') it is using;" + f" expected one of {units};" ) return value @@ -794,15 +809,18 @@ class SensorEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): def _get_adjusted_display_precision(self) -> int | None: """Return the display precision for the sensor. - When the integration has specified a suggested display precision, it will be used. - If a unit conversion is needed, the display precision will be adjusted based on - the ratio from the native unit to the current one. + When the integration has specified a suggested display + precision, it will be used. If a unit conversion is needed, + the display precision will be adjusted based on the ratio + from the native unit to the current one. - When the integration does not specify a suggested display precision, a default - device class precision will be used from UNITS_PRECISION, and the final precision - will be adjusted based on the ratio from the default unit to the current one. It - will also be capped so that the extra precision (from the base unit) does not - exceed DEFAULT_PRECISION_LIMIT. + When the integration does not specify a suggested + display precision, a default device class precision will + be used from UNITS_PRECISION, and the final precision + will be adjusted based on the ratio from the default + unit to the current one. It will also be capped so that + the extra precision (from the base unit) does not exceed + DEFAULT_PRECISION_LIMIT. """ display_precision = self.suggested_display_precision device_class = self.device_class diff --git a/homeassistant/components/sensor/const.py b/homeassistant/components/sensor/const.py index b59d32909ee..7878b380ad2 100644 --- a/homeassistant/components/sensor/const.py +++ b/homeassistant/components/sensor/const.py @@ -175,7 +175,8 @@ class SensorDeviceClass(StrEnum): CO = "carbon_monoxide" """Carbon Monoxide gas concentration. - Unit of measurement: `ppb` (parts per billion), `ppm` (parts per million), `mg/m³`, `μg/m³` + Unit of measurement: `ppb` (parts per billion), + `ppm` (parts per million), `mg/m³`, `μg/m³` """ CO2 = "carbon_dioxide" @@ -227,16 +228,20 @@ class SensorDeviceClass(StrEnum): Use this device class for sensors measuring energy consumption, for example electric energy consumption. - Unit of measurement: `J`, `kJ`, `MJ`, `GJ`, `mWh`, `Wh`, `kWh`, `MWh`, `GWh`, `TWh`, `cal`, `kcal`, `Mcal`, `Gcal` + Unit of measurement: `J`, `kJ`, `MJ`, `GJ`, `mWh`, + `Wh`, `kWh`, `MWh`, `GWh`, `TWh`, `cal`, `kcal`, + `Mcal`, `Gcal` """ ENERGY_DISTANCE = "energy_distance" """Energy distance. - Use this device class for sensors measuring energy by distance, for example the amount - of electric energy consumed by an electric car. + Use this device class for sensors measuring energy by + distance, for example the amount of electric energy + consumed by an electric car. - Unit of measurement: `kWh/100km`, `Wh/km`, `mi/kWh`, `km/kWh` + Unit of measurement: `kWh/100km`, `Wh/km`, + `mi/kWh`, `km/kWh` """ ENERGY_STORAGE = "energy_storage" @@ -245,7 +250,9 @@ class SensorDeviceClass(StrEnum): Use this device class for sensors measuring stored energy, for example the amount of electric energy currently stored in a battery or the capacity of a battery. - Unit of measurement: `J`, `kJ`, `MJ`, `GJ`, `mWh`, `Wh`, `kWh`, `MWh`, `GWh`, `TWh`, `cal`, `kcal`, `Mcal`, `Gcal` + Unit of measurement: `J`, `kJ`, `MJ`, `GJ`, `mWh`, + `Wh`, `kWh`, `MWh`, `GWh`, `TWh`, `cal`, `kcal`, + `Mcal`, `Gcal` """ FREQUENCY = "frequency" @@ -464,8 +471,10 @@ class SensorDeviceClass(StrEnum): Unit of measurement: `VOLUME_*` units - SI / metric: `mL`, `L`, `m³` - - USCS / imperial: `ft³`, `CCF`, `MCF`, `fl. oz.`, `gal` (warning: volumes expressed in - USCS/imperial units are currently assumed to be US volumes) + - USCS / imperial: `ft³`, `CCF`, `MCF`, + `fl. oz.`, `gal` (warning: volumes expressed in + USCS/imperial units are currently assumed to be + US volumes) """ VOLUME_STORAGE = "volume_storage" @@ -476,8 +485,10 @@ class SensorDeviceClass(StrEnum): Unit of measurement: `VOLUME_*` units - SI / metric: `mL`, `L`, `m³` - - USCS / imperial: `ft³`, `CCF`, `MCF`, `fl. oz.`, `gal` (warning: volumes expressed in - USCS/imperial units are currently assumed to be US volumes) + - USCS / imperial: `ft³`, `CCF`, `MCF`, + `fl. oz.`, `gal` (warning: volumes expressed in + USCS/imperial units are currently assumed to be + US volumes) """ VOLUME_FLOW_RATE = "volume_flow_rate" @@ -545,7 +556,10 @@ class SensorStateClass(StrEnum): """The state represents a measurement in present time.""" MEASUREMENT_ANGLE = "measurement_angle" - """The state represents a angle measurement in present time. Currently only degrees are supported.""" + """The state represents an angle measurement in present time. + + Currently only degrees are supported. + """ TOTAL = "total" """The state represents a total amount. diff --git a/homeassistant/components/sensor/recorder.py b/homeassistant/components/sensor/recorder.py index 796d876db83..32326022220 100644 --- a/homeassistant/components/sensor/recorder.py +++ b/homeassistant/components/sensor/recorder.py @@ -92,7 +92,8 @@ WARN_NEGATIVE: HassKey[set[str]] = HassKey(f"{DOMAIN}_warn_total_increasing_nega # Keep track of entities for which a warning about unsupported unit has been logged WARN_UNSUPPORTED_UNIT: HassKey[set[str]] = HassKey(f"{DOMAIN}_warn_unsupported_unit") WARN_UNSTABLE_UNIT: HassKey[set[str]] = HassKey(f"{DOMAIN}_warn_unstable_unit") -# Keep track of entities for which a warning about statistics mean algorithm change has been logged +# Keep track of entities for which a warning about +# statistics mean algorithm change has been logged WARN_STATISTICS_MEAN_CHANGED: HassKey[set[str]] = HassKey( f"{DOMAIN}_warn_statistics_mean_change" ) @@ -165,8 +166,8 @@ def _time_weighted_circular_mean( ) -> tuple[float, float]: """Calculate a time weighted circular mean. - The circular mean is calculated by weighting the states by duration in seconds between - state changes. + The circular mean is calculated by weighting the states + by duration in seconds between state changes. Note: there's no interpolation of values between state changes. """ old_fstate: float | None = None @@ -407,11 +408,12 @@ def _suggest_report_issue(hass: HomeAssistant, entity_id: str) -> str: def warn_dip( hass: HomeAssistant, entity_id: str, state: State, previous_fstate: float ) -> None: - """Log a warning once if a sensor with state class TOTAL_INCREASING has a decreasing value. + """Log a warning once if a sensor with TOTAL_INCREASING has a decreasing value. - The log will be suppressed until two dips have been seen to prevent warning due to - rounding issues with databases storing the state as a single precision float, which - was fixed in recorder DB version 20. + The log will be suppressed until two dips have been seen + to prevent warning due to rounding issues with databases + storing the state as a single precision float, which was + fixed in recorder DB version 20. """ if SEEN_DIP not in hass.data: hass.data[SEEN_DIP] = set() @@ -443,7 +445,7 @@ def warn_dip( def warn_negative(hass: HomeAssistant, entity_id: str, state: State) -> None: - """Log a warning once if a sensor with state class TOTAL_INCREASING has a negative value.""" + """Log a warning once if a sensor with TOTAL_INCREASING has a negative value.""" if WARN_NEGATIVE not in hass.data: hass.data[WARN_NEGATIVE] = set() if entity_id not in hass.data[WARN_NEGATIVE]: @@ -662,7 +664,8 @@ def compile_statistics( # noqa: C901 hass.data[WARN_STATISTICS_MEAN_CHANGED].add(entity_id) _LOGGER.warning( ( - "The statistics mean algorithm for %s have changed from %s to %s." + "The statistics mean algorithm for %s have" + " changed from %s to %s." " Generation of long term statistics will be suppressed" " unless it changes back or go to %s to delete the old" " statistics" diff --git a/homeassistant/components/senz/api.py b/homeassistant/components/senz/api.py index 1500f1bf645..b05a2037cec 100644 --- a/homeassistant/components/senz/api.py +++ b/homeassistant/components/senz/api.py @@ -9,7 +9,7 @@ from homeassistant.helpers import config_entry_oauth2_flow class SENZConfigEntryAuth(AbstractSENZAuth): - """Provide nVent RAYCHEM SENZ authentication tied to an OAuth2 based config entry.""" + """Provide nVent RAYCHEM SENZ authentication tied to an OAuth2 config entry.""" def __init__( self, diff --git a/homeassistant/components/sftp_storage/__init__.py b/homeassistant/components/sftp_storage/__init__.py index 9dbc956bdb1..8658c27920f 100644 --- a/homeassistant/components/sftp_storage/__init__.py +++ b/homeassistant/components/sftp_storage/__init__.py @@ -89,7 +89,8 @@ async def async_remove_entry(hass: HomeAssistant, entry: SFTPConfigEntry) -> Non pkey.unlink() except OSError as e: LOGGER.warning( - "Failed to remove private key %s for %s integration for host %s@%s. %s", + "Failed to remove private key %s for %s" + " integration for host %s@%s. %s", pkey.name, DOMAIN, entry.data[CONF_USERNAME], @@ -103,7 +104,9 @@ async def async_remove_entry(hass: HomeAssistant, entry: SFTPConfigEntry) -> Non if e.errno == errno.ENOTEMPTY: # Directory not empty if LOGGER.isEnabledFor(logging.DEBUG): leftover_files = [] - # If we get an exception while gathering leftover files, make sure to log plain message. + # If we get an exception while gathering + # leftover files, make sure to log plain + # message. with contextlib.suppress(OSError): leftover_files = [f.name for f in pkey.parent.iterdir()] @@ -117,7 +120,8 @@ async def async_remove_entry(hass: HomeAssistant, entry: SFTPConfigEntry) -> Non ) else: LOGGER.warning( - "Error occurred while removing directory %s for integration %s: %s at host %s@%s", + "Error occurred while removing directory %s" + " for integration %s: %s at host %s@%s", str(pkey.parent), DOMAIN, str(e), diff --git a/homeassistant/components/sftp_storage/backup.py b/homeassistant/components/sftp_storage/backup.py index e5cacabc6b8..0dfd9ec4fd2 100644 --- a/homeassistant/components/sftp_storage/backup.py +++ b/homeassistant/components/sftp_storage/backup.py @@ -67,7 +67,8 @@ class SFTPBackupAgent(BackupAgent): ) -> AsyncIterator[bytes]: """Download a backup file from SFTP.""" LOGGER.debug( - "Establishing SFTP connection to remote host in order to download backup id: %s", + "Establishing SFTP connection to remote host" + " in order to download backup id: %s", backup_id, ) try: diff --git a/homeassistant/components/sftp_storage/client.py b/homeassistant/components/sftp_storage/client.py index 1ba9960e961..a50df34a251 100644 --- a/homeassistant/components/sftp_storage/client.py +++ b/homeassistant/components/sftp_storage/client.py @@ -30,7 +30,7 @@ if TYPE_CHECKING: def get_client_options(cfg: SFTPConfigEntryData) -> SSHClientConnectionOptions: - """Use this function with `hass.async_add_executor_job` to asynchronously get `SSHClientConnectionOptions`.""" + """Get `SSHClientConnectionOptions` for use with `hass.async_add_executor_job`.""" return SSHClientConnectionOptions( known_hosts=None, @@ -177,7 +177,8 @@ class BackupAgentClient: if not await self.sftp.exists(metadata.file_path): await self.sftp.unlink(metadata.metadata_file) raise FileNotFoundError( - f"File at provided remote location: {metadata.file_path} does not exist." + "File at provided remote location:" + f" {metadata.file_path} does not exist." ) LOGGER.debug("Removing file at path: %s", metadata.file_path) @@ -186,7 +187,7 @@ class BackupAgentClient: await self.sftp.unlink(metadata.metadata_file) async def async_list_backups(self) -> list[AgentBackup]: - """Iterate through a list of metadata files and return a list of `AgentBackup` objects.""" + """Iterate through metadata files and return a list of `AgentBackup` objects.""" backups: list[AgentBackup] = [] @@ -217,7 +218,7 @@ class BackupAgentClient: iterator: AsyncIterator[bytes], backup: AgentBackup, ) -> None: - """Accept `iterator` as bytes iterator and write backup archive to SFTP Server.""" + """Accept `iterator` as bytes iterator and write backup archive.""" file_path = ( f"{self.cfg.runtime_data.backup_location}/{suggested_filename(backup)}" @@ -244,8 +245,10 @@ class BackupAgentClient: async def iter_file(self, backup_id: str) -> AsyncFileIterator: """Return Async File Iterator object. - `SFTPClientFile` object (that would be returned with `sftp.open`) is not an iterator. - So we return custom made class - `AsyncFileIterator` that would allow iteration on file object. + `SFTPClientFile` object (that would be returned with + `sftp.open`) is not an iterator. So we return custom + made class - `AsyncFileIterator` that would allow + iteration on file object. Raises: ------ @@ -294,7 +297,9 @@ class BackupAgentClient: ) except (OSError, PermissionDenied) as e: raise BackupAgentError( - "Failure while attempting to establish SSH connection. Please check SSH credentials and if changed, re-install the integration" + "Failure while attempting to establish SSH" + " connection. Please check SSH credentials" + " and if changed, re-install the integration" ) from e # Configure SFTP Client Connection @@ -303,7 +308,8 @@ class BackupAgentClient: await self.sftp.chdir(self.cfg.runtime_data.backup_location) except (SFTPNoSuchFile, SFTPPermissionDenied) as e: raise BackupAgentError( - "Failed to create SFTP client. Re-installing integration might be required" + "Failed to create SFTP client." + " Re-installing integration might be required" ) from e return self diff --git a/homeassistant/components/sftp_storage/config_flow.py b/homeassistant/components/sftp_storage/config_flow.py index 30683e2eb9d..b6822423371 100644 --- a/homeassistant/components/sftp_storage/config_flow.py +++ b/homeassistant/components/sftp_storage/config_flow.py @@ -58,11 +58,11 @@ class SFTPStorageException(Exception): class SFTPStorageInvalidPrivateKey(SFTPStorageException): - """Exception raised during config flow - when user provided invalid private key file.""" + """Exception raised when user provided invalid private key file.""" class SFTPStorageMissingPasswordOrPkey(SFTPStorageException): - """Exception raised during config flow - when user did not provide password or private key file.""" + """Exception raised when user did not provide password or private key file.""" class SFTPFlowHandler(ConfigFlow, domain=DOMAIN): @@ -85,8 +85,10 @@ class SFTPFlowHandler(ConfigFlow, domain=DOMAIN): Returns: the possibly updated `user_input`. Raises: - - SFTPStorageMissingPasswordOrPkey: Neither password nor private key provided - - SFTPStorageInvalidPrivateKey: The provided private key has an invalid format + - SFTPStorageMissingPasswordOrPkey: Neither password + nor private key provided + - SFTPStorageInvalidPrivateKey: The provided private + key has an invalid format """ # If neither password nor private key is provided, error out; @@ -153,9 +155,11 @@ class SFTPFlowHandler(ConfigFlow, domain=DOMAIN): # - OSError, if host or port are not correct. # - SFTPStorageInvalidPrivateKey, if private key is not valid format. # - asyncssh.misc.PermissionDenied, if credentials are not correct. - # - SFTPStorageMissingPasswordOrPkey, if password and private key are not provided. + # - SFTPStorageMissingPasswordOrPkey, if password + # and private key are not provided. # - asyncssh.sftp.SFTPNoSuchFile, if directory does not exist. - # - asyncssh.sftp.SFTPPermissionDenied, if we don't have access to said directory + # - asyncssh.sftp.SFTPPermissionDenied, + # if we don't have access to said directory async with ( connect( host=user_config.host, diff --git a/homeassistant/components/sharkiq/config_flow.py b/homeassistant/components/sharkiq/config_flow.py index 376e1d8e328..d66d67223f5 100644 --- a/homeassistant/components/sharkiq/config_flow.py +++ b/homeassistant/components/sharkiq/config_flow.py @@ -71,7 +71,9 @@ async def _validate_input( LOGGER.exception("Unexpected exception") LOGGER.error(error) raise UnknownAuth( - "An unknown error occurred. Check your region settings and open an issue on Github if the issue persists." + "An unknown error occurred. Check your region" + " settings and open an issue on GitHub" + " if the issue persists." ) from error # Return info that you want to store in the config entry. diff --git a/homeassistant/components/sharkiq/vacuum.py b/homeassistant/components/sharkiq/vacuum.py index b43f458ccb5..94e0bf82220 100644 --- a/homeassistant/components/sharkiq/vacuum.py +++ b/homeassistant/components/sharkiq/vacuum.py @@ -137,9 +137,10 @@ class SharkVacuumEntity(CoordinatorEntity[SharkIqUpdateCoordinator], StateVacuum def activity(self) -> VacuumActivity | None: """Get the current vacuum state. - NB: Currently, we do not return an error state because they can be very, very stale. - In the app, these are (usually) handled by showing the robot as stopped and sending the - user a notification. + NB: Currently, we do not return an error state + because they can be very, very stale. In the app, + these are (usually) handled by showing the robot as + stopped and sending the user a notification. """ if self.sharkiq.get_property_value(Properties.CHARGING_STATUS): return VacuumActivity.DOCKED diff --git a/homeassistant/components/shelly/config_flow.py b/homeassistant/components/shelly/config_flow.py index 45db3c337df..d81e6926f48 100644 --- a/homeassistant/components/shelly/config_flow.py +++ b/homeassistant/components/shelly/config_flow.py @@ -236,7 +236,8 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN): and isinstance(model_id, int) and (model_name := get_name_from_model_id(model_id)) ): - # Remove spaces from model name (e.g., "Shelly 1 Mini Gen4" -> "Shelly1MiniGen4") + # Remove spaces from model name + # (e.g., "Shelly 1 Mini Gen4" -> "Shelly1MiniGen4") return f"{model_name.replace(' ', '')}-{mac}" return f"Shelly-{mac}" @@ -407,11 +408,13 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN): async def _async_connect_and_get_info( self, host: str, port: int ) -> ConfigFlowResult | None: - """Connect to device, validate, and create entry or return None to continue flow. + """Connect to device, validate, and create entry or return None. - This helper consolidates the common logic between Zeroconf device selection - and manual entry flows. Returns a ConfigFlowResult if the flow should end - (create_entry or abort), or None if the flow should continue (e.g., to credentials). + This helper consolidates the common logic between + Zeroconf device selection and manual entry flows. + Returns a ConfigFlowResult if the flow should end + (create_entry or abort), or None if the flow should + continue (e.g., to credentials). Sets self.info, self.host, and self.port on success. """ @@ -685,7 +688,7 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN): await self._async_discovered_mac(mac, host) async def _async_discovered_mac(self, mac: str, host: str) -> None: - """Abort and reconnect soon if the device with the mac address is already configured.""" + """Abort and reconnect soon if the device with the mac is already configured.""" if ( current_entry := await self.async_set_unique_id(mac) ) and current_entry.data.get(CONF_HOST) == host: @@ -914,7 +917,8 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN): ) -> ConfigFlowResult | None: """Provision WiFi credentials via BLE and wait for zeroconf discovery. - Returns the flow result to be stored in self._provision_result, or None if failed. + Returns the flow result to be stored in + self._provision_result, or None if failed. """ # Provision WiFi via BLE using persistent connection try: @@ -974,7 +978,8 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN): state.port = DEFAULT_HTTP_PORT else: LOGGER.debug("BLE fallback also failed - provisioning unsuccessful") - # Store failure info and return None - provision_done will handle redirect + # Store failure info and return None + # provision_done will handle redirect return None else: state.host, state.port = result diff --git a/homeassistant/components/shelly/coordinator.py b/homeassistant/components/shelly/coordinator.py index 1a47955f23b..8b4578f0e1f 100644 --- a/homeassistant/components/shelly/coordinator.py +++ b/homeassistant/components/shelly/coordinator.py @@ -122,8 +122,9 @@ class ShellyCoordinatorBase[_DeviceT: BlockDevice | RpcDevice]( self.suggested_area: str | None = None device_name = device.name if device.initialized else entry.title interval_td = timedelta(seconds=update_interval) - # The device has come online at least once. In the case of a sleeping RPC - # device, this means that the device has connected to the WS server at least once. + # The device has come online at least once. In the case + # of a sleeping RPC device, this means that the device + # has connected to the WS server at least once. self._came_online_once = False super().__init__( hass, diff --git a/homeassistant/components/shelly/event.py b/homeassistant/components/shelly/event.py index 13fa37359a1..39f3bd77969 100644 --- a/homeassistant/components/shelly/event.py +++ b/homeassistant/components/shelly/event.py @@ -163,7 +163,8 @@ def _async_setup_rpc_entry( ShellyRpcScriptEvent(coordinator, script, SCRIPT_EVENT, event_types) ) - # If a script is removed, from the device configuration, we need to remove orphaned entities + # If a script is removed, from the device configuration, + # we need to remove orphaned entities async_remove_orphaned_entities( hass, config_entry.entry_id, diff --git a/homeassistant/components/shelly/logbook.py b/homeassistant/components/shelly/logbook.py index 1a3f1ef044b..870f82d9ce4 100644 --- a/homeassistant/components/shelly/logbook.py +++ b/homeassistant/components/shelly/logbook.py @@ -41,7 +41,10 @@ def async_describe_events( rpc_coordinator = get_rpc_coordinator_by_device_id(hass, device_id) if rpc_coordinator and rpc_coordinator.device.initialized: key = f"input:{channel - 1}" - input_name = f"{rpc_coordinator.device.name} {get_rpc_channel_name(rpc_coordinator.device, key)}" + input_name = ( + f"{rpc_coordinator.device.name}" + f" {get_rpc_channel_name(rpc_coordinator.device, key)}" + ) elif click_type in BLOCK_INPUTS_EVENTS_TYPES: block_coordinator = get_block_coordinator_by_device_id(hass, device_id) diff --git a/homeassistant/components/shopping_list/intent.py b/homeassistant/components/shopping_list/intent.py index 96764dc30d4..13d133ee5b9 100644 --- a/homeassistant/components/shopping_list/intent.py +++ b/homeassistant/components/shopping_list/intent.py @@ -83,6 +83,8 @@ class ListTopItemsIntent(intent.IntentHandler): else: items_list = ", ".join(str(itm["name"]) for itm in reversed(items)) response.async_set_speech( - f"These are the top {min(len(items), 5)} items on your shopping list: {items_list}" + "These are the top" + f" {min(len(items), 5)} items on your" + f" shopping list: {items_list}" ) return response diff --git a/homeassistant/components/sia/config_flow.py b/homeassistant/components/sia/config_flow.py index 136369f2087..d15961243b5 100644 --- a/homeassistant/components/sia/config_flow.py +++ b/homeassistant/components/sia/config_flow.py @@ -132,7 +132,7 @@ class SIAConfigFlow(ConfigFlow, domain=DOMAIN): async def async_handle_data_and_route( self, user_input: dict[str, Any] ) -> ConfigFlowResult: - """Handle the user_input, check if configured and route to the right next step or create entry.""" + """Handle user_input, check if configured and route to the right next step.""" self._update_data(user_input) self._async_abort_entries_match({CONF_PORT: self._data[CONF_PORT]}) @@ -148,7 +148,8 @@ class SIAConfigFlow(ConfigFlow, domain=DOMAIN): def _update_data(self, user_input: dict[str, Any]) -> None: """Parse the user_input and store in data and options attributes. - If there is a port in the input or no data, assume it is fully new and overwrite. + If there is a port in the input or no data, assume + it is fully new and overwrite. Add the default options and overwrite the zones in options. """ if not self._data or user_input.get(CONF_PORT): diff --git a/homeassistant/components/sia/entity.py b/homeassistant/components/sia/entity.py index 88aff7728f1..e0c8ded61be 100644 --- a/homeassistant/components/sia/entity.py +++ b/homeassistant/components/sia/entity.py @@ -116,7 +116,7 @@ class SIABaseEntity(RestoreEntity): @callback def async_handle_event(self, sia_event: SIAEvent) -> None: - """Listen to dispatcher events for this port and account and update state and attributes. + """Listen to dispatcher events for this port and account, update state. If the event is for either the zone or the 0 zone (hub zone), then handle it further. diff --git a/homeassistant/components/sia/hub.py b/homeassistant/components/sia/hub.py index c4d056314c5..1a59270313f 100644 --- a/homeassistant/components/sia/hub.py +++ b/homeassistant/components/sia/hub.py @@ -51,7 +51,7 @@ class SIAHub: @callback def async_setup_hub(self) -> None: - """Add a device to the device_registry, register shutdown listener, load reactions.""" + """Add a device to the device_registry, register shutdown listener.""" self.update_accounts() device_registry = dr.async_get(self._hass) for acc in self._accounts: @@ -74,10 +74,14 @@ class SIAHub: await self.sia_client.async_stop() async def async_create_and_fire_event(self, event: SIAEvent) -> None: - """Create a event on HA dispatcher and then on HA's bus, with the data from the SIAEvent. - - The created event is handled by default for only a small subset for each platform (there are about 320 SIA Codes defined, only 22 of those are used in the alarm_control_panel), a user can choose to build other automation or even entities on the same event for SIA codes not handled by the built-in platforms. + """Create an event on HA dispatcher and then on HA's bus. + The created event is handled by default for only a + small subset for each platform (there are about 320 + SIA Codes defined, only 22 of those are used in the + alarm_control_panel), a user can choose to build other + automation or even entities on the same event for SIA + codes not handled by the built-in platforms. """ _LOGGER.debug( "Adding event to dispatch and bus for code %s for port %s and account %s", @@ -109,7 +113,8 @@ class SIAHub: if self.sia_client is not None: self.sia_client.accounts = self.sia_accounts return - # the new client class method creates a subclass based on protocol, hence the type ignore + # the new client class method creates a subclass + # based on protocol, hence the type ignore self.sia_client = SIAClient( host="", port=self._port, @@ -119,7 +124,7 @@ class SIAHub: ) def _load_options(self) -> None: - """Store attributes to avoid property call overhead since they are called frequently.""" + """Store attributes to avoid property call overhead.""" options = dict(self._entry.options) for acc in self._accounts: acc_id = acc[CONF_ACCOUNT] @@ -135,9 +140,10 @@ class SIAHub: ) -> None: """Handle signals of config entry being updated. - First, update the accounts, this will reflect any changes with ignore_timestamps. - Second, unload underlying platforms, and then setup platforms, this reflects any changes in number of zones. - + First, update the accounts, this will reflect any + changes with ignore_timestamps. Second, unload + underlying platforms, and then setup platforms, this + reflects any changes in number of zones. """ if config_entry.state != ConfigEntryState.LOADED: return diff --git a/homeassistant/components/signal_messenger/notify.py b/homeassistant/components/signal_messenger/notify.py index 5c54a4b3d2b..d690d0d0d5d 100644 --- a/homeassistant/components/signal_messenger/notify.py +++ b/homeassistant/components/signal_messenger/notify.py @@ -97,7 +97,7 @@ class SignalNotificationService(BaseNotificationService): self._signal_cli_rest_api = signal_cli_rest_api def send_message(self, message: str = "", **kwargs: Any) -> None: - """Send a message to one or more recipients. Additionally a file can be attached.""" + """Send a message to one or more recipients.""" _LOGGER.debug("Sending signal message") diff --git a/homeassistant/components/simplefin/coordinator.py b/homeassistant/components/simplefin/coordinator.py index 97ffd3d02fc..cb22490b7e0 100644 --- a/homeassistant/components/simplefin/coordinator.py +++ b/homeassistant/components/simplefin/coordinator.py @@ -43,6 +43,8 @@ class SimpleFinDataUpdateCoordinator(DataUpdateCoordinator[FinancialData]): except SimpleFinPaymentRequiredError as err: LOGGER.warning( - "There is a billing issue with your SimpleFin account, contact Simplefin to address this issue" + "There is a billing issue with your SimpleFin" + " account, contact SimpleFin to address" + " this issue" ) raise UpdateFailed from err diff --git a/homeassistant/components/slack/notify.py b/homeassistant/components/slack/notify.py index 87a10e8cbbe..76c19e81752 100644 --- a/homeassistant/components/slack/notify.py +++ b/homeassistant/components/slack/notify.py @@ -350,8 +350,11 @@ class SlackNotificationService(BaseNotificationService): channel_name = channel_name.lstrip("#") # Get channel list - # Multiple types is not working. Tested here: https://api.slack.com/methods/conversations.list/test - # response = await self._client.conversations_list(types="public_channel,private_channel") + # Multiple types is not working. Tested here: + # https://api.slack.com/methods/conversations.list/test + # response = await self._client.conversations_list( + # types="public_channel,private_channel" + # ) # # Workaround for the types parameter not working channels = [] diff --git a/homeassistant/components/slack/utils.py b/homeassistant/components/slack/utils.py index 7619d7d265f..453508c6586 100644 --- a/homeassistant/components/slack/utils.py +++ b/homeassistant/components/slack/utils.py @@ -24,12 +24,14 @@ async def upload_file_to_slack( Args: client (AsyncWebClient): The Slack WebClient instance. channel_ids (list[str | None]): List of channel IDs to upload the file to. - file_content (Union[bytes, str, None]): Content of the file (local or remote). If None, file_path is used. + file_content (Union[bytes, str, None]): Content of the + file (local or remote). If None, file_path is used. filename (str): The file's name. title (str | None): Title of the file in Slack. message (str): Initial comment to accompany the file. thread_ts (str | None): Thread timestamp for threading messages. - file_path (str | None): Path to the local file to be read if file_content is None. + file_path (str | None): Path to the local file to be + read if file_content is None. Raises: SlackApiError: If the Slack API call fails. diff --git a/homeassistant/components/sleepiq/number.py b/homeassistant/components/sleepiq/number.py index cd2afcbb193..b3de19dfabb 100644 --- a/homeassistant/components/sleepiq/number.py +++ b/homeassistant/components/sleepiq/number.py @@ -59,7 +59,9 @@ def _get_actuator_name(bed: SleepIQBed, actuator: SleepIQActuator) -> str: if actuator.side: return ( "SleepNumber" - f" {bed.name} {actuator.side_full} {actuator.actuator_full} {ENTITY_TYPES[ACTUATOR]}" + f" {bed.name} {actuator.side_full}" + f" {actuator.actuator_full}" + f" {ENTITY_TYPES[ACTUATOR]}" ) return f"SleepNumber {bed.name} {actuator.actuator_full} {ENTITY_TYPES[ACTUATOR]}" diff --git a/homeassistant/components/slide_local/coordinator.py b/homeassistant/components/slide_local/coordinator.py index 5c465da70a5..0a8a27be4d4 100644 --- a/homeassistant/components/slide_local/coordinator.py +++ b/homeassistant/components/slide_local/coordinator.py @@ -100,7 +100,8 @@ class SlideCoordinator(DataUpdateCoordinator[dict[str, Any]]): if not self.config_entry.options.get(CONF_INVERT_POSITION, False): # For slide 0->open, 1->closed; for HA 0->closed, 1->open - # Value has therefore to be inverted, unless CONF_INVERT_POSITION is true + # Value has therefore to be inverted, + # unless CONF_INVERT_POSITION is true data["pos"] = 1 - data["pos"] if oldpos is None or oldpos == data["pos"]: diff --git a/homeassistant/components/sma/config_flow.py b/homeassistant/components/sma/config_flow.py index abb64a52cf4..117ce0efdfb 100644 --- a/homeassistant/components/sma/config_flow.py +++ b/homeassistant/components/sma/config_flow.py @@ -255,7 +255,8 @@ class SmaConfigFlow(ConfigFlow, domain=DOMAIN): entry, data_updates={CONF_MAC: self._data[CONF_MAC]} ) - # Finally, check if the hostname (which represents the SMA serial number) is unique + # Finally, check if the hostname + # (which represents the SMA serial number) is unique serial_number = discovery_info.hostname.lower() # Example hostname: sma12345678-01 # Remove 'sma' prefix and strip everything after the dash (including the dash) diff --git a/homeassistant/components/smappee/config_flow.py b/homeassistant/components/smappee/config_flow.py index 01b69a76b28..01b9c9193fa 100644 --- a/homeassistant/components/smappee/config_flow.py +++ b/homeassistant/components/smappee/config_flow.py @@ -135,7 +135,8 @@ class SmappeeFlowHandler( errors={}, ) - # Environment chosen, request additional host information for LOCAL or OAuth2 flow for CLOUD + # Environment chosen, request additional host information + # for LOCAL or OAuth2 flow for CLOUD # Ask for host detail if user_input["environment"] == ENV_LOCAL: return await self.async_step_local() @@ -160,7 +161,8 @@ class SmappeeFlowHandler( ip_address = user_input["host"] serial_number = None - # Attempt 1: try to use the local api (older generation) to resolve host to serialnumber + # Attempt 1: try to use the local api (older generation) + # to resolve host to serialnumber smappee_api = api.api.SmappeeLocalApi(ip=ip_address) logon = await self.hass.async_add_executor_job(smappee_api.logon) if logon is not None: @@ -171,7 +173,8 @@ class SmappeeFlowHandler( if config_item["key"] == "mdnsHostName": serial_number = config_item["value"] else: - # Attempt 2: try to use the local mqtt broker (newer generation) to resolve host to serialnumber + # Attempt 2: try to use the local mqtt broker + # (newer generation) to resolve host to serialnumber smappee_mqtt = mqtt.SmappeeLocalMqtt() connect = await self.hass.async_add_executor_job(smappee_mqtt.start_attempt) if not connect: diff --git a/homeassistant/components/smartthings/__init__.py b/homeassistant/components/smartthings/__init__.py index bba87d3afa8..82d8e751498 100644 --- a/homeassistant/components/smartthings/__init__.py +++ b/homeassistant/components/smartthings/__init__.py @@ -156,7 +156,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: SmartThingsConfigEntry) def _handle_max_connections() -> None: _LOGGER.debug( - "We hit the limit of max connections or we could not remove the old one, so retrying" + "We hit the limit of max connections or we could" + " not remove the old one, so retrying" ) hass.config_entries.async_schedule_reload(entry.entry_id) @@ -335,7 +336,8 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Handle config entry migration.""" if entry.version < 3: - # We keep the old data around, so we can use that to clean up the webhook in the future + # We keep the old data around, so we can use that + # to clean up the webhook in the future hass.config_entries.async_update_entry( entry, version=3, data={OLD_DATA: dict(entry.data)} ) @@ -377,7 +379,12 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: "energySaved_meter", }: return { - "new_unique_id": f"{device_id}_{MAIN}_{Capability.POWER_CONSUMPTION_REPORT}_{Attribute.POWER_CONSUMPTION}_{attribute}", + "new_unique_id": ( + f"{device_id}_{MAIN}" + f"_{Capability.POWER_CONSUMPTION_REPORT}" + f"_{Attribute.POWER_CONSUMPTION}" + f"_{attribute}" + ), } if attribute in { "X Coordinate", @@ -390,7 +397,12 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: "Z Coordinate": "z_coordinate", }[attribute] return { - "new_unique_id": f"{device_id}_{MAIN}_{Capability.THREE_AXIS}_{Attribute.THREE_AXIS}_{new_attribute}", + "new_unique_id": ( + f"{device_id}_{MAIN}" + f"_{Capability.THREE_AXIS}" + f"_{Attribute.THREE_AXIS}" + f"_{new_attribute}" + ), } if attribute in { Attribute.MACHINE_STATE, @@ -402,16 +414,27 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: if capability is None: return None return { - "new_unique_id": f"{device_id}_{MAIN}_{capability}_{attribute}_{attribute}", + "new_unique_id": ( + f"{device_id}_{MAIN}" + f"_{capability}" + f"_{attribute}_{attribute}" + ), } return None return { - "new_unique_id": f"{device_id}_{MAIN}_{capability}_{attribute}_{attribute}", + "new_unique_id": ( + f"{device_id}_{MAIN}_{capability}_{attribute}_{attribute}" + ), } if entity_entry.domain == "switch": return { - "new_unique_id": f"{entity_entry.unique_id}_{MAIN}_{Capability.SWITCH}_{Attribute.SWITCH}_{Attribute.SWITCH}", + "new_unique_id": ( + f"{entity_entry.unique_id}_{MAIN}" + f"_{Capability.SWITCH}" + f"_{Attribute.SWITCH}" + f"_{Attribute.SWITCH}" + ), } return None diff --git a/homeassistant/components/smartthings/binary_sensor.py b/homeassistant/components/smartthings/binary_sensor.py index 825473b3006..30a6bb8168e 100644 --- a/homeassistant/components/smartthings/binary_sensor.py +++ b/homeassistant/components/smartthings/binary_sensor.py @@ -328,7 +328,10 @@ class SmartThingsBinarySensor(SmartThingsEntity, BinarySensorEntity): self._attribute = attribute self.capability = capability self.entity_description = entity_description - self._attr_unique_id = f"{device.device.device_id}_{component}_{capability}_{attribute}_{attribute}" + self._attr_unique_id = ( + f"{device.device.device_id}_{component}" + f"_{capability}_{attribute}_{attribute}" + ) if ( entity_description.category_device_class and (category := get_main_component_category(device)) diff --git a/homeassistant/components/smartthings/button.py b/homeassistant/components/smartthings/button.py index d743c46fc16..e2cbbefaa23 100644 --- a/homeassistant/components/smartthings/button.py +++ b/homeassistant/components/smartthings/button.py @@ -167,7 +167,11 @@ class SmartThingsButtonEntity(SmartThingsEntity, ButtonEntity): super().__init__(client, device, capabilities) self.entity_description = entity_description self.button_capability = capability - self._attr_unique_id = f"{device.device.device_id}_{component}_{entity_description.key}_{entity_description.command}" + self._attr_unique_id = ( + f"{device.device.device_id}_{component}" + f"_{entity_description.key}" + f"_{entity_description.command}" + ) if entity_description.command_identifier is not None: self._attr_unique_id += f"_{entity_description.command_identifier}" diff --git a/homeassistant/components/smartthings/climate.py b/homeassistant/components/smartthings/climate.py index 2d7f8c00387..f5a88679e69 100644 --- a/homeassistant/components/smartthings/climate.py +++ b/homeassistant/components/smartthings/climate.py @@ -434,8 +434,9 @@ class SmartThingsAirConditioner(SmartThingsEntity, ClimateEntity): tasks.append(self.async_turn_on()) mode = STATE_TO_AC_MODE[hvac_mode] - # If new hvac_mode is HVAC_MODE_FAN_ONLY and AirConditioner support "wind" or "fan" mode the AirConditioner - # new mode has to be "wind" or "fan" + # If new hvac_mode is HVAC_MODE_FAN_ONLY and + # AirConditioner supports "wind" or "fan" mode, + # the AirConditioner new mode has to be "wind" or "fan" if hvac_mode == HVACMode.FAN_ONLY: for fan_mode in (WIND, FAN): if fan_mode in self.get_attribute_value( diff --git a/homeassistant/components/smartthings/const.py b/homeassistant/components/smartthings/const.py index 1925d973ef4..5d0edcdf04b 100644 --- a/homeassistant/components/smartthings/const.py +++ b/homeassistant/components/smartthings/const.py @@ -69,7 +69,9 @@ SENSOR_ATTRIBUTES_TO_CAPABILITIES: dict[str, str] = { Attribute.DUST_LEVEL: Capability.DUST_SENSOR, Attribute.FINE_DUST_LEVEL: Capability.DUST_SENSOR, Attribute.ENERGY: Capability.ENERGY_METER, - Attribute.EQUIVALENT_CARBON_DIOXIDE_MEASUREMENT: Capability.EQUIVALENT_CARBON_DIOXIDE_MEASUREMENT, + Attribute.EQUIVALENT_CARBON_DIOXIDE_MEASUREMENT: ( + Capability.EQUIVALENT_CARBON_DIOXIDE_MEASUREMENT + ), Attribute.FORMALDEHYDE_LEVEL: Capability.FORMALDEHYDE_MEASUREMENT, Attribute.GAS_METER: Capability.GAS_METER, Attribute.GAS_METER_CALORIFIC: Capability.GAS_METER, diff --git a/homeassistant/components/smartthings/number.py b/homeassistant/components/smartthings/number.py index 0943891c1fa..b181fa16c68 100644 --- a/homeassistant/components/smartthings/number.py +++ b/homeassistant/components/smartthings/number.py @@ -60,7 +60,12 @@ class SmartThingsWasherRinseCyclesNumberEntity(SmartThingsEntity, NumberEntity): def __init__(self, client: SmartThings, device: FullDevice) -> None: """Initialize the instance.""" super().__init__(client, device, {Capability.CUSTOM_WASHER_RINSE_CYCLES}) - self._attr_unique_id = f"{device.device.device_id}_{MAIN}_{Capability.CUSTOM_WASHER_RINSE_CYCLES}_{Attribute.WASHER_RINSE_CYCLES}_{Attribute.WASHER_RINSE_CYCLES}" + self._attr_unique_id = ( + f"{device.device.device_id}_{MAIN}" + f"_{Capability.CUSTOM_WASHER_RINSE_CYCLES}" + f"_{Attribute.WASHER_RINSE_CYCLES}" + f"_{Attribute.WASHER_RINSE_CYCLES}" + ) @property def options(self) -> list[int]: @@ -112,7 +117,12 @@ class SmartThingsHoodNumberEntity(SmartThingsEntity, NumberEntity): super().__init__( client, device, {Capability.SAMSUNG_CE_HOOD_FAN_SPEED}, component="hood" ) - self._attr_unique_id = f"{device.device.device_id}_hood_{Capability.SAMSUNG_CE_HOOD_FAN_SPEED}_{Attribute.HOOD_FAN_SPEED}_{Attribute.HOOD_FAN_SPEED}" + self._attr_unique_id = ( + f"{device.device.device_id}_hood" + f"_{Capability.SAMSUNG_CE_HOOD_FAN_SPEED}" + f"_{Attribute.HOOD_FAN_SPEED}" + f"_{Attribute.HOOD_FAN_SPEED}" + ) @property def options(self) -> list[int]: @@ -169,7 +179,12 @@ class SmartThingsRefrigeratorTemperatureNumberEntity(SmartThingsEntity, NumberEn {Capability.THERMOSTAT_COOLING_SETPOINT}, component=component, ) - self._attr_unique_id = f"{device.device.device_id}_{component}_{Capability.THERMOSTAT_COOLING_SETPOINT}_{Attribute.COOLING_SETPOINT}_{Attribute.COOLING_SETPOINT}" + self._attr_unique_id = ( + f"{device.device.device_id}_{component}" + f"_{Capability.THERMOSTAT_COOLING_SETPOINT}" + f"_{Attribute.COOLING_SETPOINT}" + f"_{Attribute.COOLING_SETPOINT}" + ) unit = self._internal_state[Capability.THERMOSTAT_COOLING_SETPOINT][ Attribute.COOLING_SETPOINT ].unit diff --git a/homeassistant/components/smartthings/select.py b/homeassistant/components/smartthings/select.py index 3fd9a006aab..903a44a9426 100644 --- a/homeassistant/components/smartthings/select.py +++ b/homeassistant/components/smartthings/select.py @@ -165,13 +165,15 @@ CAPABILITIES_TO_SELECT: dict[Capability | str, SmartThingsSelectDescription] = { command=Command.SET_AMOUNT, entity_category=EntityCategory.CONFIG, ), - Capability.SAMSUNG_CE_FLEXIBLE_AUTO_DISPENSE_DETERGENT: SmartThingsSelectDescription( - key=Capability.SAMSUNG_CE_FLEXIBLE_AUTO_DISPENSE_DETERGENT, - translation_key="flexible_detergent_amount", - options_attribute=Attribute.SUPPORTED_AMOUNT, - status_attribute=Attribute.AMOUNT, - command=Command.SET_AMOUNT, - entity_category=EntityCategory.CONFIG, + Capability.SAMSUNG_CE_FLEXIBLE_AUTO_DISPENSE_DETERGENT: ( + SmartThingsSelectDescription( + key=Capability.SAMSUNG_CE_FLEXIBLE_AUTO_DISPENSE_DETERGENT, + translation_key="flexible_detergent_amount", + options_attribute=Attribute.SUPPORTED_AMOUNT, + status_attribute=Attribute.AMOUNT, + command=Command.SET_AMOUNT, + entity_category=EntityCategory.CONFIG, + ) ), Capability.SAMSUNG_CE_LAMP: SmartThingsSelectDescription( key=Capability.SAMSUNG_CE_LAMP, @@ -361,7 +363,12 @@ class SmartThingsSelectEntity(SmartThingsEntity, SelectEntity): capabilities.update(extra_capabilities) super().__init__(client, device, capabilities, component=component) self.entity_description = entity_description - self._attr_unique_id = f"{device.device.device_id}_{component}_{entity_description.key}_{entity_description.status_attribute}_{entity_description.status_attribute}" + self._attr_unique_id = ( + f"{device.device.device_id}_{component}" + f"_{entity_description.key}" + f"_{entity_description.status_attribute}" + f"_{entity_description.status_attribute}" + ) @property def options(self) -> list[str]: diff --git a/homeassistant/components/smartthings/sensor.py b/homeassistant/components/smartthings/sensor.py index 0595cf20093..b86bf439010 100644 --- a/homeassistant/components/smartthings/sensor.py +++ b/homeassistant/components/smartthings/sensor.py @@ -1319,7 +1319,9 @@ async def async_setup_entry( capability in device.status[MAIN] for capability in capability_list ) - for capability_list in description.capability_ignore_list + for capability_list in ( + description.capability_ignore_list + ) ) ) and ( @@ -1401,7 +1403,11 @@ class SmartThingsSensor(SmartThingsEntity, SensorEntity): if entity_description.use_temperature_unit: capabilities_to_subscribe.add(Capability.TEMPERATURE_MEASUREMENT) super().__init__(client, device, capabilities_to_subscribe, component=component) - self._attr_unique_id = f"{device.device.device_id}_{component}_{capability}_{attribute}_{entity_description.key}" + self._attr_unique_id = ( + f"{device.device.device_id}_{component}" + f"_{capability}_{attribute}" + f"_{entity_description.key}" + ) self._attribute = attribute self.capability = capability self.entity_description = entity_description diff --git a/homeassistant/components/smartthings/switch.py b/homeassistant/components/smartthings/switch.py index 67a3ef2b684..39e90bdb3e0 100644 --- a/homeassistant/components/smartthings/switch.py +++ b/homeassistant/components/smartthings/switch.py @@ -85,12 +85,14 @@ CAPABILITY_TO_COMMAND_SWITCHES: dict[ command=Command.SET_SPI_MODE, entity_category=EntityCategory.CONFIG, ), - Capability.SAMSUNG_CE_AIR_CONDITIONER_LIGHTING: SmartThingsCommandSwitchEntityDescription( - key=Capability.SAMSUNG_CE_AIR_CONDITIONER_LIGHTING, - translation_key="display_lighting", - status_attribute=Attribute.LIGHTING, - command=Command.SET_LIGHTING_LEVEL, - entity_category=EntityCategory.CONFIG, + Capability.SAMSUNG_CE_AIR_CONDITIONER_LIGHTING: ( + SmartThingsCommandSwitchEntityDescription( + key=Capability.SAMSUNG_CE_AIR_CONDITIONER_LIGHTING, + translation_key="display_lighting", + status_attribute=Attribute.LIGHTING, + command=Command.SET_LIGHTING_LEVEL, + entity_category=EntityCategory.CONFIG, + ) ), Capability.CUSTOM_DRYER_WRINKLE_PREVENT: SmartThingsCommandSwitchEntityDescription( key=Capability.CUSTOM_DRYER_WRINKLE_PREVENT, @@ -99,21 +101,25 @@ CAPABILITY_TO_COMMAND_SWITCHES: dict[ command=Command.SET_DRYER_WRINKLE_PREVENT, entity_category=EntityCategory.CONFIG, ), - Capability.SAMSUNG_CE_STEAM_CLOSET_AUTO_CYCLE_LINK: SmartThingsCommandSwitchEntityDescription( - key=Capability.SAMSUNG_CE_STEAM_CLOSET_AUTO_CYCLE_LINK, - translation_key="auto_cycle_link", - status_attribute=Attribute.STEAM_CLOSET_AUTO_CYCLE_LINK, - command=Command.SET_STEAM_CLOSET_AUTO_CYCLE_LINK, - entity_category=EntityCategory.CONFIG, + Capability.SAMSUNG_CE_STEAM_CLOSET_AUTO_CYCLE_LINK: ( + SmartThingsCommandSwitchEntityDescription( + key=Capability.SAMSUNG_CE_STEAM_CLOSET_AUTO_CYCLE_LINK, + translation_key="auto_cycle_link", + status_attribute=Attribute.STEAM_CLOSET_AUTO_CYCLE_LINK, + command=Command.SET_STEAM_CLOSET_AUTO_CYCLE_LINK, + entity_category=EntityCategory.CONFIG, + ) ), - Capability.SAMSUNG_CE_MICROFIBER_FILTER_SETTINGS: SmartThingsCommandSwitchEntityDescription( - key=Capability.SAMSUNG_CE_MICROFIBER_FILTER_SETTINGS, - translation_key="bypass_mode", - status_attribute=Attribute.BYPASS_MODE, - entity_category=EntityCategory.CONFIG, - on_key="enabled", - off_key="disabled", - command=Command.SET_BYPASS_MODE, + Capability.SAMSUNG_CE_MICROFIBER_FILTER_SETTINGS: ( + SmartThingsCommandSwitchEntityDescription( + key=Capability.SAMSUNG_CE_MICROFIBER_FILTER_SETTINGS, + translation_key="bypass_mode", + status_attribute=Attribute.BYPASS_MODE, + entity_category=EntityCategory.CONFIG, + on_key="enabled", + off_key="disabled", + command=Command.SET_BYPASS_MODE, + ) ), } CAPABILITY_TO_SWITCHES: dict[Capability | str, SmartThingsSwitchEntityDescription] = { @@ -164,17 +170,21 @@ CAPABILITY_TO_SWITCHES: dict[Capability | str, SmartThingsSwitchEntityDescriptio off_command=Command.DEACTIVATE, entity_category=EntityCategory.CONFIG, ), - Capability.SAMSUNG_CE_STEAM_CLOSET_SANITIZE_MODE: SmartThingsSwitchEntityDescription( - key=Capability.SAMSUNG_CE_STEAM_CLOSET_SANITIZE_MODE, - translation_key="sanitize", - status_attribute=Attribute.STATUS, - entity_category=EntityCategory.CONFIG, + Capability.SAMSUNG_CE_STEAM_CLOSET_SANITIZE_MODE: ( + SmartThingsSwitchEntityDescription( + key=Capability.SAMSUNG_CE_STEAM_CLOSET_SANITIZE_MODE, + translation_key="sanitize", + status_attribute=Attribute.STATUS, + entity_category=EntityCategory.CONFIG, + ) ), - Capability.SAMSUNG_CE_STEAM_CLOSET_KEEP_FRESH_MODE: SmartThingsSwitchEntityDescription( - key=Capability.SAMSUNG_CE_STEAM_CLOSET_KEEP_FRESH_MODE, - translation_key="keep_fresh_mode", - status_attribute=Attribute.STATUS, - entity_category=EntityCategory.CONFIG, + Capability.SAMSUNG_CE_STEAM_CLOSET_KEEP_FRESH_MODE: ( + SmartThingsSwitchEntityDescription( + key=Capability.SAMSUNG_CE_STEAM_CLOSET_KEEP_FRESH_MODE, + translation_key="keep_fresh_mode", + status_attribute=Attribute.STATUS, + entity_category=EntityCategory.CONFIG, + ) ), Capability.CUSTOM_DO_NOT_DISTURB_MODE: SmartThingsSwitchEntityDescription( key=Capability.CUSTOM_DO_NOT_DISTURB_MODE, @@ -193,13 +203,15 @@ CAPABILITY_TO_SWITCHES: dict[Capability | str, SmartThingsSwitchEntityDescriptio on_command=Command.ENABLE_SOUND_DETECTION, off_command=Command.DISABLE_SOUND_DETECTION, ), - Capability.SAMSUNG_CE_STICK_CLEANER_DUSTBIN_STATUS: SmartThingsSwitchEntityDescription( - key=Capability.SAMSUNG_CE_STICK_CLEANER_DUSTBIN_STATUS, - translation_key="empty_dustbin", - status_attribute=Attribute.OPERATING_STATE, - on_key="emptying", - on_command=Command.START_EMPTYING, - off_command=Command.STOP_EMPTYING, + Capability.SAMSUNG_CE_STICK_CLEANER_DUSTBIN_STATUS: ( + SmartThingsSwitchEntityDescription( + key=Capability.SAMSUNG_CE_STICK_CLEANER_DUSTBIN_STATUS, + translation_key="empty_dustbin", + status_attribute=Attribute.OPERATING_STATE, + on_key="emptying", + on_command=Command.START_EMPTYING, + off_command=Command.STOP_EMPTYING, + ) ), } DISHWASHER_WASHING_OPTIONS_TO_SWITCHES: dict[ @@ -261,12 +273,14 @@ DISHWASHER_WASHING_OPTIONS_TO_SWITCHES: dict[ command=Command.SET_SANITIZE, entity_category=EntityCategory.CONFIG, ), - Attribute.SANITIZING_WASH: SmartThingsDishwasherWashingOptionSwitchEntityDescription( - key=Attribute.SANITIZING_WASH, - translation_key="sanitizing_wash", - status_attribute=Attribute.SANITIZING_WASH, - command=Command.SET_SANITIZING_WASH, - entity_category=EntityCategory.CONFIG, + Attribute.SANITIZING_WASH: ( + SmartThingsDishwasherWashingOptionSwitchEntityDescription( + key=Attribute.SANITIZING_WASH, + translation_key="sanitizing_wash", + status_attribute=Attribute.SANITIZING_WASH, + command=Command.SET_SANITIZING_WASH, + entity_category=EntityCategory.CONFIG, + ) ), Attribute.SPEED_BOOSTER: SmartThingsDishwasherWashingOptionSwitchEntityDescription( key=Attribute.SPEED_BOOSTER, @@ -427,7 +441,12 @@ class SmartThingsSwitch(SmartThingsEntity, SwitchEntity): ) self.entity_description = entity_description self.switch_capability = capability - self._attr_unique_id = f"{device.device.device_id}_{component}_{capability}_{entity_description.status_attribute}_{entity_description.status_attribute}" + self._attr_unique_id = ( + f"{device.device.device_id}_{component}" + f"_{capability}" + f"_{entity_description.status_attribute}" + f"_{entity_description.status_attribute}" + ) if ( translation_keys := entity_description.component_translation_key ) is not None and ( diff --git a/homeassistant/components/smartthings/time.py b/homeassistant/components/smartthings/time.py index d87fd4bdeae..e7f3477a9a9 100644 --- a/homeassistant/components/smartthings/time.py +++ b/homeassistant/components/smartthings/time.py @@ -67,7 +67,12 @@ class SmartThingsDnDTime(SmartThingsEntity, TimeEntity): """Initialize the time entity.""" super().__init__(client, device, {Capability.CUSTOM_DO_NOT_DISTURB_MODE}) self.entity_description = entity_description - self._attr_unique_id = f"{device.device.device_id}_{MAIN}_{Capability.CUSTOM_DO_NOT_DISTURB_MODE}_{entity_description.attribute}_{entity_description.attribute}" + self._attr_unique_id = ( + f"{device.device.device_id}_{MAIN}" + f"_{Capability.CUSTOM_DO_NOT_DISTURB_MODE}" + f"_{entity_description.attribute}" + f"_{entity_description.attribute}" + ) async def async_set_value(self, value: time) -> None: """Set the time value.""" @@ -87,7 +92,9 @@ class SmartThingsDnDTime(SmartThingsEntity, TimeEntity): Command.SET_DO_NOT_DISTURB_MODE, { **payload, - self.entity_description.attribute: f"{value.hour:02d}{value.minute:02d}", + self.entity_description.attribute: ( + f"{value.hour:02d}{value.minute:02d}" + ), }, ) diff --git a/homeassistant/components/smarttub/binary_sensor.py b/homeassistant/components/smarttub/binary_sensor.py index 55d9c2802a3..2fe1456eb1b 100644 --- a/homeassistant/components/smarttub/binary_sensor.py +++ b/homeassistant/components/smarttub/binary_sensor.py @@ -93,7 +93,10 @@ async def async_setup_entry( class SmartTubOnline(SmartTubOnboardSensorBase, BinarySensorEntity): - """A binary sensor indicating whether the spa is currently online (connected to the cloud).""" + """A binary sensor indicating whether the spa is online. + + Indicates if it is connected to the cloud. + """ _attr_device_class = BinarySensorDeviceClass.CONNECTIVITY # This seems to be very noisy and not generally useful, so disable by default. diff --git a/homeassistant/components/smarttub/entity.py b/homeassistant/components/smarttub/entity.py index 0a364ce3cbd..ab79d600e64 100644 --- a/homeassistant/components/smarttub/entity.py +++ b/homeassistant/components/smarttub/entity.py @@ -101,5 +101,5 @@ class SmartTubExternalSensorBase(SmartTubEntity): @property def sensor(self) -> SpaSensor: - """Convenience property to access the smarttub.SpaSensor instance for this sensor.""" + """Access the smarttub.SpaSensor instance for this sensor.""" return self.coordinator.data[self.spa.id][ATTR_SENSORS][self.sensor_address] diff --git a/homeassistant/components/smhi/__init__.py b/homeassistant/components/smhi/__init__.py index 07f53b02d98..a3cdd5d9a8f 100644 --- a/homeassistant/components/smhi/__init__.py +++ b/homeassistant/components/smhi/__init__.py @@ -23,7 +23,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: SMHIConfigEntry) -> bool # Setting unique id where missing if entry.unique_id is None: - unique_id = f"{entry.data[CONF_LOCATION][CONF_LATITUDE]}-{entry.data[CONF_LOCATION][CONF_LONGITUDE]}" + unique_id = ( + f"{entry.data[CONF_LOCATION][CONF_LATITUDE]}" + f"-{entry.data[CONF_LOCATION][CONF_LONGITUDE]}" + ) hass.config_entries.async_update_entry(entry, unique_id=unique_id) coordinator = SMHIDataUpdateCoordinator(hass, entry) diff --git a/homeassistant/components/smlight/entity.py b/homeassistant/components/smlight/entity.py index f88f1d81a25..3d0c21ce78c 100644 --- a/homeassistant/components/smlight/entity.py +++ b/homeassistant/components/smlight/entity.py @@ -25,5 +25,8 @@ class SmEntity(CoordinatorEntity[SmBaseDataUpdateCoordinator]): connections={(CONNECTION_NETWORK_MAC, mac)}, manufacturer=ATTR_MANUFACTURER, model=coordinator.data.info.model, - sw_version=f"core: {coordinator.data.info.sw_version} / zigbee: {coordinator.data.info.zb_version}", + sw_version=( + f"core: {coordinator.data.info.sw_version}" + f" / zigbee: {coordinator.data.info.zb_version}" + ), ) diff --git a/homeassistant/components/snapcast/media_player.py b/homeassistant/components/snapcast/media_player.py index 3f7e12b44cc..e7e22ad7b10 100644 --- a/homeassistant/components/snapcast/media_player.py +++ b/homeassistant/components/snapcast/media_player.py @@ -249,7 +249,7 @@ class SnapcastClientDevice(SnapcastCoordinatorEntity, MediaPlayerEntity): @property def group_members(self) -> list[str] | None: - """List of player entities which are currently grouped together for synchronous playback.""" + """List of players currently grouped for synchronous playback.""" if self._current_group is None: return None @@ -298,7 +298,8 @@ class SnapcastClientDevice(SnapcastCoordinatorEntity, MediaPlayerEntity): # Validate client belongs to the same server if not client.unique_id.startswith(unique_id_prefix): raise ServiceValidationError( - f"Entity '{client.entity_id}' does not belong to the same Snapcast server." + f"Entity '{client.entity_id}' does not belong" + " to the same Snapcast server." ) # Extract client ID and join it to the current group @@ -307,7 +308,8 @@ class SnapcastClientDevice(SnapcastCoordinatorEntity, MediaPlayerEntity): await self._current_group.add_client(identifier) except KeyError as e: raise ServiceValidationError( - f"Client with identifier '{identifier}' does not exist on the server." + f"Client with identifier '{identifier}'" + " does not exist on the server." ) from e self.async_write_ha_state() diff --git a/homeassistant/components/snmp/device_tracker.py b/homeassistant/components/snmp/device_tracker.py index 5dc6728f0af..40b294eed2d 100644 --- a/homeassistant/components/snmp/device_tracker.py +++ b/homeassistant/components/snmp/device_tracker.py @@ -102,7 +102,7 @@ class SnmpScanner(DeviceScanner): @classmethod async def create(cls, config): - """Asynchronously test the target device before fully initializing the scanner.""" + """Test the target device before fully initializing.""" host = config[CONF_HOST] try: @@ -125,7 +125,7 @@ class SnmpScanner(DeviceScanner): return instance async def async_init(self, hass: HomeAssistant) -> None: - """Make a one-off read to check if the target device is reachable and readable.""" + """Check if the target device is reachable and readable.""" self.request_args = await async_create_request_cmd_args( hass, self._auth_data, @@ -146,7 +146,7 @@ class SnmpScanner(DeviceScanner): return None async def async_get_extra_attributes(self, device: str) -> dict: - """Return the extra attributes of the given device or an empty dictionary if we have none.""" + """Return extra attributes of the given device.""" for client in self.last_results: if client.get("mac") and device == client["mac"]: return {"mac": client["mac"]} diff --git a/homeassistant/components/solaredge/coordinator.py b/homeassistant/components/solaredge/coordinator.py index dc63afa098a..d7221f7dc8c 100644 --- a/homeassistant/components/solaredge/coordinator.py +++ b/homeassistant/components/solaredge/coordinator.py @@ -115,7 +115,8 @@ class SolarEdgeOverviewDataService(SolarEdgeDataService): data = value self.data[key] = data - # Sanity check the energy values. SolarEdge API sometimes report "lifetimedata" of zero, + # Sanity check the energy values. SolarEdge API sometimes + # reports "lifetimedata" of zero, # while values for last Year, Month and Day energy are still OK. # See https://github.com/home-assistant/core/issues/59285 . if set(energy_keys).issubset(self.data.keys()): @@ -453,8 +454,9 @@ class SolarEdgeModulesCoordinator(DataUpdateCoordinator[None]): async def _async_update_data(self) -> None: """Fetch data from API endpoint and update statistics.""" equipment: dict[int, dict[str, Any]] = await self.api.async_get_equipment() - # We fetch last week's data from the API and refresh every 12h so we overwrite recent - # statistics. This is intended to allow adding any corrected/updated data from the API. + # We fetch last week's data from the API and refresh + # every 12h so we overwrite recent statistics. This is + # intended to allow adding any corrected/updated data. energy_data_list: list[EnergyData] = await self.api.async_get_energy_data( TimeUnit.WEEK ) @@ -545,9 +547,10 @@ class SolarEdgeModulesCoordinator(DataUpdateCoordinator[None]): if statistic_id in current_stats: statistic_sum = current_stats[statistic_id][0]["sum"] else: - # If no statistics found right before start_time, try to get the last statistic - # but use it only if it's before start_time. - # This is needed if the integration hasn't run successfully for at least a week. + # If no statistics found right before start_time, + # try to get the last statistic but use it only + # if it's before start_time. This is needed if + # the integration hasn't run for at least a week. last_stat = await get_instance(self.hass).async_add_executor_job( get_last_statistics, self.hass, 1, statistic_id, True, {"sum"} ) diff --git a/homeassistant/components/solarlog/coordinator.py b/homeassistant/components/solarlog/coordinator.py index 6bb299d92ac..30f8d49aa65 100644 --- a/homeassistant/components/solarlog/coordinator.py +++ b/homeassistant/components/solarlog/coordinator.py @@ -74,7 +74,8 @@ class SolarLogBasicDataCoordinator(DataUpdateCoordinator[SolarlogData]): ) from ex except SolarLogAuthenticationError as ex: if await self.renew_authentication(): - # login was successful, update availability of extended data, retry data update + # login was successful, update availability + # of extended data, retry data update await self.solarlog.test_extended_data_available() raise ConfigEntryNotReady( translation_domain=DOMAIN, @@ -258,7 +259,9 @@ class SolarLogLongtimeDataCoordinator(DataUpdateCoordinator[EnergyData]): if energy_data is None: energy_data = EnergyData(None, None) - self.config_entry.runtime_data.basic_data_coordinator.data.self_consumption_year = energy_data.self_consumption + ( + self.config_entry.runtime_data.basic_data_coordinator.data.self_consumption_year + ) = energy_data.self_consumption _LOGGER.debug("Energy data successfully updated") diff --git a/homeassistant/components/solarlog/entity.py b/homeassistant/components/solarlog/entity.py index 9ad99c88810..e0ed33a7057 100644 --- a/homeassistant/components/solarlog/entity.py +++ b/homeassistant/components/solarlog/entity.py @@ -50,7 +50,8 @@ class SolarLogInverterEntity(CoordinatorEntity[SolarLogDeviceDataCoordinator]): ) -> None: """Initialize the SolarLogInverter sensor.""" super().__init__(coordinator) - name = f"{coordinator.config_entry.entry_id}_{slugify(coordinator.solarlog.device_name(device_id))}" + device_name = coordinator.solarlog.device_name(device_id) + name = f"{coordinator.config_entry.entry_id}_{slugify(device_name)}" self._attr_unique_id = f"{name}_{description.key}" self._attr_device_info = DeviceInfo( manufacturer="Solar-Log", diff --git a/homeassistant/components/solarlog/sensor.py b/homeassistant/components/solarlog/sensor.py index d6785bf5915..9920e2b212a 100644 --- a/homeassistant/components/solarlog/sensor.py +++ b/homeassistant/components/solarlog/sensor.py @@ -261,8 +261,9 @@ SOLARLOG_BASIC_SENSOR_TYPES: tuple[SolarLogCoordinatorSensorEntityDescription, . ), ) -"""SOLARLOG_LONGTIME_SENSOR_TYPES represent data points that may require longer timeout and -therefore are retrieved with different DataUpdateCoordinator.""" +"""SOLARLOG_LONGTIME_SENSOR_TYPES represent data points that +may require longer timeout and therefore are retrieved with +different DataUpdateCoordinator.""" SOLARLOG_LONGTIME_SENSOR_TYPES: tuple[SolarLogLongtimeSensorEntityDescription, ...] = ( SolarLogLongtimeSensorEntityDescription( key="self_consumption_year", @@ -351,7 +352,8 @@ async def async_setup_entry( for sensor in SOLARLOG_LONGTIME_SENSOR_TYPES ) - # add battery sensors only if respective data is available (otherwise no battery attached to solarlog) + # add battery sensors only if respective data is + # available (otherwise no battery attached to solarlog) if solarLogIntegrationData.basic_data_coordinator.data.battery_data is not None: entities.extend( SolarLogBatterySensor( diff --git a/homeassistant/components/soma/cover.py b/homeassistant/components/soma/cover.py index 02aad0bc203..6b92c64ed69 100644 --- a/homeassistant/components/soma/cover.py +++ b/homeassistant/components/soma/cover.py @@ -30,7 +30,8 @@ async def async_setup_entry( entities: list[SomaTilt | SomaShade] = [] for device in data.devices: - # Assume a shade device if the type is not present in the api response (Connect <2.2.6) + # Assume a shade device if the type is not present + # in the api response (Connect <2.2.6) if "type" in device and device["type"].lower() == "tilt": entities.append(SomaTilt(device, api)) else: diff --git a/homeassistant/components/sonarr/helpers.py b/homeassistant/components/sonarr/helpers.py index e0943139ef4..4b553dfdc63 100644 --- a/homeassistant/components/sonarr/helpers.py +++ b/homeassistant/components/sonarr/helpers.py @@ -46,7 +46,8 @@ def format_queue_item(item: Any, base_url: str | None = None) -> dict[str, Any]: if episode := getattr(item, "episode", None): result["episode_number"] = getattr(episode, "episodeNumber", None) result["episode_title"] = getattr(episode, "title", None) - # Add formatted identifier like the sensor uses (if we have both season and episode) + # Add formatted identifier like the sensor uses + # (if we have both season and episode) if result["season_number"] is not None and result["episode_number"] is not None: result["episode_identifier"] = ( f"S{result['season_number']:02d}E{result['episode_number']:02d}" @@ -197,7 +198,8 @@ def format_diskspace( Args: disks: List of disk space objects from Sonarr. - space_unit: Unit for space values (bytes, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib). + space_unit: Unit for space values + (bytes, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib). Returns: Dictionary of disk information keyed by path. @@ -244,7 +246,9 @@ def format_upcoming_item( "series_id": episode.seriesId, "season_number": episode.seasonNumber, "episode_number": episode.episodeNumber, - "episode_identifier": f"S{episode.seasonNumber:02d}E{episode.episodeNumber:02d}", + "episode_identifier": ( + f"S{episode.seasonNumber:02d}E{episode.episodeNumber:02d}" + ), "title": episode.title, "air_date": str(getattr(episode, "airDate", None)), "air_date_utc": str(getattr(episode, "airDateUtc", None)), @@ -341,7 +345,9 @@ def format_episode(episode: SonarrEpisode) -> dict[str, Any]: "tvdb_id": getattr(episode, "tvdbId", None), "season_number": episode.seasonNumber, "episode_number": episode.episodeNumber, - "episode_identifier": f"S{episode.seasonNumber:02d}E{episode.episodeNumber:02d}", + "episode_identifier": ( + f"S{episode.seasonNumber:02d}E{episode.episodeNumber:02d}" + ), "title": episode.title, "air_date": str(getattr(episode, "airDate", None)), "air_date_utc": str(getattr(episode, "airDateUtc", None)), diff --git a/homeassistant/components/songpal/media_player.py b/homeassistant/components/songpal/media_player.py index e90e66cabd9..d012e9d5e72 100644 --- a/homeassistant/components/songpal/media_player.py +++ b/homeassistant/components/songpal/media_player.py @@ -343,7 +343,8 @@ class SongpalEntity(MediaPlayerEntity): def sound_mode_list(self) -> list[str] | None: """Return list of available sound modes. - When active mode is None it means that sound mode is unavailable on the sound bar. + When active mode is None it means that sound mode is + unavailable on the sound bar. Can be due to incompatible sound bar or the sound bar is in a mode that does not support sound mode changes. """ diff --git a/homeassistant/components/sonos/__init__.py b/homeassistant/components/sonos/__init__.py index f9bc70e54ac..8124c14dcac 100644 --- a/homeassistant/components/sonos/__init__.py +++ b/homeassistant/components/sonos/__init__.py @@ -218,13 +218,15 @@ class SonosDiscoveryManager: _ = IPv4Address(ip_address) except AddressValueError: _LOGGER.debug( - "Sonos integration only supports IPv4 addresses, invalid ip_address received: %s", + "Sonos integration only supports IPv4 addresses," + " invalid ip_address received: %s", ip_address, ) return soco = SoCo(ip_address) try: - # Cache now to avoid household ID lookup during first ZoneGroupState processing + # Cache now to avoid household ID lookup during + # first ZoneGroupState processing await self.hass.async_add_executor_job( getattr, soco, @@ -426,7 +428,8 @@ class SonosDiscoveryManager: ) -> None: """Add and maintain Sonos devices from a manual configuration.""" - # Loop through each configured host and verify that Soco attributes are available for it. + # Loop through each configured host and verify that + # Soco attributes are available for it. for host in self.hosts.copy(): ip_addr = await self.hass.async_add_executor_job(socket.gethostbyname, host) soco = SoCo(ip_addr) @@ -457,8 +460,9 @@ class SonosDiscoveryManager: if self.hosts_in_error.pop(ip_addr, None): _LOGGER.warning("Connection reestablished to Sonos device %s", ip_addr) - # Each speaker has the topology for other online speakers, so add them in here if they were not - # configured. The metadata is already in Soco for these. + # Each speaker has the topology for other online + # speakers, so add them in here if they were not + # configured. The metadata is already in Soco. if new_hosts := { x.ip_address for x in visible_zones if x.ip_address not in self.hosts }: @@ -469,12 +473,14 @@ class SonosDiscoveryManager: _LOGGER.debug("Discarding %s from manual hosts", ip_addr) self.hosts.discard(ip_addr) - # Loop through each configured host that is not in error. Send a discovery message - # if a speaker does not already exist, or ping the speaker if it is unavailable. + # Loop through each configured host that is not in + # error. Send a discovery message if a speaker does + # not already exist, or ping if it is unavailable. for host in self.hosts.copy(): ip_addr = await self.hass.async_add_executor_job(socket.gethostbyname, host) soco = SoCo(ip_addr) - # Skip hosts that are in error to avoid blocking call on soco.uuid in event loop + # Skip hosts that are in error to avoid blocking + # call on soco.uuid in event loop if self.hosts_in_error.get(ip_addr): continue known_speaker = next( diff --git a/homeassistant/components/sonos/alarms.py b/homeassistant/components/sonos/alarms.py index 9cdec3b9689..bc3f18d4423 100644 --- a/homeassistant/components/sonos/alarms.py +++ b/homeassistant/components/sonos/alarms.py @@ -89,10 +89,14 @@ class SonosAlarms(SonosHouseholdCoordinator): if "Alarm list UID" in err_msg and "does not match" in err_msg: if not self._household_mismatch_logged: _LOGGER.warning( - "Sonos alarms for %s cannot be updated due to a household mismatch. " - "This is a known limitation in setups with multiple households. " - "You can safely ignore this warning, or to silence it, remove the " - "affected household from your Sonos system. Error: %s", + "Sonos alarms for %s cannot be updated" + " due to a household mismatch. " + "This is a known limitation in setups" + " with multiple households. " + "You can safely ignore this warning," + " or to silence it, remove the " + "affected household from your Sonos" + " system. Error: %s", soco.player_name, err_msg, ) diff --git a/homeassistant/components/sonos/entity.py b/homeassistant/components/sonos/entity.py index 7ffbf475e2b..0b8be269077 100644 --- a/homeassistant/components/sonos/entity.py +++ b/homeassistant/components/sonos/entity.py @@ -107,7 +107,7 @@ class SonosEntity(Entity): class SonosPollingEntity(SonosEntity): - """Representation of a Sonos entity which may not support updating by subscriptions.""" + """Representation of a Sonos entity without subscription support.""" @abstractmethod def poll_state(self) -> None: diff --git a/homeassistant/components/sonos/helpers.py b/homeassistant/components/sonos/helpers.py index 801fd0bc99c..2b4df23b4cc 100644 --- a/homeassistant/components/sonos/helpers.py +++ b/homeassistant/components/sonos/helpers.py @@ -93,7 +93,7 @@ def soco_error[_T: _SonosEntitiesType, **_P, _R]( def _find_target_identifier(instance: Any, fallback_soco: SoCo | None) -> str | None: - """Extract the best available target identifier from the provided instance object.""" + """Extract the best target identifier from the instance.""" if entity_id := getattr(instance, "entity_id", None): # SonosEntity instance return entity_id diff --git a/homeassistant/components/sonos/household_coordinator.py b/homeassistant/components/sonos/household_coordinator.py index 636f3e27d43..e1e56696d30 100644 --- a/homeassistant/components/sonos/household_coordinator.py +++ b/homeassistant/components/sonos/household_coordinator.py @@ -81,7 +81,10 @@ class SonosHouseholdCoordinator: raise NotImplementedError def update_cache(self, soco: SoCo, update_id: int | None = None) -> bool: - """Update the cache of the household-level feature and return if cache has changed.""" + """Update the household-level feature cache. + + Return if cache has changed. + """ raise NotImplementedError def add_speaker(self, soco: SoCo) -> None: diff --git a/homeassistant/components/sonos/media_browser.py b/homeassistant/components/sonos/media_browser.py index 25773973856..c81c54af790 100644 --- a/homeassistant/components/sonos/media_browser.py +++ b/homeassistant/components/sonos/media_browser.py @@ -46,9 +46,11 @@ type GetBrowseImageUrlType = Callable[[str, str, str | None], str] def fix_image_url(url: str) -> str: - """Update the image url to fully encode characters to allow image display in media_browser UI. + """Update the image url to fully encode characters. - Images whose file path contains characters such as ',()+ are not loaded without escaping them. + This allows image display in media_browser UI. Images + whose file path contains characters such as ',()+ are + not loaded without escaping them. """ # Before parsing encode the plus sign; otherwise it'll be interpreted as a space. @@ -108,7 +110,8 @@ def _get_title(id_string: str) -> str: """Extract a suitable title from the content id string.""" if id_string.startswith("S:"): # Format is S://server/share/folder - # If just S: this will be in the mappings; otherwise use the last folder in path. + # If just S: this will be in the mappings; + # otherwise use the last folder in path. title = LIBRARY_TITLES_MAPPING.get( id_string, urllib.parse.unquote(id_string.rsplit("/", maxsplit=1)[-1]) ) @@ -621,9 +624,10 @@ def get_media( ) matches = [result] else: - # When requesting media by album_artist, composer, genre use the browse interface - # to navigate the hierarchy. This occurs when invoked from media browser or service - # calls + # When requesting media by album_artist, composer, + # genre use the browse interface to navigate the + # hierarchy. This occurs when invoked from media + # browser or service calls # Example: A:ALBUMARTIST/Neil Young/Greatest Hits - get specific album # Example: A:ALBUMARTIST/Neil Young - get all albums # Others: composer, genre diff --git a/homeassistant/components/sonos/media_player.py b/homeassistant/components/sonos/media_player.py index 4190e4568af..b49b70cc204 100644 --- a/homeassistant/components/sonos/media_player.py +++ b/homeassistant/components/sonos/media_player.py @@ -839,15 +839,17 @@ class SonosMediaPlayerEntity(SonosEntity, MediaPlayerEntity): async def async_unjoin_player(self) -> None: """Remove this player from any group. - Coalesces all calls within UNJOIN_SERVICE_TIMEOUT to allow use of SonosSpeaker.unjoin_multi() - which optimizes the order in which speakers are removed from their groups. - Removing coordinators last better preserves playqueues on the speakers. + Coalesces all calls within UNJOIN_SERVICE_TIMEOUT to + allow use of SonosSpeaker.unjoin_multi() which + optimizes the order in which speakers are removed + from their groups. Removing coordinators last better + preserves playqueues on the speakers. """ sonos_data = self.config_entry.runtime_data household_id = self.speaker.household_id async def async_process_unjoin(now: datetime.datetime) -> None: - """Process the unjoin with all remove requests within the coalescing period.""" + """Process the unjoin with all remove requests.""" unjoin_data = sonos_data.unjoin_data.pop(household_id) _LOGGER.debug( "Processing unjoins for %s", [x.zone_name for x in unjoin_data.speakers] diff --git a/homeassistant/components/sonos/speaker.py b/homeassistant/components/sonos/speaker.py index 79232d424ac..c5c520fa1d2 100644 --- a/homeassistant/components/sonos/speaker.py +++ b/homeassistant/components/sonos/speaker.py @@ -351,7 +351,7 @@ class SonosSpeaker: def log_subscription_result( self, result: Any, event: str, level: int = logging.DEBUG ) -> None: - """Log a message if a subscription action (create/renew/stop) results in an exception.""" + """Log if a subscription action results in an exception.""" if not isinstance(result, Exception): return @@ -966,7 +966,8 @@ class SonosSpeaker: new_members = set(sonos_group[1:]) removed_members = old_members - new_members for removed_speaker in removed_members: - # Only clear if this speaker was coordinated by self and in the same group + # Only clear if this speaker was coordinated + # by self and in the same group if ( removed_speaker.coordinator == self and removed_speaker.sonos_group is self.sonos_group @@ -1176,10 +1177,12 @@ class SonosSpeaker: if not with_group: return groups - # Unjoin non-coordinator speakers not contained in the desired snapshot group + # Unjoin non-coordinator speakers not contained in + # the desired snapshot group # - # If a coordinator is unjoined from its group, another speaker from the group - # will inherit the coordinator's playqueue and its own playqueue will be lost + # If a coordinator is unjoined from its group, + # another speaker from the group will inherit the + # coordinator's playqueue and its own will be lost speakers_to_unjoin = set() for speaker in speakers: if speaker.sonos_group == speaker.snapshot_group: @@ -1265,7 +1268,8 @@ class SonosSpeaker: await config_entry.runtime_data.topology_condition.wait() except TimeoutError: group_description = "; ".join( - f"{group[0].zone_name}: {', '.join(speaker.zone_name for speaker in group)}" + f"{group[0].zone_name}: " + f"{', '.join(speaker.zone_name for speaker in group)}" for group in groups ) raise HomeAssistantError( diff --git a/homeassistant/components/sonos/switch.py b/homeassistant/components/sonos/switch.py index 6e5a65b735f..40cdbfb4f81 100644 --- a/homeassistant/components/sonos/switch.py +++ b/homeassistant/components/sonos/switch.py @@ -155,7 +155,7 @@ async def async_setup_entry( def _get_switch_state( speaker: SonosSpeaker, ) -> tuple[list[str], str | None, bool | None]: - """Return all switch state needed for entity creation in a single executor call.""" + """Return all switch state for entity creation.""" return ( available_soco_attributes(speaker), _get_tv_autoplay_state(speaker), @@ -399,7 +399,8 @@ class SonosTVUngroupAutoplaySwitchEntity(SonosPollingEntity, SwitchEntity): """Enable or disable ungroup on autoplay on the device.""" try: self.soco.deviceProperties.SetAutoplayLinkedZones( - # enable=True (ungroup) → IncludeLinkedZones=0 (don't include linked zones) + # enable=True (ungroup) → IncludeLinkedZones=0 + # (don't include linked zones) [("IncludeLinkedZones", "0" if enable else "1"), *_TV_SOURCE] ) except SoCoUPnPException as exc: diff --git a/homeassistant/components/soundtouch/media_player.py b/homeassistant/components/soundtouch/media_player.py index a2eea46fa03..b12deaf52b0 100644 --- a/homeassistant/components/soundtouch/media_player.py +++ b/homeassistant/components/soundtouch/media_player.py @@ -393,7 +393,7 @@ class SoundTouchMediaPlayer(MediaPlayerEntity): return None def _get_instance_by_id(self, instance_id): - """Search and return a SoundTouchDevice instance by it's ID (aka MAC address).""" + """Search and return a SoundTouchDevice by its ID.""" for entry in self.hass.config_entries.async_loaded_entries(DOMAIN): data = entry.runtime_data if data.device.config.device_id == instance_id: diff --git a/homeassistant/components/spotify/coordinator.py b/homeassistant/components/spotify/coordinator.py index 6fdaff48a65..efc1ff8fea4 100644 --- a/homeassistant/components/spotify/coordinator.py +++ b/homeassistant/components/spotify/coordinator.py @@ -121,8 +121,9 @@ class SpotifyCoordinator(DataUpdateCoordinator[SpotifyCoordinatorData]): position_updated_at=None, playlist=None, ) - # Record the last updated time, because Spotify's timestamp property is unreliable - # and doesn't actually return the fetch time as is mentioned in the API description + # Record the last updated time, because Spotify's + # timestamp property is unreliable and doesn't + # actually return the fetch time as described in API position_updated_at = dt_util.utcnow() dj_playlist = False diff --git a/homeassistant/components/sql/util.py b/homeassistant/components/sql/util.py index a6fd526c5c0..222ce4d196e 100644 --- a/homeassistant/components/sql/util.py +++ b/homeassistant/components/sql/util.py @@ -121,7 +121,8 @@ def validate_query( Args: hass: The Home Assistant instance. query_template: The SQL query string to be validated. - uses_recorder_db: A boolean indicating if the query is against the recorder database. + uses_recorder_db: A boolean indicating if the query is + against the recorder database. unique_id: The unique ID of the entity, used for creating issue registry keys. Raises: diff --git a/homeassistant/components/squeezebox/__init__.py b/homeassistant/components/squeezebox/__init__.py index 4383be1eb6d..ebfb5489539 100644 --- a/homeassistant/components/squeezebox/__init__.py +++ b/homeassistant/components/squeezebox/__init__.py @@ -140,7 +140,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: SqueezeboxConfigEntry) - }, ) - # For other errors where status is None (e.g., server error, connection refused by server) + # For other errors where status is None + # (e.g., server error, connection refused by server) _LOGGER.warning( "LMS %s returned no status or an error (HTTP status: %s). Retrying setup", host, diff --git a/homeassistant/components/squeezebox/browse_media.py b/homeassistant/components/squeezebox/browse_media.py index f89411687e8..c1a24d77565 100644 --- a/homeassistant/components/squeezebox/browse_media.py +++ b/homeassistant/components/squeezebox/browse_media.py @@ -324,10 +324,12 @@ async def build_item_response( child_media = _build_response_favorites(item) elif search_type in ["apps", "radios"]: - # item["cmd"] contains the name of the command to use with the cli for the app + # item["cmd"] contains the name of the command + # to use with the cli for the app; # add the command to the dictionaries if item["title"] == "Search" or item.get("type") in UNPLAYABLE_TYPES: - # Skip searches in apps as they'd need UI or if the link isn't to audio + # Skip searches in apps as they'd need UI + # or if the link isn't to audio continue app_cmd = "app-" + item["cmd"] diff --git a/homeassistant/components/squeezebox/config_flow.py b/homeassistant/components/squeezebox/config_flow.py index 86dc6a9e816..3463121fb41 100644 --- a/homeassistant/components/squeezebox/config_flow.py +++ b/homeassistant/components/squeezebox/config_flow.py @@ -287,7 +287,10 @@ class SqueezeboxConfigFlow(ConfigFlow, domain=DOMAIN): return self.async_show_form( step_id="edit_integration_discovered", description_placeholders={ - "desc": f"LMS Host: {self.chosen_server[CONF_HOST]}, Port: {self.chosen_server[CONF_PORT]}" + "desc": ( + f"LMS Host: {self.chosen_server[CONF_HOST]}," + f" Port: {self.chosen_server[CONF_PORT]}" + ) }, data_schema=SHORT_EDIT_SCHEMA, errors=errors, @@ -330,7 +333,10 @@ class SqueezeboxConfigFlow(ConfigFlow, domain=DOMAIN): if TYPE_CHECKING: assert self.unique_id - # if we have detected this player, do nothing. if not, there must be a server out there for us to configure, so start the normal user flow (which tries to autodetect server) + # if we have detected this player, do nothing. if not, + # there must be a server out there for us to configure, + # so start the normal user flow (which tries to + # autodetect server) if registry.async_get_entity_id(MP_DOMAIN, DOMAIN, self.unique_id) is not None: # this player is already known, so do nothing other than mark as configured raise AbortFlow("already_configured") diff --git a/homeassistant/components/squeezebox/coordinator.py b/homeassistant/components/squeezebox/coordinator.py index 4f36db6644e..096d39f7a6b 100644 --- a/homeassistant/components/squeezebox/coordinator.py +++ b/homeassistant/components/squeezebox/coordinator.py @@ -106,7 +106,8 @@ class SqueezeBoxPlayerUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): async def _async_update_data(self) -> dict[str, Any]: """Update the Player() object if available, or listen for rediscovery if not.""" if self.available: - # Only update players available at last update, unavailable players are rediscovered instead + # Only update players available at last update, + # unavailable players are rediscovered instead await self.player.async_update() if not self.player.connected: diff --git a/homeassistant/components/squeezebox/entity.py b/homeassistant/components/squeezebox/entity.py index f2be716320f..9b66df9dbfe 100644 --- a/homeassistant/components/squeezebox/entity.py +++ b/homeassistant/components/squeezebox/entity.py @@ -32,8 +32,12 @@ class SqueezeboxEntity(CoordinatorEntity[SqueezeBoxPlayerUpdateCoordinator]): @property def available(self) -> bool: """Return True if entity is available.""" - # super().available refers to CoordinatorEntity.available (self.coordinator.last_update_success) - # self.coordinator.available is the custom availability flag from SqueezeBoxPlayerUpdateCoordinator + # super().available refers to + # CoordinatorEntity.available + # (self.coordinator.last_update_success). + # self.coordinator.available is the custom + # availability flag from + # SqueezeBoxPlayerUpdateCoordinator return self.coordinator.available and super().available diff --git a/homeassistant/components/squeezebox/media_player.py b/homeassistant/components/squeezebox/media_player.py index bb322961ce6..0e7484b96a4 100644 --- a/homeassistant/components/squeezebox/media_player.py +++ b/homeassistant/components/squeezebox/media_player.py @@ -134,7 +134,8 @@ async def async_setup_entry( manufacturer = player.creator model_id = player.model_type sw_version = "" - # Why? so we nicely merge with a server and a player linked by a MAC server is not all info lost + # So we nicely merge with a server and a player + # linked by a MAC server is not all info lost if ( server_device and (CONNECTION_NETWORK_MAC, format_mac(player.player_id)) @@ -762,8 +763,8 @@ class SqueezeBoxMediaPlayerEntity(SqueezeboxEntity, MediaPlayerEntity): async def async_join_players(self, group_members: list[str]) -> None: """Add other Squeezebox players to this player's sync group. - If the other player is a member of a sync group, it will leave the current sync group - without asking. + If the other player is a member of a sync group, + it will leave the current sync group without asking. """ ent_reg = er.async_get(self.hass) for other_player_entity_id in group_members: @@ -798,7 +799,8 @@ class SqueezeBoxMediaPlayerEntity(SqueezeboxEntity, MediaPlayerEntity): def get_synthetic_id_and_cache_url(self, url: str) -> str: """Cache a thumbnail URL and return a synthetic ID. - This enables us to proxy thumbnails for apps and favorites, as those do not have IDs. + This enables us to proxy thumbnails for apps and + favorites, as those do not have IDs. """ synthetic_id = f"s_{ulid_now()}" diff --git a/homeassistant/components/squeezebox/switch.py b/homeassistant/components/squeezebox/switch.py index 3e567b6228a..315228d3ffd 100644 --- a/homeassistant/components/squeezebox/switch.py +++ b/homeassistant/components/squeezebox/switch.py @@ -81,10 +81,12 @@ async def async_setup_entry( coordinator.async_add_listener(_async_listener) # If coordinator already has alarm data from the initial refresh, - # call the listener immediately to process existing alarms and create alarm entities. + # call the listener immediately to process existing + # alarms and create alarm entities. if coordinator.data["alarms"]: _LOGGER.debug( - "Coordinator has alarm data, calling _async_listener immediately for player %s", + "Coordinator has alarm data, calling" + " _async_listener immediately for player %s", coordinator.player, ) _async_listener() diff --git a/homeassistant/components/squeezebox/update.py b/homeassistant/components/squeezebox/update.py index 6b7af58209a..242ec0eda87 100644 --- a/homeassistant/components/squeezebox/update.py +++ b/homeassistant/components/squeezebox/update.py @@ -115,8 +115,10 @@ class ServerStatusUpdatePlugins(ServerStatusUpdate): """If install is supported give some info.""" rs = self.coordinator.data[UPDATE_PLUGINS_RELEASE_SUMMARY] return ( - (rs or "") - + "The Plugins will be updated on the next restart triggered by selecting the Update button. Allow enough time for the service to restart. It will become briefly unavailable." + (rs or "") + "The Plugins will be updated on the next restart" + " triggered by selecting the Update button." + " Allow enough time for the service to restart." + " It will become briefly unavailable." if self.coordinator.can_server_restart else rs ) diff --git a/homeassistant/components/ssdp/scanner.py b/homeassistant/components/ssdp/scanner.py index 9ba47efcedb..6e011664aed 100644 --- a/homeassistant/components/ssdp/scanner.py +++ b/homeassistant/components/ssdp/scanner.py @@ -388,7 +388,8 @@ class Scanner: ssdp_change = SSDP_SOURCE_SSDP_CHANGE_MAPPING[source] _async_process_callbacks(self.hass, callbacks, discovery_info, ssdp_change) - # Config flows should only be created for alive/update messages from alive devices + # Config flows should only be created for alive/update + # messages from alive devices if source == SsdpSource.ADVERTISEMENT_BYEBYE: self._async_dismiss_discoveries(discovery_info) return diff --git a/homeassistant/components/ssdp/server.py b/homeassistant/components/ssdp/server.py index b209072312f..4b01c9ff2c1 100644 --- a/homeassistant/components/ssdp/server.py +++ b/homeassistant/components/ssdp/server.py @@ -124,7 +124,11 @@ class Server: async def _async_get_instance_udn(self) -> str: """Get Unique Device Name for this instance.""" instance_id = await async_get_instance_id(self.hass) - return f"uuid:{instance_id[0:8]}-{instance_id[8:12]}-{instance_id[12:16]}-{instance_id[16:20]}-{instance_id[20:32]}".upper() + return ( + f"uuid:{instance_id[0:8]}-{instance_id[8:12]}" + f"-{instance_id[12:16]}-{instance_id[16:20]}" + f"-{instance_id[20:32]}" + ).upper() async def _async_start_upnp_servers(self, event: Event) -> None: """Start the UPnP/SSDP servers.""" diff --git a/homeassistant/components/starline/sensor.py b/homeassistant/components/starline/sensor.py index 472d8f72643..3ba9ad3b3b3 100644 --- a/homeassistant/components/starline/sensor.py +++ b/homeassistant/components/starline/sensor.py @@ -60,7 +60,8 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( SensorEntityDescription( key="fuel", translation_key="fuel", - # No device_class: fuel can be reported as percentage or volume depending on vehicle + # No device_class: fuel can be reported as percentage + # or volume depending on vehicle state_class=SensorStateClass.TOTAL, ), SensorEntityDescription( diff --git a/homeassistant/components/starlink/coordinator.py b/homeassistant/components/starlink/coordinator.py index ee3d73cc83f..418d91437de 100644 --- a/homeassistant/components/starlink/coordinator.py +++ b/homeassistant/components/starlink/coordinator.py @@ -140,7 +140,8 @@ class StarlinkUpdateCoordinator(DataUpdateCoordinator[StarlinkData]): """Set Starlink system sleep schedule end time.""" duration = end - self.data.sleep[0] if duration < 0: - # If the duration pushed us into the next day, add one days worth to correct that. + # If the duration pushed us into the next day, + # add one days worth to correct that. duration += 1440 async with asyncio.timeout(4): try: diff --git a/homeassistant/components/starlink/sensor.py b/homeassistant/components/starlink/sensor.py index efc820a9d49..e69e04d341b 100644 --- a/homeassistant/components/starlink/sensor.py +++ b/homeassistant/components/starlink/sensor.py @@ -64,7 +64,7 @@ class StarlinkSensorEntity(StarlinkEntity, SensorEntity): class StarlinkAccumulationSensor(StarlinkSensorEntity, RestoreSensor): - """A StarlinkAccumulationSensor for Starlink devices. Handles creating unique IDs.""" + """A StarlinkAccumulationSensor for Starlink devices.""" _attr_native_value: int | float = 0 diff --git a/homeassistant/components/statistics/sensor.py b/homeassistant/components/statistics/sensor.py index 74d6bf7d2a9..dc2147978ba 100644 --- a/homeassistant/components/statistics/sensor.py +++ b/homeassistant/components/statistics/sensor.py @@ -525,7 +525,7 @@ ICON = "mdi:calculator" def valid_state_characteristic_configuration(config: dict[str, Any]) -> dict[str, Any]: - """Validate that the characteristic selected is valid for the source sensor type, throw if it isn't.""" + """Validate characteristic is valid for source sensor type.""" is_binary = split_entity_id(config[CONF_ENTITY_ID])[0] == BINARY_SENSOR_DOMAIN characteristic = cast(str, config[CONF_STATE_CHARACTERISTIC]) if (is_binary and characteristic not in STATS_BINARY_SUPPORT) or ( @@ -556,7 +556,8 @@ def valid_keep_last_sample(config: dict[str, Any]) -> dict[str, Any]: if config.get(CONF_KEEP_LAST_SAMPLE) is True and config.get(CONF_MAX_AGE) is None: raise vol.RequiredFieldInvalid( - "The sensor configuration must provide 'max_age' if 'keep_last_sample' is True" + "The sensor configuration must provide 'max_age'" + " if 'keep_last_sample' is True" ) return config @@ -932,7 +933,8 @@ class StatisticsSensor(SensorEntity): while self.ages and (now_timestamp - self.ages[0]) > max_age: if self.samples_keep_last and len(self.ages) == 1: - # Under normal circumstance this will not be executed, as a purge will not + # Under normal circumstance this will not be + # executed, as a purge will not # be scheduled for the last value if samples_keep_last is enabled. # If this happens to be called outside normal scheduling logic or a # source sensor update, this ensures the last value is preserved. @@ -1096,7 +1098,8 @@ class StatisticsSensor(SensorEntity): def _update_value(self) -> None: """Front to call the right statistical characteristics functions. - One of the _stat_*() functions is represented by self._state_characteristic_fn(). + One of the _stat_*() functions is represented by + self._state_characteristic_fn(). """ value = self._state_characteristic_fn(self.states, self.ages, self._percentile) diff --git a/homeassistant/components/stream/__init__.py b/homeassistant/components/stream/__init__.py index b2ceb53ab97..6043b53a546 100644 --- a/homeassistant/components/stream/__init__.py +++ b/homeassistant/components/stream/__init__.py @@ -185,8 +185,10 @@ def create_stream( ) -> Stream: """Create a stream with the specified identifier based on the source url. - The stream_source is typically an rtsp url (though any url accepted by ffmpeg is fine) and - options (see STREAM_OPTIONS_SCHEMA) are converted and passed into pyav / ffmpeg. + The stream_source is typically an rtsp url (though any + url accepted by ffmpeg is fine) and options (see + STREAM_OPTIONS_SCHEMA) are converted and passed into + pyav / ffmpeg. The stream_label is a string used as an additional message in logging. """ @@ -460,7 +462,8 @@ class Stream: def _run_worker(self) -> None: """Handle consuming streams and restart keepalive streams.""" - # Keep import here so that we can import stream integration without installing reqs + # Keep import here so that we can import stream + # integration without installing reqs from .worker import StreamState, stream_worker # noqa: PLC0415 stream_state = StreamState(self.hass, self.outputs, self._diagnostics) @@ -491,7 +494,8 @@ class Stream: stream_state.discontinuity() if not _should_retry() or self._thread_quit.is_set(): if self._fast_restart_once: - # The stream source is updated, restart without any delay and reset the retry + # The stream source is updated, restart + # without any delay and reset the retry # backoff for the new url. wait_timeout = 0 self._fast_restart_once = False @@ -501,8 +505,9 @@ class Stream: self._set_state(False) # To avoid excessive restarts, wait before restarting - # As the required recovery time may be different for different setups, start - # with trying a short wait_timeout and increase it on each reconnection attempt. + # As the required recovery time may be different + # for different setups, start with trying a short + # wait_timeout and increase it on each attempt. # Reset the wait_timeout after the worker has been up for several minutes if time.time() - start_time > STREAM_RESTART_RESET_TIME: wait_timeout = 0 @@ -515,9 +520,10 @@ class Stream: ) async def worker_finished() -> None: - # The worker is no checking availability of the stream and can no longer track - # availability so mark it as available, otherwise the frontend may not be able to - # interact with the stream. + # The worker is no longer checking availability + # of the stream and can no longer track it so + # mark it as available, otherwise the frontend + # may not be able to interact with the stream. if not self.available: self._async_update_state(True) # We can call remove_provider() sequentially as the wrapped _stop() function @@ -555,7 +561,8 @@ class Stream: ) -> None: """Make a .mp4 recording from a provided stream.""" - # Keep import here so that we can import stream integration without installing reqs + # Keep import here so that we can import stream + # integration without installing reqs from .recorder import RecorderOutput # noqa: PLC0415 # Check for file access diff --git a/homeassistant/components/stream/core.py b/homeassistant/components/stream/core.py index fab20d442bc..3a3d9f9a75c 100644 --- a/homeassistant/components/stream/core.py +++ b/homeassistant/components/stream/core.py @@ -198,7 +198,7 @@ class Segment: def render_hls( self, last_stream_id: int, render_parts: bool, add_hint: bool ) -> str: - """Render the HLS playlist section for the Segment including a hint if requested.""" + """Render the Segment HLS playlist, optionally including parts and a hint.""" playlist_template = self._render_hls_template(last_stream_id, render_parts) playlist = playlist_template.format( self.hls_playlist_parts[0] if render_parts else "" @@ -417,15 +417,17 @@ TRANSFORM_IMAGE_FUNCTION = ( class KeyFrameConverter: - """Enables generating and getting an image from the last keyframe seen in the stream. + """Generate and get an image from the last keyframe. An overview of the thread and state interaction: the worker thread sets a packet get_image is called from the main asyncio loop - get_image schedules _generate_image in an executor thread - _generate_image will try to create an image from the packet - _generate_image will clear the packet, so there will only be one attempt per packet - If successful, self._image will be updated and returned by get_image + get_image schedules _generate_image in an executor + _generate_image will try to create an image from + the packet + _generate_image will clear the packet, so there + will only be one attempt per packet + If successful, self._image will be updated and returned If unsuccessful, get_image will return the previous image """ diff --git a/homeassistant/components/stream/hls.py b/homeassistant/components/stream/hls.py index f75d00e3d99..796b617bb86 100644 --- a/homeassistant/components/stream/hls.py +++ b/homeassistant/components/stream/hls.py @@ -119,8 +119,10 @@ class HlsMasterPlaylistView(StreamView): @staticmethod def render(track: StreamOutput) -> str: """Render M3U8 file.""" - # Need to calculate max bandwidth as input_container.bit_rate doesn't seem to work - # Calculate file size / duration and use a small multiplier to account for variation + # Need to calculate max bandwidth as + # input_container.bit_rate doesn't seem to work. + # Calculate file size / duration and use a small + # multiplier to account for variation # hls spec already allows for 25% variation if not (segment := track.get_segment(track.sequences[-2])): return "" @@ -184,15 +186,15 @@ class HlsPlaylistView(StreamView): ] if track.stream_settings.ll_hls: + part_dur = track.stream_settings.part_target_duration + start_offset = EXT_X_START_LL_HLS * part_dur playlist.extend( [ "#EXT-X-PART-INF:PART-TARGET=" f"{track.stream_settings.part_target_duration:.3f}", "#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,PART-HOLD-BACK=" f"{2 * track.stream_settings.part_target_duration:.3f}", - "#EXT-X-START:TIME-OFFSET=-" - f"{EXT_X_START_LL_HLS * track.stream_settings.part_target_duration:.3f}" - ",PRECISE=YES", + f"#EXT-X-START:TIME-OFFSET=-{start_offset:.3f},PRECISE=YES", ] ) else: diff --git a/homeassistant/components/stream/recorder.py b/homeassistant/components/stream/recorder.py index 2c991bd6064..fdddeb36be8 100644 --- a/homeassistant/components/stream/recorder.py +++ b/homeassistant/components/stream/recorder.py @@ -80,10 +80,12 @@ class RecorderOutput(StreamOutput): def write_segment(segment: Segment) -> None: """Write a segment to output.""" # fmt: off - nonlocal output, output_v, output_a, last_stream_id, running_duration, last_sequence + nonlocal output, output_v, output_a + nonlocal last_stream_id, running_duration, last_sequence # fmt: on - # Because the stream_worker is in a different thread from the record service, - # the lookback segments may still have some overlap with the recorder segments + # Because the stream_worker is in a different + # thread from the record service, the lookback + # segments may still overlap with recorder ones if segment.sequence <= last_sequence: return last_sequence = segment.sequence diff --git a/homeassistant/components/stream/worker.py b/homeassistant/components/stream/worker.py index 5ec94f9b153..6def655ca96 100644 --- a/homeassistant/components/stream/worker.py +++ b/homeassistant/components/stream/worker.py @@ -185,7 +185,11 @@ class StreamMuxer: # https://github.com/home-assistant/core/pull/39970 # "cmaf" flag replaces several of the movflags used, # but too recent to use for now - "movflags": "frag_custom+empty_moov+default_base_moof+frag_discont+negative_cts_offsets+skip_trailer+delay_moov", + "movflags": ( + "frag_custom+empty_moov+default_base_moof" + "+frag_discont+negative_cts_offsets" + "+skip_trailer+delay_moov" + ), # Sometimes the first segment begins with negative timestamps, # and this setting just # adjusts the timestamps in the output from that segment to start @@ -199,7 +203,12 @@ class StreamMuxer: # Fragment durations may exceed the 15% allowed variance but it seems ok **( { - "movflags": "empty_moov+default_base_moof+frag_discont+negative_cts_offsets+skip_trailer+delay_moov", + "movflags": ( + "empty_moov+default_base_moof" + "+frag_discont" + "+negative_cts_offsets" + "+skip_trailer+delay_moov" + ), # Create a fragment every TARGET_PART_DURATION. The data from # each fragment is stored in a "Part" that can be combined with # the data from all the other "Part"s, plus an init section, @@ -662,7 +671,8 @@ def stream_worker( except av.FFmpegError as ex: container.close() raise StreamWorkerError( - f"Error demuxing stream while finding first packet ({redact_av_error_string(ex)})" + "Error demuxing stream while finding first packet" + f" ({redact_av_error_string(ex)})" ) from ex muxer = StreamMuxer( diff --git a/homeassistant/components/subaru/coordinator.py b/homeassistant/components/subaru/coordinator.py index 638ba25f68f..39e65eeadb3 100644 --- a/homeassistant/components/subaru/coordinator.py +++ b/homeassistant/components/subaru/coordinator.py @@ -83,7 +83,8 @@ async def _refresh_subaru_data( for vehicle in vehicle_info.values(): vin = vehicle[VEHICLE_VIN] - # Optionally send an "update" remote command to vehicle (throttled with update_interval) + # Optionally send an "update" remote command to + # vehicle (throttled with update_interval) if config_entry.options.get(CONF_UPDATE_ENABLED, False): await _update_subaru(vehicle, controller) diff --git a/homeassistant/components/subaru/lock.py b/homeassistant/components/subaru/lock.py index 8af699fb45f..b2cba866596 100644 --- a/homeassistant/components/subaru/lock.py +++ b/homeassistant/components/subaru/lock.py @@ -53,7 +53,9 @@ async def async_setup_entry( class SubaruLock(LockEntity): """Representation of a Subaru door lock. - Note that the Subaru API currently does not support returning the status of the locks. Lock status is always unknown. + Note that the Subaru API currently does not support + returning the status of the locks. Lock status is + always unknown. """ _attr_has_entity_name = True diff --git a/homeassistant/components/swiss_public_transport/__init__.py b/homeassistant/components/swiss_public_transport/__init__.py index 49fe9949772..1233003f6d4 100644 --- a/homeassistant/components/swiss_public_transport/__init__.py +++ b/homeassistant/components/swiss_public_transport/__init__.py @@ -145,7 +145,8 @@ async def async_migrate_entry( new_unique_id=f"{new_unique_id}_departure", ) _LOGGER.debug( - "Faulty entity with unique_id 'None_departure' migrated to new unique_id '%s'", + "Faulty entity with unique_id 'None_departure'" + " migrated to new unique_id '%s'", f"{new_unique_id}_departure", ) @@ -155,7 +156,9 @@ async def async_migrate_entry( ) if config_entry.version < 3: - # Via stations and time/offset settings now available, which are not backwards compatible if used, changes unique id + # Via stations and time/offset settings now available, + # which are not backwards compatible if used, + # changes unique id hass.config_entries.async_update_entry(config_entry, version=3, minor_version=1) _LOGGER.debug( diff --git a/homeassistant/components/switchbee/entity.py b/homeassistant/components/switchbee/entity.py index d2d58a3ace3..cd059f85906 100644 --- a/homeassistant/components/switchbee/entity.py +++ b/homeassistant/components/switchbee/entity.py @@ -73,7 +73,10 @@ class SwitchBeeDeviceEntity[_DeviceTypeT: SwitchBeeBaseDevice]( return self._is_online and super().available def _check_if_became_offline(self) -> None: - """Check if the device was online (now offline), log message and mark it as Unavailable.""" + """Check if the device was online (now offline). + + Log message and mark it as unavailable. + """ if self._is_online: _LOGGER.warning( diff --git a/homeassistant/components/switchbee/switch.py b/homeassistant/components/switchbee/switch.py index f7e41c31710..ee0c7ec9a8c 100644 --- a/homeassistant/components/switchbee/switch.py +++ b/homeassistant/components/switchbee/switch.py @@ -77,8 +77,9 @@ class SwitchBeeSwitchEntity[ self._check_if_became_online() - # timed power switch state is an integer representing the number of minutes left until it goes off - # regulare switches state is ON/OFF (1/0 respectively) + # timed power switch state is an integer representing + # the number of minutes left until it goes off; + # regular switches state is ON/OFF (1/0 respectively) self._attr_is_on = coordinator_device.state != ApiStateCommand.OFF async def async_turn_on(self, **kwargs: Any) -> None: diff --git a/homeassistant/components/switchbot/__init__.py b/homeassistant/components/switchbot/__init__.py index b9b85c4b4f2..cb37f03dadb 100644 --- a/homeassistant/components/switchbot/__init__.py +++ b/homeassistant/components/switchbot/__init__.py @@ -198,16 +198,22 @@ CLASS_BY_DEVICE = { SupportedModels.AIR_PURIFIER_US.value: switchbot.SwitchbotAirPurifier, SupportedModels.AIR_PURIFIER_TABLE_JP.value: switchbot.SwitchbotAirPurifier, SupportedModels.AIR_PURIFIER_TABLE_US.value: switchbot.SwitchbotAirPurifier, - SupportedModels.EVAPORATIVE_HUMIDIFIER.value: switchbot.SwitchbotEvaporativeHumidifier, + SupportedModels.EVAPORATIVE_HUMIDIFIER.value: ( + switchbot.SwitchbotEvaporativeHumidifier + ), SupportedModels.FLOOR_LAMP.value: switchbot.SwitchbotStripLight3, SupportedModels.STRIP_LIGHT_3.value: switchbot.SwitchbotStripLight3, SupportedModels.RGBICWW_FLOOR_LAMP.value: switchbot.SwitchbotRgbicLight, SupportedModels.RGBICWW_STRIP_LIGHT.value: switchbot.SwitchbotRgbicLight, - SupportedModels.PERMANENT_OUTDOOR_LIGHT.value: switchbot.SwitchbotPermanentOutdoorLight, + SupportedModels.PERMANENT_OUTDOOR_LIGHT.value: ( + switchbot.SwitchbotPermanentOutdoorLight + ), SupportedModels.PLUG_MINI_EU.value: switchbot.SwitchbotRelaySwitch, SupportedModels.RELAY_SWITCH_2PM.value: switchbot.SwitchbotRelaySwitch2PM, SupportedModels.GARAGE_DOOR_OPENER.value: switchbot.SwitchbotGarageDoorOpener, - SupportedModels.SMART_THERMOSTAT_RADIATOR.value: switchbot.SwitchbotSmartThermostatRadiator, + SupportedModels.SMART_THERMOSTAT_RADIATOR.value: ( + switchbot.SwitchbotSmartThermostatRadiator + ), SupportedModels.ART_FRAME.value: switchbot.SwitchbotArtFrame, SupportedModels.KEYPAD_VISION.value: switchbot.SwitchbotKeypadVision, SupportedModels.KEYPAD_VISION_PRO.value: switchbot.SwitchbotKeypadVision, diff --git a/homeassistant/components/switchbot/button.py b/homeassistant/components/switchbot/button.py index f68a45390cb..33f3851f458 100644 --- a/homeassistant/components/switchbot/button.py +++ b/homeassistant/components/switchbot/button.py @@ -92,7 +92,7 @@ class SwitchBotArtFramePrevButton(SwitchBotArtFrameButtonBase): class SwitchBotMeterProCO2SyncDateTimeButton(SwitchbotEntity, ButtonEntity): - """Button to sync date and time on Meter Pro CO2 to the current HA instance datetime.""" + """Button to sync date and time on Meter Pro CO2.""" _device: switchbot.SwitchbotMeterProCO2 _attr_entity_category = EntityCategory.CONFIG @@ -119,7 +119,8 @@ class SwitchBotMeterProCO2SyncDateTimeButton(SwitchbotEntity, ButtonEntity): timestamp = int(now.timestamp()) _LOGGER.debug( - "Syncing time for %s: timestamp=%s, utc_offset_hours=%s, utc_offset_minutes=%s", + "Syncing time for %s: timestamp=%s," + " utc_offset_hours=%s, utc_offset_minutes=%s", self._address, timestamp, utc_offset_hours, diff --git a/homeassistant/components/switchbot/const.py b/homeassistant/components/switchbot/const.py index fe03ba96f16..0645f8f38e1 100644 --- a/homeassistant/components/switchbot/const.py +++ b/homeassistant/components/switchbot/const.py @@ -182,7 +182,9 @@ ENCRYPTED_SWITCHBOT_MODEL_TO_CLASS: dict[ SwitchbotModel.PLUG_MINI_EU: switchbot.SwitchbotRelaySwitch, SwitchbotModel.RELAY_SWITCH_2PM: switchbot.SwitchbotRelaySwitch2PM, SwitchbotModel.GARAGE_DOOR_OPENER: switchbot.SwitchbotRelaySwitch, - SwitchbotModel.SMART_THERMOSTAT_RADIATOR: switchbot.SwitchbotSmartThermostatRadiator, + SwitchbotModel.SMART_THERMOSTAT_RADIATOR: ( + switchbot.SwitchbotSmartThermostatRadiator + ), SwitchbotModel.ART_FRAME: switchbot.SwitchbotArtFrame, SwitchbotModel.KEYPAD_VISION: switchbot.SwitchbotKeypadVision, SwitchbotModel.KEYPAD_VISION_PRO: switchbot.SwitchbotKeypadVision, diff --git a/homeassistant/components/switchbot/entity.py b/homeassistant/components/switchbot/entity.py index 83279a25820..398f6f219a2 100644 --- a/homeassistant/components/switchbot/entity.py +++ b/homeassistant/components/switchbot/entity.py @@ -41,7 +41,8 @@ class SwitchbotEntity( self._attr_device_info = DeviceInfo( connections={(dr.CONNECTION_BLUETOOTH, self._address)}, manufacturer=MANUFACTURER, - model=coordinator.model, # Sometimes the modelName is missing from the advertisement data + # Sometimes the modelName is missing from ads + model=coordinator.model, name=coordinator.device_name, ) self._channel: int | None = None diff --git a/homeassistant/components/switcher_kis/__init__.py b/homeassistant/components/switcher_kis/__init__.py index 7a0fd7471e0..dcc843349bd 100644 --- a/homeassistant/components/switcher_kis/__init__.py +++ b/homeassistant/components/switcher_kis/__init__.py @@ -46,7 +46,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: SwitcherConfigEntry) -> # New device - create device _LOGGER.info( - "Discovered Switcher device - id: %s, key: %s, name: %s, type: %s (%s), is_token_needed: %s", + "Discovered Switcher device - id: %s, key: %s," + " name: %s, type: %s (%s), is_token_needed: %s", device.device_id, device.device_key, device.name, diff --git a/homeassistant/components/synology_dsm/config_flow.py b/homeassistant/components/synology_dsm/config_flow.py index 23a370582eb..4bcbd19920d 100644 --- a/homeassistant/components/synology_dsm/config_flow.py +++ b/homeassistant/components/synology_dsm/config_flow.py @@ -305,7 +305,8 @@ class SynologyDSMFlowHandler(ConfigFlow, domain=DOMAIN): friendly_name = upnp_friendly_name.split("(", 1)[0].strip() mac_address = discovery_info.upnp[ATTR_UPNP_SERIAL] discovered_macs = [format_synology_mac(mac_address)] - # Synology NAS can broadcast on multiple IP addresses, since they can be connected to multiple ethernets. + # Synology NAS can broadcast on multiple IP addresses, + # since they can be connected to multiple Ethernet interfaces. # The serial of the NAS is actually its MAC address. host = cast(str, parsed_url.hostname) return await self._async_from_discovery(host, friendly_name, discovered_macs) diff --git a/homeassistant/components/systemnexa2/coordinator.py b/homeassistant/components/systemnexa2/coordinator.py index d52702148f6..b3a05ca26f0 100644 --- a/homeassistant/components/systemnexa2/coordinator.py +++ b/homeassistant/components/systemnexa2/coordinator.py @@ -99,7 +99,9 @@ class SystemNexa2DataUpdateCoordinator(DataUpdateCoordinator[SystemNexa2Data]): except DeviceInitializationError as e: _LOGGER.error( - "Failed to initialize device with IP/Hostname %s, please verify that the device is powered on and reachable on port 3000", + "Failed to initialize device with IP/Hostname" + " %s, please verify that the device is powered" + " on and reachable on port 3000", self.config_entry.data[CONF_HOST], ) raise ConfigEntryNotReady(