diff --git a/homeassistant/components/fastdotcom/__init__.py b/homeassistant/components/fastdotcom/__init__.py index d3f3a40dfef2..a7b98f469cc8 100644 --- a/homeassistant/components/fastdotcom/__init__.py +++ b/homeassistant/components/fastdotcom/__init__.py @@ -29,7 +29,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: FastdotcomConfigEntry) - else: await coordinator.async_config_entry_first_refresh() - # Don't start a speedtest during startup, this will slow down the overall startup dramatically + # Don't start a speedtest during startup, this will slow + # down the overall startup dramatically async_at_started(hass, _async_finish_startup) return True diff --git a/homeassistant/components/feedreader/coordinator.py b/homeassistant/components/feedreader/coordinator.py index 38840fe8277e..7b2d4a890377 100644 --- a/homeassistant/components/feedreader/coordinator.py +++ b/homeassistant/components/feedreader/coordinator.py @@ -185,7 +185,8 @@ class FeedReaderCoordinator( firstrun = True # Set last entry timestamp as epoch time if not available self._last_entry_timestamp = dt_util.utc_from_timestamp(0).timetuple() - # locally cache self._last_entry_timestamp so that entries published at identical times can be processed + # locally cache self._last_entry_timestamp so that + # entries published at identical times can be processed last_entry_timestamp = self._last_entry_timestamp for entry in self._feed.entries: if firstrun or ( diff --git a/homeassistant/components/feedreader/event.py b/homeassistant/components/feedreader/event.py index 867d2b4def76..fb6e1596b2f3 100644 --- a/homeassistant/components/feedreader/event.py +++ b/homeassistant/components/feedreader/event.py @@ -67,8 +67,9 @@ class FeedReaderEvent(CoordinatorEntity[FeedReaderCoordinator], EventEntity): if (data := self.coordinator.data) is None or not data: return - # RSS feeds are normally sorted reverse chronologically by published date - # so we always take the first entry in list, since we only care about the latest entry + # RSS feeds are normally sorted reverse chronologically + # by published date so we always take the first entry + # in list, since we only care about the latest entry feed_data: FeedParserDict = data[0] if description := feed_data.get("description"): diff --git a/homeassistant/components/file_upload/__init__.py b/homeassistant/components/file_upload/__init__.py index 7f8935487c0b..7cbd89cd261c 100644 --- a/homeassistant/components/file_upload/__init__.py +++ b/homeassistant/components/file_upload/__init__.py @@ -74,7 +74,8 @@ class FileUploadData: """Create temporary directory.""" temp_dir = Path(tempfile.gettempdir()) / TEMP_DIR_NAME - # If it exists, it's an old one and Home Assistant didn't shut down correctly. + # If it exists, it's an old one and Home Assistant + # didn't shut down correctly. if temp_dir.exists(): shutil.rmtree(temp_dir) diff --git a/homeassistant/components/fing/__init__.py b/homeassistant/components/fing/__init__.py index 8303d6bf0cf5..f7bcc16d8c63 100644 --- a/homeassistant/components/fing/__init__.py +++ b/homeassistant/components/fing/__init__.py @@ -21,10 +21,13 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: FingConfigEntry) if coordinator.data.network_id is None: _LOGGER.warning( - "Skip setting up Fing integration; Received an empty NetworkId from the request - Check if the API version is the latest" + "Skip setting up Fing integration; Received an empty" + " NetworkId from the request - Check if the API" + " version is the latest" ) raise ConfigEntryError( - "The Agent's API version is outdated. Please update the agent to the latest version." + "The Agent's API version is outdated." + " Please update the agent to the latest version." ) config_entry.runtime_data = coordinator diff --git a/homeassistant/components/fing/config_flow.py b/homeassistant/components/fing/config_flow.py index 10dd6bbb3f85..f406e9c223b6 100644 --- a/homeassistant/components/fing/config_flow.py +++ b/homeassistant/components/fing/config_flow.py @@ -48,7 +48,9 @@ class FingConfigFlow(ConfigFlow, domain=DOMAIN): devices_response = await fing_api.get_devices() with suppress(httpx.ConnectError): - # The suppression is needed because the get_agent_info method isn't available for desktop agents + # The suppression is needed because the + # get_agent_info method isn't available + # for desktop agents agent_info_response = await fing_api.get_agent_info() except httpx.NetworkError as _: @@ -57,7 +59,8 @@ class FingConfigFlow(ConfigFlow, domain=DOMAIN): errors["base"] = "timeout_connect" except httpx.HTTPStatusError as exception: description_placeholders["message"] = ( - f"{exception.response.status_code} - {exception.response.reason_phrase}" + f"{exception.response.status_code}" + f" - {exception.response.reason_phrase}" ) if exception.response.status_code == 401: errors["base"] = "invalid_api_key" diff --git a/homeassistant/components/fing/coordinator.py b/homeassistant/components/fing/coordinator.py index b2390f77317b..4a2263267452 100644 --- a/homeassistant/components/fing/coordinator.py +++ b/homeassistant/components/fing/coordinator.py @@ -69,7 +69,8 @@ class FingDataUpdateCoordinator(DataUpdateCoordinator[FingDataObject]): if err.response.status_code == 401: raise UpdateFailed("Invalid API key") from err raise UpdateFailed( - f"Http request failed -> {err.response.status_code} - {err.response.reason_phrase}" + f"Http request failed -> {err.response.status_code}" + f" - {err.response.reason_phrase}" ) from err except httpx.InvalidURL as err: raise UpdateFailed("Invalid hostname or IP address") from err diff --git a/homeassistant/components/fitbit/api.py b/homeassistant/components/fitbit/api.py index 8d44a0b686e6..9d00cffdd25d 100644 --- a/homeassistant/components/fitbit/api.py +++ b/homeassistant/components/fitbit/api.py @@ -117,7 +117,10 @@ class FitbitApi(ABC): return devices async def async_get_latest_time_series(self, resource_type: str) -> dict[str, Any]: - """Return the most recent value from the time series for the specified resource type.""" + """Return the most recent value from the time series. + + Returns the value for the specified resource type. + """ client = await self._async_get_client() # Set request header based on the configured unit system diff --git a/homeassistant/components/fitbit/config_flow.py b/homeassistant/components/fitbit/config_flow.py index 86794f5a963d..d366ab83c479 100644 --- a/homeassistant/components/fitbit/config_flow.py +++ b/homeassistant/components/fitbit/config_flow.py @@ -52,7 +52,10 @@ class OAuth2FlowHandler( async def async_step_creation( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: - """Create config entry from external data with Fitbit specific error handling.""" + """Create config entry from external data. + + Handles Fitbit specific errors. + """ try: return await super().async_step_creation() except FitbitAuthException as err: diff --git a/homeassistant/components/fitbit/const.py b/homeassistant/components/fitbit/const.py index e04d986ec788..bb503c7f348c 100644 --- a/homeassistant/components/fitbit/const.py +++ b/homeassistant/components/fitbit/const.py @@ -50,7 +50,8 @@ class FitbitUnitSystem(StrEnum): This is used as a header to tell the Fitbit API which type of units to return. https://dev.fitbit.com/build/reference/web-api/developer-guide/application-design/#Units - Prefer to leave unset for newer configurations to use the Home Assistant default units. + Prefer to leave unset for newer configurations to use + the Home Assistant default units. """ LEGACY_DEFAULT = "default" diff --git a/homeassistant/components/fitbit/exceptions.py b/homeassistant/components/fitbit/exceptions.py index 82ac53d5f999..c123bfceaeba 100644 --- a/homeassistant/components/fitbit/exceptions.py +++ b/homeassistant/components/fitbit/exceptions.py @@ -1,6 +1,7 @@ """Exceptions for fitbit API calls. -These exceptions exist to provide common exceptions for the async and sync client libraries. +These exceptions provide common exceptions for the async +and sync client libraries. """ from homeassistant.exceptions import HomeAssistantError diff --git a/homeassistant/components/flexit_bacnet/climate.py b/homeassistant/components/flexit_bacnet/climate.py index 1f580983a49e..4b7eb6ecb9f5 100644 --- a/homeassistant/components/flexit_bacnet/climate.py +++ b/homeassistant/components/flexit_bacnet/climate.py @@ -115,7 +115,11 @@ class FlexitClimateEntity(FlexitEntity, ClimateEntity): await self.device.set_air_temp_setpoint_away(temperature) else: await self.device.set_air_temp_setpoint_home(temperature) - except (asyncio.exceptions.TimeoutError, ConnectionError, DecodingError) as exc: + except ( + asyncio.exceptions.TimeoutError, + ConnectionError, + DecodingError, + ) as exc: raise HomeAssistantError( translation_domain=DOMAIN, translation_key="set_temperature", @@ -149,7 +153,11 @@ class FlexitClimateEntity(FlexitEntity, ClimateEntity): # Set the desired ventilation mode ventilation_mode = PRESET_TO_VENTILATION_MODE_MAP[preset_mode] await self.device.set_ventilation_mode(ventilation_mode) - except (asyncio.exceptions.TimeoutError, ConnectionError, DecodingError) as exc: + except ( + asyncio.exceptions.TimeoutError, + ConnectionError, + DecodingError, + ) as exc: raise HomeAssistantError( translation_domain=DOMAIN, translation_key="set_preset_mode", @@ -175,7 +183,11 @@ class FlexitClimateEntity(FlexitEntity, ClimateEntity): await self.device.set_ventilation_mode(VENTILATION_MODE_STOP) else: await self.device.set_ventilation_mode(VENTILATION_MODE_HOME) - except (asyncio.exceptions.TimeoutError, ConnectionError, DecodingError) as exc: + except ( + asyncio.exceptions.TimeoutError, + ConnectionError, + DecodingError, + ) as exc: raise HomeAssistantError( translation_domain=DOMAIN, translation_key="set_hvac_mode", diff --git a/homeassistant/components/flexit_bacnet/number.py b/homeassistant/components/flexit_bacnet/number.py index b8c329bd1d4a..10988a2c00cc 100644 --- a/homeassistant/components/flexit_bacnet/number.py +++ b/homeassistant/components/flexit_bacnet/number.py @@ -39,7 +39,8 @@ class FlexitNumberEntityDescription(NumberEntityDescription): set_native_value_fn: Callable[[FlexitBACnet], Callable[[int], Awaitable[None]]] -# Setpoints for Away, Home and High are dependent of each other. Fireplace and Cooker Hood +# Setpoints for Away, Home and High are dependent of each +# other. Fireplace and Cooker Hood # have setpoints between 0 (MIN_FAN_SETPOINT) and 100 (MAX_FAN_SETPOINT). # See the table below for all the setpoints. # diff --git a/homeassistant/components/flux_led/__init__.py b/homeassistant/components/flux_led/__init__.py index 322732a33d78..d5d5b707c7b6 100644 --- a/homeassistant/components/flux_led/__init__.py +++ b/homeassistant/components/flux_led/__init__.py @@ -190,7 +190,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: FluxLedConfigEntry) -> b if entry.unique_id and discovery.get(ATTR_ID): mac = dr.format_mac(cast(str, discovery[ATTR_ID])) if not mac_matches_by_one(mac, entry.unique_id): - # The device is offline and another flux_led device is now using the ip address + # The device is offline and another flux_led device + # is now using the ip address raise ConfigEntryNotReady( f"Unexpected device found at {host}; Expected {entry.unique_id}, found" f" {mac}" diff --git a/homeassistant/components/forecast_solar/config_flow.py b/homeassistant/components/forecast_solar/config_flow.py index c85201f7b0d0..54378fa778cd 100644 --- a/homeassistant/components/forecast_solar/config_flow.py +++ b/homeassistant/components/forecast_solar/config_flow.py @@ -105,7 +105,11 @@ class ForecastSolarFlowHandler(ConfigFlow, domain=DOMAIN): CONF_AZIMUTH: user_input[CONF_AZIMUTH], CONF_MODULES_POWER: user_input[CONF_MODULES_POWER], }, - "title": f"{user_input[CONF_DECLINATION]}° / {user_input[CONF_AZIMUTH]}° / {user_input[CONF_MODULES_POWER]}W", + "title": ( + f"{user_input[CONF_DECLINATION]}°" + f" / {user_input[CONF_AZIMUTH]}°" + f" / {user_input[CONF_MODULES_POWER]}W" + ), "unique_id": None, }, ], @@ -240,7 +244,11 @@ class PlaneSubentryFlowHandler(ConfigSubentryFlow): if user_input is not None: return self.async_create_entry( - title=f"{user_input[CONF_DECLINATION]}° / {user_input[CONF_AZIMUTH]}° / {user_input[CONF_MODULES_POWER]}W", + title=( + f"{user_input[CONF_DECLINATION]}°" + f" / {user_input[CONF_AZIMUTH]}°" + f" / {user_input[CONF_MODULES_POWER]}W" + ), data={ CONF_DECLINATION: user_input[CONF_DECLINATION], CONF_AZIMUTH: user_input[CONF_AZIMUTH], @@ -276,7 +284,11 @@ class PlaneSubentryFlowHandler(ConfigSubentryFlow): CONF_AZIMUTH: user_input[CONF_AZIMUTH], CONF_MODULES_POWER: user_input[CONF_MODULES_POWER], }, - title=f"{user_input[CONF_DECLINATION]}° / {user_input[CONF_AZIMUTH]}° / {user_input[CONF_MODULES_POWER]}W", + title=( + f"{user_input[CONF_DECLINATION]}°" + f" / {user_input[CONF_AZIMUTH]}°" + f" / {user_input[CONF_MODULES_POWER]}W" + ), ): if not entry.update_listeners: self.hass.config_entries.async_schedule_reload(entry.entry_id) diff --git a/homeassistant/components/forecast_solar/diagnostics.py b/homeassistant/components/forecast_solar/diagnostics.py index 435de7c1f86d..4e79eea307ba 100644 --- a/homeassistant/components/forecast_solar/diagnostics.py +++ b/homeassistant/components/forecast_solar/diagnostics.py @@ -36,7 +36,9 @@ async def async_get_config_entry_diagnostics( }, "data": { "energy_production_today": coordinator.data.energy_production_today, - "energy_production_today_remaining": coordinator.data.energy_production_today_remaining, + "energy_production_today_remaining": ( + coordinator.data.energy_production_today_remaining + ), "energy_production_tomorrow": coordinator.data.energy_production_tomorrow, "energy_current_hour": coordinator.data.energy_current_hour, "power_production_now": coordinator.data.power_production_now, diff --git a/homeassistant/components/forked_daapd/browse_media.py b/homeassistant/components/forked_daapd/browse_media.py index 6e7a4547aa33..c1ba2350886a 100644 --- a/homeassistant/components/forked_daapd/browse_media.py +++ b/homeassistant/components/forked_daapd/browse_media.py @@ -58,11 +58,16 @@ OWNTONE_TYPE_TO_MEDIA_TYPE = { } MEDIA_TYPE_TO_OWNTONE_TYPE = {v: k for k, v in OWNTONE_TYPE_TO_MEDIA_TYPE.items()} -# media_content_id is a uri in the form of SCHEMA:Title:OwnToneURI:Subtype (Subtype only used for Genre) -# OwnToneURI is in format library:type:id (for directories, id is path) -# media_content_type - type of item (mostly used to check if playable or can expand) -# OwnTone type may differ from media_content_type when media_content_type is a directory -# OwnTone type is used in our own branching, but media_content_type is used for determining playability +# media_content_id is a uri in the form of +# SCHEMA:Title:OwnToneURI:Subtype (Subtype only for Genre) +# OwnToneURI is in format library:type:id +# (for directories, id is path) +# media_content_type - type of item +# (mostly used to check if playable or can expand) +# OwnTone type may differ from media_content_type +# when media_content_type is a directory +# OwnTone type is used in our own branching, but +# media_content_type is used for determining playability @dataclass diff --git a/homeassistant/components/forked_daapd/media_player.py b/homeassistant/components/forked_daapd/media_player.py index d29f15f8074a..fc040f3bcc0a 100644 --- a/homeassistant/components/forked_daapd/media_player.py +++ b/homeassistant/components/forked_daapd/media_player.py @@ -348,7 +348,7 @@ class ForkedDaapdMaster(MediaPlayerEntity): self._queue["count"] >= 1 and self._queue["items"][0]["data_kind"] == "pipe" and self._queue["items"][0]["title"] in KNOWN_PIPES - ): # if we're playing a pipe, set the source automatically so we can forward controls + ): # if playing a pipe, set source to forward controls self._source = f"{self._queue['items'][0]['title']} (pipe)" self._update_track_info() event.set() diff --git a/homeassistant/components/foscam/coordinator.py b/homeassistant/components/foscam/coordinator.py index e25fa9381e0c..b11a7a34f029 100644 --- a/homeassistant/components/foscam/coordinator.py +++ b/homeassistant/components/foscam/coordinator.py @@ -17,7 +17,7 @@ type FoscamConfigEntry = ConfigEntry[FoscamCoordinator] @dataclass class FoscamDeviceInfo: - """A data class representing the current state and configuration of a Foscam camera device.""" + """Represent the current state and config of a Foscam camera.""" dev_info: dict product_info: dict diff --git a/homeassistant/components/foscam/switch.py b/homeassistant/components/foscam/switch.py index d4003b36d9c0..c3212926d4a4 100644 --- a/homeassistant/components/foscam/switch.py +++ b/homeassistant/components/foscam/switch.py @@ -15,14 +15,22 @@ from .entity import FoscamEntity def handle_ir_turn_on(session: FoscamCamera) -> None: - """Turn on IR LED: sets IR mode to auto (if supported), then turns off the IR LED.""" + """Turn on IR LED. + + Sets IR mode to auto (if supported), then turns off + the IR LED. + """ session.set_infra_led_config(1) session.open_infra_led() def handle_ir_turn_off(session: FoscamCamera) -> None: - """Turn off IR LED: sets IR mode to manual (if supported), then turns open the IR LED.""" + """Turn off IR LED. + + Sets IR mode to manual (if supported), then turns + open the IR LED. + """ session.set_infra_led_config(0) session.close_infra_led() diff --git a/homeassistant/components/freebox/binary_sensor.py b/homeassistant/components/freebox/binary_sensor.py index 83879e14115c..3b0cc5a70bfb 100644 --- a/homeassistant/components/freebox/binary_sensor.py +++ b/homeassistant/components/freebox/binary_sensor.py @@ -112,7 +112,11 @@ class FreeboxDwsSensor(FreeboxHomeBinarySensor): class FreeboxCoverSensor(FreeboxHomeBinarySensor): - """Representation of a cover Freebox plastic removal cover binary sensor (for some sensors: motion detector, door opener detector...).""" + """Represent a Freebox plastic removal cover sensor. + + Applies to some sensors: motion detector, + door opener detector, etc. + """ _attr_device_class = BinarySensorDeviceClass.SAFETY _attr_entity_category = EntityCategory.DIAGNOSTIC diff --git a/homeassistant/components/freebox/router.py b/homeassistant/components/freebox/router.py index a654552155d9..bdfbd015ff3c 100644 --- a/homeassistant/components/freebox/router.py +++ b/homeassistant/components/freebox/router.py @@ -143,7 +143,8 @@ class FreeboxRouter: fbx_devices: list[dict[str, Any]] = [] - # Access to Host list not available in bridge mode, API return error_code 'nodev' + # Access to Host list not available in bridge mode, + # API return error_code 'nodev' if self.supports_hosts: self.supports_hosts, fbx_devices = await get_hosts_list_if_supported( self._api @@ -180,7 +181,8 @@ class FreeboxRouter: # System sensors syst_datas: dict[str, Any] = await self._api.system.get_config() - # According to the doc `syst_datas["sensors"]` is temperature sensors in celsius degree. + # According to the doc `syst_datas["sensors"]` is + # temperature sensors in celsius degree. # Name and id of sensors may vary under Freebox devices. for sensor in syst_datas["sensors"]: self.sensors_temperature[sensor["name"]] = sensor.get("value") diff --git a/homeassistant/components/fressnapf_tracker/__init__.py b/homeassistant/components/fressnapf_tracker/__init__.py index 91c97f4fcd9c..98a679b15de7 100644 --- a/homeassistant/components/fressnapf_tracker/__init__.py +++ b/homeassistant/components/fressnapf_tracker/__init__.py @@ -38,7 +38,8 @@ _LOGGER = logging.getLogger(__name__) async def _get_valid_tracker(hass: HomeAssistant, device: Device) -> Tracker | None: """Test if the tracker returns valid data and return it. - Malformed data might indicate the tracker is broken or hasn't been properly registered with the app. + Malformed data might indicate the tracker is broken or + hasn't been properly registered with the app. """ client = ApiClient( serial_number=device.serialnumber, diff --git a/homeassistant/components/fritz/button.py b/homeassistant/components/fritz/button.py index fb0dfcfe938b..bc7dd6c3d49d 100644 --- a/homeassistant/components/fritz/button.py +++ b/homeassistant/components/fritz/button.py @@ -188,15 +188,21 @@ class FritzButton(ButtonEntity): """Triggers Fritz!Box service.""" if self.entity_description.key == "cleanup": _LOGGER.warning( - "The 'cleanup' button is deprecated and will be removed in Home Assistant Core 2026.11.0. " - "Please update your automations and dashboards to remove any usage of this button. " - "The action is now performed automatically at each data refresh", + "The 'cleanup' button is deprecated and will" + " be removed in Home Assistant Core" + " 2026.11.0. Please update your automations" + " and dashboards to remove any usage of" + " this button. The action is now performed" + " automatically at each data refresh", ) elif self.entity_description.key == "firmware_update": _LOGGER.warning( - "The 'firmware update' button is deprecated and will be removed in Home Assistant Core " - "2026.11.0. It has been superseded by an update entity. Please update your automations " - "and dashboards to remove any usage of this button", + "The 'firmware update' button is deprecated" + " and will be removed in Home Assistant" + " Core 2026.11.0. It has been superseded" + " by an update entity. Please update your" + " automations and dashboards to remove" + " any usage of this button", ) await self.entity_description.press_action(self.avm_wrapper) diff --git a/homeassistant/components/fritz/config_flow.py b/homeassistant/components/fritz/config_flow.py index 980969e3958a..7467bae12090 100644 --- a/homeassistant/components/fritz/config_flow.py +++ b/homeassistant/components/fritz/config_flow.py @@ -376,8 +376,10 @@ class FritzBoxToolsFlowHandler(ConfigFlow, domain=DOMAIN): if (port == DEFAULT_HTTP_PORT and not ssl) or ( port == DEFAULT_HTTPS_PORT and ssl ): - # don't show default ports in reconfigure flow, as they are determined by ssl value - # this allows the user to toggle ssl without having to change the port + # don't show default ports in reconfigure flow, + # as they are determined by ssl value + # this allows the user to toggle ssl + # without having to change the port port = vol.UNDEFINED return self._show_setup_form_reconfigure( diff --git a/homeassistant/components/fritz/switch.py b/homeassistant/components/fritz/switch.py index 5b3fa1357d67..c62453a581ec 100644 --- a/homeassistant/components/fritz/switch.py +++ b/homeassistant/components/fritz/switch.py @@ -49,8 +49,9 @@ def _wifi_naming( """Return a friendly name for a Wi-Fi network.""" if wifi_index == 2 and wifi_count == 4: - # In case of 4 Wi-Fi networks, the 2nd one is used for internal communication - # between mesh devices and should not be named like the others to avoid confusion + # In case of 4 Wi-Fi networks, the 2nd one is used + # for internal communication between mesh devices and + # should not be named like the others to avoid confusion return None if (wifi_index + 1) == wifi_count: @@ -110,7 +111,10 @@ async def _migrate_to_new_unique_id( description += f" ({WIFI_STANDARD[index]})" old_unique_id = f"{avm_wrapper.unique_id}-{slugify(description)}" - new_unique_id = f"{avm_wrapper.unique_id}-wi_fi_{slugify(_wifi_naming(network, index - 1, len(networks)))}" + new_unique_id = ( + f"{avm_wrapper.unique_id}-wi_fi_" + f"{slugify(_wifi_naming(network, index - 1, len(networks)))}" + ) entity_id = entity_registry.async_get_entity_id( Platform.SWITCH, DOMAIN, old_unique_id @@ -454,7 +458,9 @@ class FritzBoxPortSwitch(FritzBoxBaseSwitch): self._attributes = {} self.connection_type = connection_type - self.port_mapping = port_mapping # dict in the format as it comes from fritzconnection. eg: {'NewRemoteHost': '0.0.0.0', 'NewExternalPort': 22, 'NewProtocol': 'TCP', 'NewInternalPort': 22, 'NewInternalClient': '192.168.178.31', 'NewEnabled': True, 'NewPortMappingDescription': 'Beast SSH ', 'NewLeaseDuration': 0} + # dict in the format as it comes from fritzconnection, + # eg: {"NewRemoteHost": "0.0.0.0", "NewExternalPort": 22, ...} + self.port_mapping = port_mapping self._idx = idx # needed for update routine self._attr_entity_category = EntityCategory.CONFIG diff --git a/homeassistant/components/fritzbox/entity.py b/homeassistant/components/fritzbox/entity.py index cc33920c76fa..3d62bdac653d 100644 --- a/homeassistant/components/fritzbox/entity.py +++ b/homeassistant/components/fritzbox/entity.py @@ -41,7 +41,7 @@ class FritzBoxEntity(CoordinatorEntity[FritzboxDataUpdateCoordinator], ABC): class FritzBoxDeviceEntity(FritzBoxEntity): - """Reflects FritzhomeDevice and uses its attributes to construct FritzBoxDeviceEntity.""" + """Reflect FritzhomeDevice and construct FritzBoxDeviceEntity.""" @property def available(self) -> bool: diff --git a/homeassistant/components/fritzbox/light.py b/homeassistant/components/fritzbox/light.py index dd1525b02dfb..b2cd66780f9b 100644 --- a/homeassistant/components/fritzbox/light.py +++ b/homeassistant/components/fritzbox/light.py @@ -138,7 +138,8 @@ class FritzboxLight(FritzBoxDeviceEntity, LightEntity): ) else: LOGGER.debug( - "device has no fullcolorsupport, using supported colors with 'setcolor'" + "device has no fullcolorsupport," + " using supported colors with 'setcolor'" ) # find supported hs values closest to what user selected hue = min( diff --git a/homeassistant/components/fritzbox/switch.py b/homeassistant/components/fritzbox/switch.py index 0cfa7733bb8c..2fdd0ff0cb42 100644 --- a/homeassistant/components/fritzbox/switch.py +++ b/homeassistant/components/fritzbox/switch.py @@ -71,7 +71,7 @@ class FritzboxSwitch(FritzBoxDeviceEntity, SwitchEntity): await self.coordinator.async_refresh() def check_lock_state(self) -> None: - """Raise an Error if manual switching via FRITZ!Box user interface is disabled.""" + """Raise an Error if manual switching via FRITZ!Box is disabled.""" if self.data.lock: raise HomeAssistantError( translation_domain=DOMAIN, diff --git a/homeassistant/components/fritzbox_callmonitor/base.py b/homeassistant/components/fritzbox_callmonitor/base.py index 2b0945c8df3c..3b136be16aa0 100644 --- a/homeassistant/components/fritzbox_callmonitor/base.py +++ b/homeassistant/components/fritzbox_callmonitor/base.py @@ -62,7 +62,7 @@ class FritzBoxPhonebook: self.prefixes = prefixes def init_phonebook(self) -> None: - """Establish a connection to the FRITZ!Box and check if phonebook_id is valid.""" + """Connect to the FRITZ!Box and check if phonebook_id is valid.""" self.fph = FritzPhonebook( address=self.host, user=self.username, diff --git a/homeassistant/components/fronius/__init__.py b/homeassistant/components/fronius/__init__.py index 679bdb247327..dc30702cd1b4 100644 --- a/homeassistant/components/fronius/__init__.py +++ b/homeassistant/components/fronius/__init__.py @@ -84,8 +84,9 @@ class FroniusSolarNet: self.coordinator_lock = asyncio.Lock() self.fronius = fronius self.host: str = entry.data[CONF_HOST] - # entry.unique_id is either logger uid or first inverter uid if no logger available - # prepended by "solar_net_" to have individual device for whole system (power_flow) + # entry.unique_id is either logger uid or first inverter + # uid if no logger available prepended by "solar_net_" + # to have individual device for whole system (power_flow) self.solar_net_device_id = f"solar_net_{entry.unique_id}" self.system_device_info: DeviceInfo | None = None @@ -217,7 +218,8 @@ class FroniusSolarNet: await _coordinator.async_config_entry_first_refresh() self.inverter_coordinators.append(_coordinator) - # Only for re-scans. Initial setup adds entities through sensor.async_setup_entry + # Only for re-scans. Initial setup adds entities + # through sensor.async_setup_entry if self.config_entry.state == ConfigEntryState.LOADED: async_dispatcher_send(self.hass, SOLAR_NET_DISCOVERY_NEW, _coordinator) diff --git a/homeassistant/components/fronius/sensor.py b/homeassistant/components/fronius/sensor.py index 564fc5f3044d..a831d163668a 100644 --- a/homeassistant/components/fronius/sensor.py +++ b/homeassistant/components/fronius/sensor.py @@ -772,7 +772,10 @@ class _FroniusSensorEntity(CoordinatorEntity["FroniusCoordinatorBase"], SensorEn return self.coordinator.data[self.solar_net_id] def _get_entity_value(self) -> Any: - """Extract entity value from coordinator. Raises KeyError if not included in latest update.""" + """Extract entity value from coordinator. + + Raises KeyError if not included in latest update. + """ new_value = self.coordinator.data[self.solar_net_id][self.response_key]["value"] if new_value is None: return self.entity_description.default_value @@ -790,8 +793,10 @@ class _FroniusSensorEntity(CoordinatorEntity["FroniusCoordinatorBase"], SensorEn try: self._attr_native_value = self._get_entity_value() except KeyError: - # sets state to `None` if no default_value is defined in entity description - # KeyError: raised when omitted in response - eg. at night when no production + # sets state to `None` if no default_value is defined + # in entity description + # KeyError: raised when omitted in response + # eg. at night when no production self._attr_native_value = self.entity_description.default_value self.async_write_ha_state() diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index 3479ce1113c4..7df0bd76e85e 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -509,7 +509,8 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: _LOGGER.info("Using frontend from PR #%s", dev_pr_number) except HomeAssistantError as err: _LOGGER.error( - "Failed to download PR #%s: %s, falling back to the integrated frontend", + "Failed to download PR #%s: %s, falling back" + " to the integrated frontend", dev_pr_number, err, ) diff --git a/homeassistant/components/frontier_silicon/config_flow.py b/homeassistant/components/frontier_silicon/config_flow.py index 3c6c24809262..c42a9ec96c7f 100644 --- a/homeassistant/components/frontier_silicon/config_flow.py +++ b/homeassistant/components/frontier_silicon/config_flow.py @@ -129,7 +129,8 @@ class FrontierSiliconConfigFlow(ConfigFlow, domain=DOMAIN): async def _async_step_device_config_if_needed(self) -> ConfigFlowResult: """Most users will not have changed the default PIN on their radio. - We try to use this default PIN, and only if this fails ask for it via `async_step_device_config` + We try to use this default PIN, and only if this fails + ask for it via `async_step_device_config` """ try: @@ -155,7 +156,10 @@ class FrontierSiliconConfigFlow(ConfigFlow, domain=DOMAIN): async def async_step_confirm( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: - """Allow the user to confirm adding the device. Used when the default PIN could successfully be used.""" + """Allow the user to confirm adding the device. + + Used when the default PIN could successfully be used. + """ if user_input is not None: return await self._async_create_entry() diff --git a/homeassistant/components/frontier_silicon/media_player.py b/homeassistant/components/frontier_silicon/media_player.py index da236158a48f..bb33aa393883 100644 --- a/homeassistant/components/frontier_silicon/media_player.py +++ b/homeassistant/components/frontier_silicon/media_player.py @@ -445,7 +445,8 @@ class AFSAPIDevice(MediaPlayerEntity): if len(keys) != 1: raise BrowseError("Presets can only have 1 level") - # Keys of presets are 0-based, while the list shown on the device starts from 1 + # Keys of presets are 0-based, while the list shown + # on the device starts from 1 preset = int(keys[0]) - 1 await self.fs_device.select_preset(preset) diff --git a/homeassistant/components/fujitsu_fglair/sensor.py b/homeassistant/components/fujitsu_fglair/sensor.py index 3bb693e10680..af632aad23cf 100644 --- a/homeassistant/components/fujitsu_fglair/sensor.py +++ b/homeassistant/components/fujitsu_fglair/sensor.py @@ -29,7 +29,10 @@ async def async_setup_entry( class FGLairOutsideTemperature(FGLairEntity, SensorEntity): - """Entity representing outside temperature sensed by the outside unit of a Fujitsu Heatpump.""" + """Entity representing outside temperature. + + Sensed by the outside unit of a Fujitsu Heatpump. + """ _attr_device_class = SensorDeviceClass.TEMPERATURE _attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS diff --git a/homeassistant/components/fully_kiosk/entity.py b/homeassistant/components/fully_kiosk/entity.py index 7dc7298260ff..6f79ce005f8e 100644 --- a/homeassistant/components/fully_kiosk/entity.py +++ b/homeassistant/components/fully_kiosk/entity.py @@ -21,7 +21,9 @@ def valid_global_mac_address(mac: str | None) -> bool: return False try: first_octet = int(mac.split(":")[0], 16) - # If the second least-significant bit is set, it's a locally administered address, should not be used as an ID + # If the second least-significant bit is set, it's a + # locally administered address, should not be used as + # an ID return not bool(first_octet & 0x2) except ValueError: return False diff --git a/homeassistant/components/fyta/coordinator.py b/homeassistant/components/fyta/coordinator.py index b0a70ace731d..6cbe0a680988 100644 --- a/homeassistant/components/fyta/coordinator.py +++ b/homeassistant/components/fyta/coordinator.py @@ -66,7 +66,8 @@ class FytaCoordinator(DataUpdateCoordinator[dict[int, Plant]]): ) from err _LOGGER.debug("Data successfully updated") - # data must be assigned before _async_add_remove_devices, as it is uses to set-up possible new devices + # data must be assigned before _async_add_remove_devices, + # as it is uses to set-up possible new devices self.data = data self._async_add_remove_devices() diff --git a/homeassistant/components/garadget/cover.py b/homeassistant/components/garadget/cover.py index 80802c5d6cb3..4cfac53d4177 100644 --- a/homeassistant/components/garadget/cover.py +++ b/homeassistant/components/garadget/cover.py @@ -252,7 +252,10 @@ class GaradgetCover(CoverEntity): def _get_variable(self, var): """Get latest status.""" - url = f"{self.particle_url}/v1/devices/{self.device_id}/{var}?access_token={self.access_token}" + url = ( + f"{self.particle_url}/v1/devices/{self.device_id}" + f"/{var}?access_token={self.access_token}" + ) ret = requests.get(url, timeout=10) result = {} for pairs in ret.json()["result"].split("|"): diff --git a/homeassistant/components/generic/config_flow.py b/homeassistant/components/generic/config_flow.py index 29b5b9e451ed..21b8670f328b 100644 --- a/homeassistant/components/generic/config_flow.py +++ b/homeassistant/components/generic/config_flow.py @@ -345,7 +345,8 @@ class GenericIPCamConfigFlow(ConfigFlow, domain=DOMAIN): errors = {} hass = self.hass if user_input: - # Secondary validation because serialised vol can't seem to handle this complexity: + # Secondary validation because serialised vol can't + # seem to handle this complexity: if not user_input.get(CONF_STILL_IMAGE_URL) and not user_input.get( CONF_STREAM_SOURCE ): @@ -429,7 +430,8 @@ class GenericOptionsFlowHandler(OptionsFlow): hass = self.hass if user_input: - # Secondary validation because serialised vol can't seem to handle this complexity: + # Secondary validation because serialised vol can't + # seem to handle this complexity: if not user_input.get(CONF_STILL_IMAGE_URL) and not user_input.get( CONF_STREAM_SOURCE ): @@ -580,7 +582,10 @@ async def ws_start_preview( ha_stream_url = None if user_input.get(CONF_STILL_IMAGE_URL): - ha_still_url = f"/api/generic/preview_flow_image/{msg['flow_id']}?t={datetime.now().isoformat()}" + ha_still_url = ( + "/api/generic/preview_flow_image" + f"/{msg['flow_id']}?t={datetime.now().isoformat()}" + ) _LOGGER.debug("Got preview still URL: %s", ha_still_url) if ha_stream := flow.preview_stream: diff --git a/homeassistant/components/generic_thermostat/climate.py b/homeassistant/components/generic_thermostat/climate.py index b31c67c6a2f6..b7141e5bcb17 100644 --- a/homeassistant/components/generic_thermostat/climate.py +++ b/homeassistant/components/generic_thermostat/climate.py @@ -696,7 +696,8 @@ class GenericThermostat(ClimateEntity, RestoreEntity): f" {self.preset_modes}" ) if preset_mode == self._attr_preset_mode: - # I don't think we need to call async_write_ha_state if we didn't change the state + # I don't think we need to call async_write_ha_state + # if we didn't change the state return if preset_mode == PRESET_NONE: self._attr_preset_mode = PRESET_NONE diff --git a/homeassistant/components/geocaching/entity.py b/homeassistant/components/geocaching/entity.py index 6912b65ec046..fb5388aa5785 100644 --- a/homeassistant/components/geocaching/entity.py +++ b/homeassistant/components/geocaching/entity.py @@ -29,8 +29,10 @@ class GeocachingCacheEntity(GeocachingBaseEntity): super().__init__(coordinator) self.cache = cache - # A device can have multiple entities, and for a cache which requires multiple entities we want to group them together. - # Therefore, we create a device for each cache, which holds all related entities. + # A device can have multiple entities, and for a cache + # which requires multiple entities we want to group them + # together. Therefore, we create a device for each cache, + # which holds all related entities. self._attr_device_info = DeviceInfo( name=f"Geocache {cache.name}", identifiers={(DOMAIN, cast(str, cache.reference_code))}, diff --git a/homeassistant/components/geocaching/oauth.py b/homeassistant/components/geocaching/oauth.py index d72a197a3a7b..06c5e62237ab 100644 --- a/homeassistant/components/geocaching/oauth.py +++ b/homeassistant/components/geocaching/oauth.py @@ -46,7 +46,8 @@ class GeocachingOAuth2Implementation(AuthImplementation): "redirect_uri": redirect_uri, } token = await self._token_request(data) - # Store the redirect_uri (Needed for refreshing token, but not according to oAuth2 spec!) + # Store the redirect_uri + # (Needed for refreshing token, but not per oAuth2 spec!) token["redirect_uri"] = redirect_uri return token @@ -57,7 +58,8 @@ class GeocachingOAuth2Implementation(AuthImplementation): "client_secret": self.client_secret, "grant_type": "refresh_token", "refresh_token": token["refresh_token"], - # Add previously stored redirect_uri (Mandatory, but not according to oAuth2 spec!) + # Add previously stored redirect_uri + # (Mandatory, but not per oAuth2 spec!) "redirect_uri": token["redirect_uri"], } diff --git a/homeassistant/components/geocaching/sensor.py b/homeassistant/components/geocaching/sensor.py index 75eade05cf1e..80e8d2cb29a0 100644 --- a/homeassistant/components/geocaching/sensor.py +++ b/homeassistant/components/geocaching/sensor.py @@ -115,7 +115,9 @@ async def async_setup_entry( # Base class for a cache entity. -# Sets the device, ID and translation settings to correctly group the entity to the correct cache device and give it the correct name. +# Sets the device, ID and translation settings to correctly +# group the entity to the correct cache device and give it +# the correct name. class GeoEntityBaseCache(GeocachingCacheEntity, SensorEntity): """Base class for cache entities.""" @@ -130,7 +132,8 @@ class GeoEntityBaseCache(GeocachingCacheEntity, SensorEntity): self._attr_unique_id = f"{cache.reference_code}_{key}" - # The translation key determines the name of the entity as this is the lookup for the `strings.json` file. + # The translation key determines the name of the entity + # as this is the lookup for the `strings.json` file. self._attr_translation_key = f"cache_{key}" diff --git a/homeassistant/components/gios/coordinator.py b/homeassistant/components/gios/coordinator.py index 95e962197665..cc7b6f6d5c2e 100644 --- a/homeassistant/components/gios/coordinator.py +++ b/homeassistant/components/gios/coordinator.py @@ -48,7 +48,8 @@ class GiosDataUpdateCoordinator(DataUpdateCoordinator[GiosSensors]): if TYPE_CHECKING: # Station ID is Optional in the library, but here we know it is set for sure # so we can safely assert it is not None for type checking purposes - # Gios instance is created only with a valid station ID in the async_setup_entry. + # Gios instance is created only with a valid station + # ID in the async_setup_entry. assert station_id is not None self.device_info = DeviceInfo( diff --git a/homeassistant/components/github/config_flow.py b/homeassistant/components/github/config_flow.py index a99ebe22dce3..9ebfdd8f4d64 100644 --- a/homeassistant/components/github/config_flow.py +++ b/homeassistant/components/github/config_flow.py @@ -143,7 +143,8 @@ class GitHubConfigFlow(ConfigFlow, domain=DOMAIN): async def _wait_for_login() -> None: if TYPE_CHECKING: - # mypy is not aware that we can't get here without having these set already + # mypy is not aware that we can't get here + # without having these set already assert self._device is not None assert self._login_device is not None diff --git a/homeassistant/components/go2rtc/__init__.py b/homeassistant/components/go2rtc/__init__.py index 3d4d6c67d747..de270c07fef0 100644 --- a/homeassistant/components/go2rtc/__init__.py +++ b/homeassistant/components/go2rtc/__init__.py @@ -74,7 +74,7 @@ _AUTH = "auth" def _validate_auth(config: dict) -> dict: - """Validate that username and password are only set when a URL is configured or when debug UI is enabled.""" + """Validate username/password only when URL is configured or debug UI enabled.""" auth_exists = CONF_USERNAME in config debug_ui_enabled = config.get(CONF_DEBUG_UI, False) @@ -83,7 +83,8 @@ def _validate_auth(config: dict) -> dict: if auth_exists and CONF_URL not in config and not debug_ui_enabled: raise vol.Invalid( - "Username and password can only be set when a URL is configured or debug_ui is true" + "Username and password can only be set when a URL is" + " configured or debug_ui is true" ) return config @@ -363,7 +364,8 @@ class WebRTCProvider(CameraWebRTCProvider): if camera.platform.platform_name == "generic": # This is a workaround to use ffmpeg for generic cameras - # A proper fix will be added in the future together with supporting multiple streams per camera + # A proper fix will be added in the future together + # with supporting multiple streams per camera stream_source = "ffmpeg:" + stream_source if not self.async_is_supported(stream_source): @@ -407,7 +409,8 @@ class WebRTCProvider(CameraWebRTCProvider): [ stream_source, # We are setting any ffmpeg rtsp related logs to debug - # Connection problems to the camera will be logged by the first stream + # Connection problems to the camera will be + # logged by the first stream # Therefore setting it to debug will not hide any important logs f"ffmpeg:{identifier}#audio=opus#query=log_level=debug", ], diff --git a/homeassistant/components/goodwe/__init__.py b/homeassistant/components/goodwe/__init__.py index d191ecb15a29..f1ac6fe758fe 100644 --- a/homeassistant/components/goodwe/__init__.py +++ b/homeassistant/components/goodwe/__init__.py @@ -64,7 +64,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: GoodweConfigEntry) -> bo async def async_check_port( hass: HomeAssistant, entry: GoodweConfigEntry, host: str ) -> Inverter: - """Check the communication port of the inverter, it may have changed after a firmware update.""" + """Check the communication port of the inverter. + + It may have changed after a firmware update. + """ inverter, port = await GoodweFlowHandler.async_detect_inverter_port(host=host) family = type(inverter).__name__ hass.config_entries.async_update_entry( diff --git a/homeassistant/components/goodwe/select.py b/homeassistant/components/goodwe/select.py index 7a28a632060c..505708b518b1 100644 --- a/homeassistant/components/goodwe/select.py +++ b/homeassistant/components/goodwe/select.py @@ -69,7 +69,8 @@ async def async_setup_entry( ) else: _LOGGER.warning( - "Active mode %s not found in Goodwe Inverter Operation Mode Entity. Skipping entity creation", + "Active mode %s not found in Goodwe Inverter Operation" + " Mode Entity. Skipping entity creation", active_mode, ) diff --git a/homeassistant/components/goodwe/sensor.py b/homeassistant/components/goodwe/sensor.py index 3eae0e644981..c23e6ff07744 100644 --- a/homeassistant/components/goodwe/sensor.py +++ b/homeassistant/components/goodwe/sensor.py @@ -48,10 +48,16 @@ _LOGGER = logging.getLogger(__name__) BATTERY_SOC = "battery_soc" # Sensors that are reset to 0 at midnight. -# The inverter is only powered by the solar panels and not mains power, so it goes dead when the sun goes down. -# The "_day" sensors are reset to 0 when the inverter wakes up in the morning when the sun comes up and power to the inverter is restored. -# This makes sure daily values are reset at midnight instead of at sunrise. -# When the inverter has a battery connected, HomeAssistant will not reset the values but let the inverter reset them by looking at the unavailable state of the inverter. +# The inverter is only powered by the solar panels and not +# mains power, so it goes dead when the sun goes down. +# The "_day" sensors are reset to 0 when the inverter wakes +# up in the morning when the sun comes up and power to the +# inverter is restored. +# This makes sure daily values are reset at midnight instead +# of at sunrise. +# When the inverter has a battery connected, HomeAssistant +# will not reset the values but let the inverter reset them +# by looking at the unavailable state of the inverter. DAILY_RESET = ["e_day", "e_load_day"] _MAIN_SENSORS = ( @@ -242,7 +248,8 @@ class InverterSensor(CoordinatorEntity[GoodweUpdateCoordinator], SensorEntity): Some sensors values like daily produced energy are kept available, even when the inverter is in sleep mode and no longer responds to request. - In contrast to "total" sensors, these "daily" sensors need to be reset to 0 on midnight. + In contrast to "total" sensors, these "daily" sensors + need to be reset to 0 on midnight. """ if not self.coordinator.last_update_success: self.coordinator.reset_sensor(self._sensor.id_) diff --git a/homeassistant/components/google/calendar.py b/homeassistant/components/google/calendar.py index 107353926342..a009efa98612 100644 --- a/homeassistant/components/google/calendar.py +++ b/homeassistant/components/google/calendar.py @@ -510,7 +510,8 @@ class GoogleCalendarEntity( def _get_calendar_event(event: Event) -> CalendarEvent: """Return a CalendarEvent from an API event.""" rrule: str | None = None - # Home Assistant expects a single RRULE: and all other rule types are unsupported or ignored + # Home Assistant expects a single RRULE: and all other + # rule types are unsupported or ignored if ( len(event.recurrence) == 1 and (raw_rule := event.recurrence[0]) diff --git a/homeassistant/components/google/config_flow.py b/homeassistant/components/google/config_flow.py index 418cdc689643..12594979e6ee 100644 --- a/homeassistant/components/google/config_flow.py +++ b/homeassistant/components/google/config_flow.py @@ -192,7 +192,8 @@ class OAuth2FlowHandler( primary_calendar = await calendar_service.async_get_calendar("primary") except ApiForbiddenException as err: _LOGGER.error( - "Error reading primary calendar, make sure Google Calendar API is enabled: %s", + "Error reading primary calendar, make sure" + " Google Calendar API is enabled: %s", err, ) return self.async_abort( diff --git a/homeassistant/components/google_air_quality/config_flow.py b/homeassistant/components/google_air_quality/config_flow.py index b1dffebaf3aa..e59c5f348404 100644 --- a/homeassistant/components/google_air_quality/config_flow.py +++ b/homeassistant/components/google_air_quality/config_flow.py @@ -91,7 +91,8 @@ def _is_location_already_configured( for subentry in entry.subentries.values(): # A more accurate way is to use the haversine formula, but for simplicity # we use a simple distance check. The epsilon value is small anyway. - # This is mostly to capture cases where the user has slightly moved the location pin. + # This is mostly to capture cases where the user + # has slightly moved the location pin. if ( abs(subentry.data[CONF_LATITUDE] - new_data[CONF_LATITUDE]) <= epsilon and abs(subentry.data[CONF_LONGITUDE] - new_data[CONF_LONGITUDE]) diff --git a/homeassistant/components/google_air_quality/sensor.py b/homeassistant/components/google_air_quality/sensor.py index 676619005064..f731991fa1af 100644 --- a/homeassistant/components/google_air_quality/sensor.py +++ b/homeassistant/components/google_air_quality/sensor.py @@ -234,7 +234,11 @@ class AirQualitySensorEntity( """Set up Air Quality Sensors.""" super().__init__(coordinator) self.entity_description = description - self._attr_unique_id = f"{description.key}_{subentry.data[CONF_LATITUDE]}_{subentry.data[CONF_LONGITUDE]}" + self._attr_unique_id = ( + f"{description.key}" + f"_{subentry.data[CONF_LATITUDE]}" + f"_{subentry.data[CONF_LONGITUDE]}" + ) self._attr_device_info = DeviceInfo( identifiers={ (DOMAIN, f"{self.coordinator.config_entry.entry_id}_{subentry_id}") diff --git a/homeassistant/components/google_assistant/helpers.py b/homeassistant/components/google_assistant/helpers.py index a623ce56f6af..72d9c7bb089f 100644 --- a/homeassistant/components/google_assistant/helpers.py +++ b/homeassistant/components/google_assistant/helpers.py @@ -172,7 +172,7 @@ class AbstractConfig(ABC): @abstractmethod def get_local_webhook_id(self, agent_user_id): - """Return the webhook ID to be used for actions for a given agent user id via the local SDK.""" + """Return the webhook ID for a given agent user id via the local SDK.""" @abstractmethod def get_agent_user_id_from_context(self, context): @@ -425,7 +425,8 @@ class AbstractConfig(ABC): ) if (agent_user_id := self.get_agent_user_id_from_webhook(webhook_id)) is None: - # No agent user linked to this webhook, means that the user has somehow unregistered + # No agent user linked to this webhook, means that + # the user has somehow unregistered # removing webhook and stopping processing of this request. _LOGGER.error( ( diff --git a/homeassistant/components/google_assistant/http.py b/homeassistant/components/google_assistant/http.py index 961c9d3d3457..fb0ce07b345a 100644 --- a/homeassistant/components/google_assistant/http.py +++ b/homeassistant/components/google_assistant/http.py @@ -138,7 +138,7 @@ class GoogleConfig(AbstractConfig): return found_agent_user_id def get_local_webhook_id(self, agent_user_id): - """Return the webhook ID to be used for actions for a given agent user id via the local SDK.""" + """Return the webhook ID for a given agent user id via the local SDK.""" if data := self._store.agent_user_ids.get(agent_user_id): return data[STORE_GOOGLE_LOCAL_WEBHOOK_ID] return None @@ -323,7 +323,8 @@ class GoogleConfigStore: if (data := await self._store.async_load()) is None: # if the store is not found create an empty one # Note that the first request is always a cloud request, - # and that will store the correct agent user id to be used for local requests + # and that will store the correct agent user id + # to be used for local requests data = { STORE_AGENT_USER_IDS: {}, } diff --git a/homeassistant/components/google_assistant/report_state.py b/homeassistant/components/google_assistant/report_state.py index bcfa2896b376..c95defaddef6 100644 --- a/homeassistant/components/google_assistant/report_state.py +++ b/homeassistant/components/google_assistant/report_state.py @@ -57,7 +57,8 @@ def async_enable_report_state( {"devices": {"states": pending.popleft()}} ) - # If things got queued up in last batch while we were reporting, schedule ourselves again + # If things got queued up in last batch while we were + # reporting, schedule ourselves again if pending[0]: unsub_pending = async_call_later( hass, REPORT_STATE_WINDOW, report_states_job @@ -111,8 +112,8 @@ def async_enable_report_state( result = await google_config.async_sync_notification_all(event_id, payload) if result != 200: _LOGGER.error( - "Unable to send notification with result code: %s, check log for more" - " info", + "Unable to send notification with result" + " code: %s, check log for more info", result, ) @@ -129,7 +130,8 @@ def async_enable_report_state( _LOGGER.debug("Scheduling report state for %s: %s", changed_entity, entity_data) - # If a significant change is already scheduled and we have another significant one, + # If a significant change is already scheduled and we + # have another significant one, # let's create a new batch of changes if changed_entity in pending[-1]: pending.append({}) diff --git a/homeassistant/components/google_assistant/trait.py b/homeassistant/components/google_assistant/trait.py index e0a4e6f514cd..26a11eed54ab 100644 --- a/homeassistant/components/google_assistant/trait.py +++ b/homeassistant/components/google_assistant/trait.py @@ -1637,7 +1637,9 @@ class ArmDisArmTrait(_Trait): AlarmControlPanelState.ARMED_HOME: AlarmControlPanelEntityFeature.ARM_HOME, AlarmControlPanelState.ARMED_NIGHT: AlarmControlPanelEntityFeature.ARM_NIGHT, AlarmControlPanelState.ARMED_AWAY: AlarmControlPanelEntityFeature.ARM_AWAY, - AlarmControlPanelState.ARMED_CUSTOM_BYPASS: AlarmControlPanelEntityFeature.ARM_CUSTOM_BYPASS, + AlarmControlPanelState.ARMED_CUSTOM_BYPASS: ( + AlarmControlPanelEntityFeature.ARM_CUSTOM_BYPASS + ), AlarmControlPanelState.TRIGGERED: AlarmControlPanelEntityFeature.TRIGGER, } """The list of states to support in increasing security state.""" diff --git a/homeassistant/components/google_assistant_sdk/helpers.py b/homeassistant/components/google_assistant_sdk/helpers.py index 7d1b457fdc2b..9aecb871a907 100644 --- a/homeassistant/components/google_assistant_sdk/helpers.py +++ b/homeassistant/components/google_assistant_sdk/helpers.py @@ -137,7 +137,11 @@ def default_language_code(hass: HomeAssistant) -> str: def best_matching_language_code( hass: HomeAssistant, assist_language: str, agent_language: str | None = None ) -> str: - """Get the best matching language, based on the preferred assist language and the configured agent language.""" + """Get the best matching language. + + Based on the preferred assist language and the configured + agent language. + """ # Use the assist language if supported if assist_language in SUPPORTED_LANGUAGE_CODES: diff --git a/homeassistant/components/google_cloud/helpers.py b/homeassistant/components/google_cloud/helpers.py index f6fd4bce7a06..8dae604a1cc4 100644 --- a/homeassistant/components/google_cloud/helpers.py +++ b/homeassistant/components/google_cloud/helpers.py @@ -62,7 +62,8 @@ def tts_options_schema( """Return schema for TTS options with default values from config or constants.""" # If we are called from the config flow we want the defaults to be from constants # to allow clearing the current value (passed as suggested_value) in the UI. - # If we aren't called from the config flow we want the defaults to be from the config. + # If we aren't called from the config flow we want the + # defaults to be from the config. defaults = {} if from_config_flow else config_options return vol.Schema( { diff --git a/homeassistant/components/google_cloud/tts.py b/homeassistant/components/google_cloud/tts.py index 34a35cf83638..b009fb0dbbbc 100644 --- a/homeassistant/components/google_cloud/tts.py +++ b/homeassistant/components/google_cloud/tts.py @@ -193,7 +193,8 @@ class BaseGoogleCloudProvider: ssml_gender=gender, name=voice, ), - # Avoid: "This voice does not support speaking rate or pitch parameters at this time." + # Avoid: "This voice does not support speaking rate + # or pitch parameters at this time." # by not specifying the fields unless they differ from the defaults audio_config=texttospeech.AudioConfig( audio_encoding=encoding, diff --git a/homeassistant/components/google_drive/__init__.py b/homeassistant/components/google_drive/__init__.py index 1d0293048956..9a2bf25c83b1 100644 --- a/homeassistant/components/google_drive/__init__.py +++ b/homeassistant/components/google_drive/__init__.py @@ -42,7 +42,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: GoogleDriveConfigEntry) OAuth2Session(hass, entry, implementation), ) - # Test we can refresh the token and raise ConfigEntryAuthFailed or ConfigEntryNotReady if not + # Test we can refresh the token and raise + # ConfigEntryAuthFailed or ConfigEntryNotReady if not await auth.async_get_access_token() client = DriveClient(await instance_id.async_get(hass), auth) diff --git a/homeassistant/components/google_drive/api.py b/homeassistant/components/google_drive/api.py index d780cce7f0d0..d24b05276aaf 100644 --- a/homeassistant/components/google_drive/api.py +++ b/homeassistant/components/google_drive/api.py @@ -132,7 +132,8 @@ class DriveClient: query = " and ".join( [ "properties has { key='home_assistant' and value='root' }", - f"properties has {{ key='instance_id' and value='{self._ha_instance_id}' }}", + "properties has { key='instance_id'" + f" and value='{self._ha_instance_id}' }}", "trashed=false", ] ) @@ -196,7 +197,8 @@ class DriveClient: query = " and ".join( [ "properties has { key='home_assistant' and value='backup' }", - f"properties has {{ key='instance_id' and value='{self._ha_instance_id}' }}", + "properties has { key='instance_id'" + f" and value='{self._ha_instance_id}' }}", "trashed=false", ] ) @@ -220,7 +222,8 @@ class DriveClient: query = " and ".join( [ "properties has { key='home_assistant' and value='backup' }", - f"properties has {{ key='instance_id' and value='{self._ha_instance_id}' }}", + "properties has { key='instance_id'" + f" and value='{self._ha_instance_id}' }}", f"properties has {{ key='backup_id' and value='{backup_id}' }}", ] ) diff --git a/homeassistant/components/google_generative_ai_conversation/ai_task.py b/homeassistant/components/google_generative_ai_conversation/ai_task.py index e90c067204e3..be34e09161d3 100644 --- a/homeassistant/components/google_generative_ai_conversation/ai_task.py +++ b/homeassistant/components/google_generative_ai_conversation/ai_task.py @@ -86,7 +86,8 @@ class GoogleGenerativeAITaskEntity( if not isinstance(chat_log.content[-1], conversation.AssistantContent): LOGGER.error( - "Last content in chat log is not an AssistantContent: %s. This could be due to the model not returning a valid response", + "Last content in chat log is not an AssistantContent: %s." + " This could be due to the model not returning a valid response", chat_log.content[-1], ) raise HomeAssistantError(ERROR_GETTING_RESPONSE) @@ -149,7 +150,9 @@ class GoogleGenerativeAITaskEntity( if response.prompt_feedback: raise HomeAssistantError( - f"Error generating content due to content violations, reason: {response.prompt_feedback.block_reason_message}" + "Error generating content due to content" + " violations, reason:" + f" {response.prompt_feedback.block_reason_message}" ) if ( diff --git a/homeassistant/components/google_generative_ai_conversation/config_flow.py b/homeassistant/components/google_generative_ai_conversation/config_flow.py index 70b5d830f979..1126b6c9ad8a 100644 --- a/homeassistant/components/google_generative_ai_conversation/config_flow.py +++ b/homeassistant/components/google_generative_ai_conversation/config_flow.py @@ -254,7 +254,8 @@ class LLMSubentryFlowHandler(ConfigSubentryFlow): if user_input[CONF_RECOMMENDED] == self.last_rendered_recommended: if not user_input.get(CONF_LLM_HASS_API): user_input.pop(CONF_LLM_HASS_API, None) - # Don't allow to save options that enable the Google Search tool with an Assist API + # Don't allow to save options that enable the + # Google Search tool with an Assist API if not ( user_input.get(CONF_LLM_HASS_API) and user_input.get(CONF_USE_GOOGLE_SEARCH_TOOL, False) is True diff --git a/homeassistant/components/google_generative_ai_conversation/entity.py b/homeassistant/components/google_generative_ai_conversation/entity.py index 2b36fbeca768..8ac090916334 100644 --- a/homeassistant/components/google_generative_ai_conversation/entity.py +++ b/homeassistant/components/google_generative_ai_conversation/entity.py @@ -368,7 +368,9 @@ async def _transform_stream( thinking_content_index = 0 tool_call_index = 0 - # According to the API docs, this would mean no candidate is returned, so we can safely throw an error here. + # According to the API docs, this would mean no + # candidate is returned, so we can safely throw + # an error here. if response.prompt_feedback or not response.candidates: reason = ( response.prompt_feedback.block_reason_message @@ -376,7 +378,8 @@ async def _transform_stream( else "unknown" ) raise HomeAssistantError( - f"The message got blocked due to content violations, reason: {reason}" + "The message got blocked due to content" + f" violations, reason: {reason}" ) candidate = response.candidates[0] @@ -510,9 +513,11 @@ class GoogleGenerativeAILLMBaseEntity(Entity): for tool in chat_log.llm_api.tools ] - # Using search grounding allows the model to retrieve information from the web, - # however, it may interfere with how the model decides to use some tools, or entities - # for example weather entity may be disregarded if the model chooses to Google it. + # Using search grounding allows the model to retrieve + # information from the web, however, it may interfere + # with how the model decides to use some tools, or + # entities for example weather entity may be + # disregarded if the model chooses to Google it. if options.get(CONF_USE_GOOGLE_SEARCH_TOOL) is True: tools = tools or [] tools.append(Tool(google_search=GoogleSearch())) @@ -548,8 +553,11 @@ class GoogleGenerativeAILLMBaseEntity(Entity): not isinstance(chat_content, conversation.ToolResultContent) and chat_content.content == "" ): - # Skipping is not possible since the number of function calls need to match the number of function responses - # and skipping one would mean removing the other and hence this would prevent a proper chat log + # Skipping is not possible since the number of + # function calls need to match the number of + # function responses and skipping one would + # mean removing the other and hence this would + # prevent a proper chat log chat_content = replace(chat_content, content=" ") if tool_results: @@ -748,7 +756,9 @@ async def async_prepare_files_for_prompt( if uploaded_file.state == FileState.FAILED: raise HomeAssistantError( - f"File `{uploaded_file.name}` processing failed, reason: {uploaded_file.error.message if uploaded_file.error else 'unknown'}" + f"File `{uploaded_file.name}` processing" + " failed, reason:" + f" {uploaded_file.error.message if uploaded_file.error else 'unknown'}" ) prompt_parts = await hass.async_add_executor_job(upload_files) diff --git a/homeassistant/components/google_generative_ai_conversation/helpers.py b/homeassistant/components/google_generative_ai_conversation/helpers.py index 7942335a0697..9ee6a3672230 100644 --- a/homeassistant/components/google_generative_ai_conversation/helpers.py +++ b/homeassistant/components/google_generative_ai_conversation/helpers.py @@ -59,7 +59,8 @@ def _parse_audio_mime_type(mime_type: str) -> dict[str, int]: for param in parts: # Skip the main type part param = param.strip() if param.lower().startswith("rate="): - # Handle cases like "rate=" with no value or non-integer value and keep rate as default + # Handle cases like "rate=" with no value or + # non-integer value and keep rate as default with suppress(ValueError, IndexError): rate_str = param.split("=", 1)[1] rate = int(rate_str) diff --git a/homeassistant/components/google_generative_ai_conversation/stt.py b/homeassistant/components/google_generative_ai_conversation/stt.py index efd5f4f72b88..0e79d112e173 100644 --- a/homeassistant/components/google_generative_ai_conversation/stt.py +++ b/homeassistant/components/google_generative_ai_conversation/stt.py @@ -216,8 +216,10 @@ class GoogleGenerativeAISttEntity( @property def supported_channels(self) -> list[stt.AudioChannels]: """Return a list of supported channels.""" - # Per https://ai.google.dev/gemini-api/docs/audio - # If the audio source contains multiple channels, Gemini combines those channels into a single channel. + # Per + # https://ai.google.dev/gemini-api/docs/audio + # If the audio source contains multiple channels, + # Gemini combines those channels into a single channel. return [stt.AudioChannels.CHANNEL_MONO] async def async_process_audio_stream( diff --git a/homeassistant/components/google_photos/media_source.py b/homeassistant/components/google_photos/media_source.py index 81f89694549b..1b4dcb80d57c 100644 --- a/homeassistant/components/google_photos/media_source.py +++ b/homeassistant/components/google_photos/media_source.py @@ -111,7 +111,8 @@ class GooglePhotosMediaSource(MediaSource): async def async_resolve_media(self, item: MediaSourceItem) -> PlayMedia: """Resolve media identifier to a url. - This will resolve a specific media item to a url for the full photo or video contents. + This will resolve a specific media item to a url for + the full photo or video contents. """ try: identifier = PhotosIdentifier.of(item.identifier) @@ -282,7 +283,9 @@ def _build_media_item( def _media_url(media_item: MediaItem, max_size: int) -> str: - """Return a media item url with the specified max thumbnail size on the longest edge. + """Return a media item url with the specified max thumbnail size. + + The size applies to the longest edge. See https://developers.google.com/photos/library/guides/access-media-items#base-urls """ diff --git a/homeassistant/components/google_tasks/api.py b/homeassistant/components/google_tasks/api.py index f51c5103b87a..4b1cca8089d3 100644 --- a/homeassistant/components/google_tasks/api.py +++ b/homeassistant/components/google_tasks/api.py @@ -116,7 +116,8 @@ class AsyncConfigEntryAuth: def response_handler(_, response, exception: HttpError) -> None: if exception is not None: raise GoogleTasksApiError( - f"Google Tasks API responded with error ({exception.reason or exception.status_code})" + "Google Tasks API responded with error" + f" ({exception.reason or exception.status_code})" ) from exception if response: data = json.loads(response) diff --git a/homeassistant/components/google_travel_time/__init__.py b/homeassistant/components/google_travel_time/__init__.py index c1b6a4919818..d8ac5eeef493 100644 --- a/homeassistant/components/google_travel_time/__init__.py +++ b/homeassistant/components/google_travel_time/__init__.py @@ -57,7 +57,9 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> ) except ValueError: _LOGGER.error( - "Invalid time format found while migrating: %s. The old config never worked. Reset to default (empty)", + "Invalid time format found while migrating: %s." + " The old config never worked." + " Reset to default (empty)", options[CONF_TIME], ) options[CONF_TIME] = None diff --git a/homeassistant/components/google_weather/config_flow.py b/homeassistant/components/google_weather/config_flow.py index 8e52116f7211..2d2cb21c628f 100644 --- a/homeassistant/components/google_weather/config_flow.py +++ b/homeassistant/components/google_weather/config_flow.py @@ -97,7 +97,8 @@ def _is_location_already_configured( continue # A more accurate way is to use the haversine formula, but for simplicity # we use a simple distance check. The epsilon value is small anyway. - # This is mostly to capture cases where the user has slightly moved the location pin. + # This is mostly to capture cases where the user + # has slightly moved the location pin. if ( abs(subentry.data[CONF_LATITUDE] - new_data[CONF_LATITUDE]) <= epsilon and abs(subentry.data[CONF_LONGITUDE] - new_data[CONF_LONGITUDE]) diff --git a/homeassistant/components/google_weather/diagnostics.py b/homeassistant/components/google_weather/diagnostics.py index 61fc9144f1ce..36755b9a5de8 100644 --- a/homeassistant/components/google_weather/diagnostics.py +++ b/homeassistant/components/google_weather/diagnostics.py @@ -34,9 +34,11 @@ async def async_get_config_entry_diagnostics( "daily_forecast_data": subentry_rt.coordinator_daily_forecast.data.to_dict() if subentry_rt.coordinator_daily_forecast.data else None, - "hourly_forecast_data": subentry_rt.coordinator_hourly_forecast.data.to_dict() - if subentry_rt.coordinator_hourly_forecast.data - else None, + "hourly_forecast_data": ( + subentry_rt.coordinator_hourly_forecast.data.to_dict() + if subentry_rt.coordinator_hourly_forecast.data + else None + ), } return async_redact_data(diag_data, TO_REDACT) diff --git a/homeassistant/components/google_weather/weather.py b/homeassistant/components/google_weather/weather.py index c822e5205553..63b3b53b32c3 100644 --- a/homeassistant/components/google_weather/weather.py +++ b/homeassistant/components/google_weather/weather.py @@ -264,7 +264,9 @@ class GoogleWeatherEntity( ATTR_FORECAST_NATIVE_APPARENT_TEMP: ( item.feels_like_max_temperature.degrees ), - ATTR_FORECAST_WIND_BEARING: item.daytime_forecast.wind.direction.degrees, + ATTR_FORECAST_WIND_BEARING: ( + item.daytime_forecast.wind.direction.degrees + ), ATTR_FORECAST_NATIVE_WIND_GUST_SPEED: max( item.daytime_forecast.wind.gust.value, item.nighttime_forecast.wind.gust.value, @@ -292,10 +294,14 @@ class GoogleWeatherEntity( ), ATTR_FORECAST_TIME: item.interval.start_time, ATTR_FORECAST_HUMIDITY: item.relative_humidity, - ATTR_FORECAST_PRECIPITATION_PROBABILITY: item.precipitation.probability.percent, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: ( + item.precipitation.probability.percent + ), ATTR_FORECAST_CLOUD_COVERAGE: item.cloud_cover, ATTR_FORECAST_NATIVE_PRECIPITATION: item.precipitation.qpf.quantity, - ATTR_FORECAST_NATIVE_PRESSURE: item.air_pressure.mean_sea_level_millibars, + ATTR_FORECAST_NATIVE_PRESSURE: ( + item.air_pressure.mean_sea_level_millibars + ), ATTR_FORECAST_NATIVE_TEMP: item.temperature.degrees, ATTR_FORECAST_NATIVE_APPARENT_TEMP: item.feels_like_temperature.degrees, ATTR_FORECAST_WIND_BEARING: item.wind.direction.degrees, @@ -326,11 +332,17 @@ class GoogleWeatherEntity( ), ATTR_FORECAST_TIME: day_forecast.interval.start_time, ATTR_FORECAST_HUMIDITY: day_forecast.relative_humidity, - ATTR_FORECAST_PRECIPITATION_PROBABILITY: day_forecast.precipitation.probability.percent, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: ( + day_forecast.precipitation.probability.percent + ), ATTR_FORECAST_CLOUD_COVERAGE: day_forecast.cloud_cover, - ATTR_FORECAST_NATIVE_PRECIPITATION: day_forecast.precipitation.qpf.quantity, + ATTR_FORECAST_NATIVE_PRECIPITATION: ( + day_forecast.precipitation.qpf.quantity + ), ATTR_FORECAST_NATIVE_TEMP: item.max_temperature.degrees, - ATTR_FORECAST_NATIVE_APPARENT_TEMP: item.feels_like_max_temperature.degrees, + ATTR_FORECAST_NATIVE_APPARENT_TEMP: ( + item.feels_like_max_temperature.degrees + ), ATTR_FORECAST_WIND_BEARING: day_forecast.wind.direction.degrees, ATTR_FORECAST_NATIVE_WIND_GUST_SPEED: day_forecast.wind.gust.value, ATTR_FORECAST_NATIVE_WIND_SPEED: day_forecast.wind.speed.value, @@ -348,13 +360,21 @@ class GoogleWeatherEntity( ), ATTR_FORECAST_TIME: night_forecast.interval.start_time, ATTR_FORECAST_HUMIDITY: night_forecast.relative_humidity, - ATTR_FORECAST_PRECIPITATION_PROBABILITY: night_forecast.precipitation.probability.percent, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: ( + night_forecast.precipitation.probability.percent + ), ATTR_FORECAST_CLOUD_COVERAGE: night_forecast.cloud_cover, - ATTR_FORECAST_NATIVE_PRECIPITATION: night_forecast.precipitation.qpf.quantity, + ATTR_FORECAST_NATIVE_PRECIPITATION: ( + night_forecast.precipitation.qpf.quantity + ), ATTR_FORECAST_NATIVE_TEMP: item.min_temperature.degrees, - ATTR_FORECAST_NATIVE_APPARENT_TEMP: item.feels_like_min_temperature.degrees, + ATTR_FORECAST_NATIVE_APPARENT_TEMP: ( + item.feels_like_min_temperature.degrees + ), ATTR_FORECAST_WIND_BEARING: night_forecast.wind.direction.degrees, - ATTR_FORECAST_NATIVE_WIND_GUST_SPEED: night_forecast.wind.gust.value, + ATTR_FORECAST_NATIVE_WIND_GUST_SPEED: ( + night_forecast.wind.gust.value + ), ATTR_FORECAST_NATIVE_WIND_SPEED: night_forecast.wind.speed.value, ATTR_FORECAST_UV_INDEX: night_forecast.uv_index, ATTR_FORECAST_IS_DAYTIME: False, diff --git a/homeassistant/components/govee_ble/config_flow.py b/homeassistant/components/govee_ble/config_flow.py index 8bc2ee149270..568c72a17dec 100644 --- a/homeassistant/components/govee_ble/config_flow.py +++ b/homeassistant/components/govee_ble/config_flow.py @@ -94,7 +94,10 @@ class GoveeConfigFlow(ConfigFlow, domain=DOMAIN): { vol.Required(CONF_ADDRESS): vol.In( { - address: f"{device.get_device_name(None) or discovery_info.name} ({address})" + address: ( + f"{device.get_device_name(None) or discovery_info.name}" + f" ({address})" + ) for address, ( device, discovery_info, diff --git a/homeassistant/components/govee_ble/coordinator.py b/homeassistant/components/govee_ble/coordinator.py index 011a89e565bb..f75c0c95ff93 100644 --- a/homeassistant/components/govee_ble/coordinator.py +++ b/homeassistant/components/govee_ble/coordinator.py @@ -27,7 +27,10 @@ def process_service_info( entry: GoveeBLEConfigEntry, service_info: BluetoothServiceInfoBleak, ) -> SensorUpdate: - """Process a BluetoothServiceInfoBleak, running side effects and returning sensor data.""" + """Process a BluetoothServiceInfoBleak. + + Runs side effects and returns sensor data. + """ coordinator = entry.runtime_data data = coordinator.device_data update = data.update(service_info) diff --git a/homeassistant/components/gree/coordinator.py b/homeassistant/components/gree/coordinator.py index d1d3ec2a091d..21a66dffb42d 100644 --- a/homeassistant/components/gree/coordinator.py +++ b/homeassistant/components/gree/coordinator.py @@ -94,7 +94,8 @@ class DeviceDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): f"Device {self.name} is unavailable, could not send update request" ) from error else: - # raise update failed if time for more than MAX_ERRORS has passed since last update + # raise update failed if time for more than + # MAX_ERRORS has passed since last update now = utcnow() elapsed_success = now - self._last_response_time if self.update_interval and elapsed_success >= timedelta( @@ -115,7 +116,8 @@ class DeviceDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): self._error_count = 0 if self.last_update_success and self._error_count >= MAX_ERRORS: raise UpdateFailed( - f"Device {self.name} is unresponsive for too long and now unavailable" + f"Device {self.name} is unresponsive for" + " too long and now unavailable" ) self._last_response_time = utcnow() diff --git a/homeassistant/components/group/lock.py b/homeassistant/components/group/lock.py index 8f2d833e8505..72539d882d91 100644 --- a/homeassistant/components/group/lock.py +++ b/homeassistant/components/group/lock.py @@ -142,7 +142,8 @@ class LockGroup(GroupEntity, LockEntity): self._attr_is_unlocking = None self._attr_is_locked = None else: - # Set attributes based on member states and let the lock entity sort out the correct state + # Set attributes based on member states and let the + # lock entity sort out the correct state self._attr_is_jammed = LockState.JAMMED in states self._attr_is_locking = LockState.LOCKING in states self._attr_is_opening = LockState.OPENING in states diff --git a/homeassistant/components/group/sensor.py b/homeassistant/components/group/sensor.py index cd6ee5db4dae..5117a9096de1 100644 --- a/homeassistant/components/group/sensor.py +++ b/homeassistant/components/group/sensor.py @@ -1,4 +1,7 @@ -"""Platform allowing several sensors to be grouped into one sensor to provide numeric combinations.""" +"""Platform allowing several sensors to be grouped into one sensor. + +Provides numeric combinations. +""" from collections.abc import Callable from datetime import datetime @@ -399,7 +402,8 @@ class SensorGroup(GroupEntity, SensorEntity): numeric_state = float(state.state) uom = state.attributes.get("unit_of_measurement") - # Convert the state to the native unit of measurement when we have valid units + # Convert the state to the native unit of + # measurement when we have valid units # and a correct device class if valid_units and uom in valid_units and self._can_convert is True: numeric_state = UNIT_CONVERTERS[self.device_class].convert( @@ -439,10 +443,14 @@ class SensorGroup(GroupEntity, SensorEntity): if entity_id not in self._state_incorrect: self._state_incorrect.add(entity_id) _LOGGER.warning( - "Unable to use state. Only entities with correct unit of measurement" + "Unable to use state. Only entities" + " with correct unit of measurement" " is supported," - " entity %s, value %s with device class %s" - " and unit of measurement %s excluded from calculation in %s", + " entity %s, value %s with" + " device class %s" + " and unit of measurement %s" + " excluded from calculation" + " in %s", entity_id, state.state, self.device_class, @@ -507,7 +515,8 @@ class SensorGroup(GroupEntity, SensorEntity): if not self._ignore_non_numeric and len(valid_state_entities) < len( self._entity_ids ): - # Only return state class if all states are valid when not ignoring non numeric + # Only return state class if all states are valid + # when not ignoring non numeric return None state_classes: list[SensorStateClass] = [] @@ -562,7 +571,8 @@ class SensorGroup(GroupEntity, SensorEntity): if not self._ignore_non_numeric and len(valid_state_entities) < len( self._entity_ids ): - # Only return device class if all states are valid when not ignoring non numeric + # Only return device class if all states are valid + # when not ignoring non numeric return None device_classes: list[SensorDeviceClass] = [] @@ -618,7 +628,8 @@ class SensorGroup(GroupEntity, SensorEntity): if not self._ignore_non_numeric and len(valid_state_entities) < len( self._entity_ids ): - # Only return device class if all states are valid when not ignoring non numeric + # Only return device class if all states are valid + # when not ignoring non numeric return None unit_of_measurements: list[str] = [] @@ -631,7 +642,8 @@ class SensorGroup(GroupEntity, SensorEntity): return None unit_of_measurements.append(_unit_of_measurement) - # Ensure only valid unit of measurements for the specific device class can be used + # Ensure only valid unit of measurements for the + # specific device class can be used if ( ( # Test if uom's in device class is convertible diff --git a/homeassistant/components/group/util.py b/homeassistant/components/group/util.py index 6af7198f1b78..be79af99f7f1 100644 --- a/homeassistant/components/group/util.py +++ b/homeassistant/components/group/util.py @@ -32,7 +32,7 @@ def mean_tuple(*args: Any) -> tuple[float | Any, ...]: def mean_circle(*args: Any) -> tuple[float | Any, ...]: - """Return the circular mean of hue values and arithmetic mean of saturation values from HS color tuples.""" + """Return circular mean of hue and arithmetic mean of saturation from HS tuples.""" if not args: return () diff --git a/homeassistant/components/growatt_server/__init__.py b/homeassistant/components/growatt_server/__init__.py index 1833d914de6d..e416b93c73dc 100644 --- a/homeassistant/components/growatt_server/__init__.py +++ b/homeassistant/components/growatt_server/__init__.py @@ -88,7 +88,8 @@ async def async_migrate_entry( achieve: Migration: login() → plant_list() → [cache API instance] Setup: [reuse cached API] → device_list() - This reduces to just 1 login() call during the migration+setup cycle and prevent account lockout. + This reduces to just 1 login() call during the + migration+setup cycle and prevent account lockout. """ _LOGGER.debug( "Migrating config entry from version %s.%s", @@ -125,7 +126,8 @@ async def async_migrate_entry( # Handle DEFAULT_PLANT_ID resolution if config.get(CONF_PLANT_ID) == DEFAULT_PLANT_ID: - # V1 API should never have DEFAULT_PLANT_ID (plant selection happens in config flow) + # V1 API should never have DEFAULT_PLANT_ID + # (plant selection happens in config flow) # If it does, this indicates a corrupted config entry if config.get(CONF_AUTH_TYPE) == AUTH_API_TOKEN: _LOGGER.error( @@ -260,7 +262,8 @@ def get_device_list_v1( f"Authentication failed for Growatt API: {e.error_msg or str(e)}" ) from e raise ConfigEntryError( - f"API error during device list: {e.error_msg or str(e)} (Code: {e.error_code})" + f"API error during device list: {e.error_msg or str(e)}" + f" (Code: {e.error_code})" ) from e devices = devices_dict.get("devices", []) supported_devices = [ diff --git a/homeassistant/components/growatt_server/config_flow.py b/homeassistant/components/growatt_server/config_flow.py index 1914dc215121..a4b76c746d93 100644 --- a/homeassistant/components/growatt_server/config_flow.py +++ b/homeassistant/components/growatt_server/config_flow.py @@ -152,7 +152,8 @@ class GrowattServerConfigFlow(ConfigFlow, domain=DOMAIN): errors["base"] = ERROR_INVALID_AUTH else: _LOGGER.debug( - "Growatt V1 API error during credential update: %s (Code: %s)", + "Growatt V1 API error during credential" + " update: %s (Code: %s)", err.error_msg or str(err), err.error_code, ) diff --git a/homeassistant/components/growatt_server/coordinator.py b/homeassistant/components/growatt_server/coordinator.py index 6cb9e94267d7..f5da2779580b 100644 --- a/homeassistant/components/growatt_server/coordinator.py +++ b/homeassistant/components/growatt_server/coordinator.py @@ -104,11 +104,16 @@ class GrowattCoordinator(DataUpdateCoordinator[dict[str, Any]]): if self.device_type == "total": if self.api_version == "v1": - # The V1 Plant APIs do not provide the same information as the classic plant_info() API + # The V1 Plant APIs do not provide the same + # information as the classic plant_info() API # More specifically: - # 1. There is no monetary information to be found, so today and lifetime money is not available - # 2. There is no nominal power, this is provided by inverter min_energy() - # This means, for the total coordinator we can only fetch and map the following: + # 1. There is no monetary information to be + # found, so today and lifetime money is not + # available + # 2. There is no nominal power, this is + # provided by inverter min_energy() + # This means, for the total coordinator we can + # only fetch and map the following: # todayEnergy -> today_energy # totalEnergy -> total_energy # invTodayPpv -> current_power @@ -117,7 +122,8 @@ class GrowattCoordinator(DataUpdateCoordinator[dict[str, Any]]): except growattServer.GrowattV1ApiError as err: if err.error_code == V1_API_ERROR_NO_PRIVILEGE: raise ConfigEntryAuthFailed( - f"Authentication failed for Growatt API: {err.error_msg or str(err)}" + "Authentication failed for Growatt API:" + f" {err.error_msg or str(err)}" ) from err raise UpdateFailed( f"Error fetching plant energy overview: {err}" @@ -145,7 +151,8 @@ class GrowattCoordinator(DataUpdateCoordinator[dict[str, Any]]): except growattServer.GrowattV1ApiError as err: if err.error_code == V1_API_ERROR_NO_PRIVILEGE: raise ConfigEntryAuthFailed( - f"Authentication failed for Growatt API: {err.error_msg or str(err)}" + "Authentication failed for Growatt API:" + f" {err.error_msg or str(err)}" ) from err raise UpdateFailed(f"Error fetching min device data: {err}") from err @@ -172,7 +179,8 @@ class GrowattCoordinator(DataUpdateCoordinator[dict[str, Any]]): except growattServer.GrowattV1ApiError as err: if err.error_code == V1_API_ERROR_NO_PRIVILEGE: raise ConfigEntryAuthFailed( - f"Authentication failed for Growatt API: {err.error_msg or str(err)}" + "Authentication failed for Growatt API:" + f" {err.error_msg or str(err)}" ) from err raise UpdateFailed(f"Error fetching SPH device data: {err}") from err @@ -376,7 +384,8 @@ class GrowattCoordinator(DataUpdateCoordinator[dict[str, Any]]): try: # Use V1 API for token authentication - # The library's _process_response will raise GrowattV1ApiError if error_code != 0 + # The library's _process_response will raise + # GrowattV1ApiError if error_code != 0 await self.hass.async_add_executor_job( self.api.min_write_time_segment, self.device_id, @@ -393,7 +402,8 @@ class GrowattCoordinator(DataUpdateCoordinator[dict[str, Any]]): translation_placeholders={"error": str(err)}, ) from err - # Update coordinator's cached data without making an API call (avoids rate limit) + # Update coordinator's cached data without making an + # API call (avoids rate limit) if self.data: # Update the time segment data in the cache self.data[f"forcedTimeStart{segment_id}"] = start_time.strftime("%H:%M") diff --git a/homeassistant/components/growatt_server/sensor/mix.py b/homeassistant/components/growatt_server/sensor/mix.py index c3412600d826..a4223c5675f4 100644 --- a/homeassistant/components/growatt_server/sensor/mix.py +++ b/homeassistant/components/growatt_server/sensor/mix.py @@ -242,7 +242,8 @@ MIX_SENSOR_TYPES: tuple[GrowattSensorEntityDescription, ...] = ( device_class=SensorDeviceClass.ENERGY, state_class=SensorStateClass.TOTAL_INCREASING, ), - # This sensor is manually created using the most recent X-Axis value from the chartData + # This sensor is manually created using the most recent + # X-Axis value from the chartData GrowattSensorEntityDescription( key="mix_last_update", translation_key="mix_last_update", @@ -253,7 +254,9 @@ MIX_SENSOR_TYPES: tuple[GrowattSensorEntityDescription, ...] = ( GrowattSensorEntityDescription( key="mix_import_from_grid_today_combined", translation_key="mix_import_from_grid_today_combined", - api_key="etouser_combined", # This id is not present in the raw API data, it is added by the sensor + # This id is not present in the raw API data, + # it is added by the sensor + api_key="etouser_combined", native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, device_class=SensorDeviceClass.ENERGY, state_class=SensorStateClass.TOTAL_INCREASING, diff --git a/homeassistant/components/guardian/__init__.py b/homeassistant/components/guardian/__init__.py index 8b0ab5d18634..afc47be08a3d 100644 --- a/homeassistant/components/guardian/__init__.py +++ b/homeassistant/components/guardian/__init__.py @@ -188,7 +188,8 @@ class PairedSensorManager: try: uids = set(self._sensor_pair_dump_coordinator.data["paired_uids"]) except KeyError: - # Sometimes the paired_uids key can fail to exist; the user can't do anything + # Sometimes the paired_uids key can fail to exist; + # the user can't do anything # about it, so in this case, we quietly abort and return: return