From 382e1ac679584150b642082fafe86a906afac805 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Wed, 18 Jan 2023 11:10:16 +0100 Subject: [PATCH] Code styling tweaks to the ESPHome integration (#86146) --- homeassistant/components/esphome/__init__.py | 12 +++-- .../components/esphome/bluetooth/client.py | 50 ++++++++++++------- homeassistant/components/esphome/light.py | 30 ++++++----- .../components/esphome/media_player.py | 3 +- homeassistant/components/esphome/sensor.py | 3 +- 5 files changed, 62 insertions(+), 36 deletions(-) diff --git a/homeassistant/components/esphome/__init__.py b/homeassistant/components/esphome/__init__.py index 8fe3cec19cb..73009399ab2 100644 --- a/homeassistant/components/esphome/__init__.py +++ b/homeassistant/components/esphome/__init__.py @@ -141,7 +141,8 @@ async def async_setup_entry( # noqa: C901 # Use async_listen instead of async_listen_once so that we don't deregister # the callback twice when shutting down Home Assistant. - # "Unable to remove unknown listener .onetime_listener>" + # "Unable to remove unknown listener + # .onetime_listener>" entry_data.cleanup_callbacks.append( hass.bus.async_listen(EVENT_HOMEASSISTANT_STOP, on_stop) ) @@ -651,7 +652,9 @@ class EsphomeEnumMapper(Generic[_EnumT, _ValT]): def __init__(self, mapping: dict[_EnumT, _ValT]) -> None: """Construct a EsphomeEnumMapper.""" # Add none mapping - augmented_mapping: dict[_EnumT | None, _ValT | None] = mapping # type: ignore[assignment] + augmented_mapping: dict[ + _EnumT | None, _ValT | None + ] = mapping # type: ignore[assignment] augmented_mapping[None] = None self._mapping = augmented_mapping @@ -823,7 +826,10 @@ class EsphomeEntity(Entity, Generic[_InfoT, _StateT]): @property def entity_registry_enabled_default(self) -> bool: - """Return if the entity should be enabled when first added to the entity registry.""" + """Return if the entity should be enabled when first added. + + This only applies when fist added to the entity registry. + """ return not self._static_info.disabled_by_default @property diff --git a/homeassistant/components/esphome/bluetooth/client.py b/homeassistant/components/esphome/bluetooth/client.py index 6aa21c315a3..819bf0f4b1d 100644 --- a/homeassistant/components/esphome/bluetooth/client.py +++ b/homeassistant/components/esphome/bluetooth/client.py @@ -77,8 +77,11 @@ def verify_connected(func: _WrapFuncType) -> _WrapFuncType: task.cancel() with contextlib.suppress(asyncio.CancelledError): await task + raise BleakError( - f"{self._source_name}: {self._ble_device.name} - {self._ble_device.address}: " # pylint: disable=protected-access + f"{self._source_name}: " # pylint: disable=protected-access + f"{self._ble_device.name} - " # pylint: disable=protected-access + f" {self._ble_device.address}: " # pylint: disable=protected-access "Disconnected during operation" ) return next(iter(done)).result() @@ -105,8 +108,8 @@ def api_error_as_bleak_error(func: _WrapFuncType) -> _WrapFuncType: # that we find out about the disconnection during the operation # before the callback is delivered. - # pylint: disable=protected-access if ex.error.error == -1: + # pylint: disable=protected-access _LOGGER.debug( "%s: %s - %s: BLE device disconnected during %s operation", self._source_name, @@ -228,7 +231,8 @@ class ESPHomeClient(BaseBleakClient): """Connect to a specified Peripheral. Keyword Args: - timeout (float): Timeout for required ``BleakScanner.find_device_by_address`` call. Defaults to 10.0. + timeout (float): Timeout for required + ``BleakScanner.find_device_by_address`` call. Defaults to 10.0. Returns: Boolean representing connection status. """ @@ -395,7 +399,8 @@ class ESPHomeClient(BaseBleakClient): """Get all services registered for this GATT server. Returns: - A :py:class:`bleak.backends.service.BleakGATTServiceCollection` with this device's services tree. + A :py:class:`bleak.backends.service.BleakGATTServiceCollection` + with this device's services tree. """ address_as_int = self._address_as_int domain_data = self.domain_data @@ -494,9 +499,10 @@ class ESPHomeClient(BaseBleakClient): """Perform read operation on the specified GATT characteristic. Args: - char_specifier (BleakGATTCharacteristic, int, str or UUID): The characteristic to read from, - specified by either integer handle, UUID or directly by the - BleakGATTCharacteristic object representing it. + char_specifier (BleakGATTCharacteristic, int, str or UUID): + The characteristic to read from, specified by either integer + handle, UUID or directly by the BleakGATTCharacteristic + object representing it. Returns: (bytearray) The read data. """ @@ -530,11 +536,13 @@ class ESPHomeClient(BaseBleakClient): """Perform a write operation of the specified GATT characteristic. Args: - char_specifier (BleakGATTCharacteristic, int, str or UUID): The characteristic to write - to, specified by either integer handle, UUID or directly by the - BleakGATTCharacteristic object representing it. + char_specifier (BleakGATTCharacteristic, int, str or UUID): + The characteristic to write to, specified by either integer + handle, UUID or directly by the BleakGATTCharacteristic object + representing it. data (bytes or bytearray): The data to send. - response (bool): If write-with-response operation should be done. Defaults to `False`. + response (bool): If write-with-response operation should be done. + Defaults to `False`. """ characteristic = self._resolve_characteristic(char_specifier) await self._client.bluetooth_gatt_write( @@ -566,16 +574,19 @@ class ESPHomeClient(BaseBleakClient): ) -> None: """Activate notifications/indications on a characteristic. - Callbacks must accept two inputs. The first will be a integer handle of the characteristic generating the - data and the second will be a ``bytearray`` containing the data sent from the connected server. + Callbacks must accept two inputs. The first will be a integer handle of the + characteristic generating the data and the second will be a ``bytearray`` + containing the data sent from the connected server. + .. code-block:: python def callback(sender: int, data: bytearray): print(f"{sender}: {data}") client.start_notify(char_uuid, callback) Args: - char_specifier (BleakGATTCharacteristic, int, str or UUID): The characteristic to activate - notifications/indications on a characteristic, specified by either integer handle, - UUID or directly by the BleakGATTCharacteristic object representing it. + char_specifier (BleakGATTCharacteristic, int, str or UUID): + The characteristic to activate notifications/indications on a + characteristic, specified by either integer handle, UUID or + directly by the BleakGATTCharacteristic object representing it. callback (function): The function to be called on notification. """ ble_handle = characteristic.handle @@ -645,9 +656,10 @@ class ESPHomeClient(BaseBleakClient): """Deactivate notification/indication on a specified characteristic. Args: - char_specifier (BleakGATTCharacteristic, int, str or UUID): The characteristic to deactivate - notification/indication on, specified by either integer handle, UUID or - directly by the BleakGATTCharacteristic object representing it. + char_specifier (BleakGATTCharacteristic, int, str or UUID): + The characteristic to deactivate notification/indication on, + specified by either integer handle, UUID or directly by the + BleakGATTCharacteristic object representing it. """ characteristic = self._resolve_characteristic(char_specifier) # Do not raise KeyError if notifications are not enabled on this characteristic diff --git a/homeassistant/components/esphome/light.py b/homeassistant/components/esphome/light.py index 76de857a863..880d94a5f55 100644 --- a/homeassistant/components/esphome/light.py +++ b/homeassistant/components/esphome/light.py @@ -118,7 +118,10 @@ def _color_mode_to_ha(mode: int) -> str: def _filter_color_modes( supported: list[int], features: LightColorCapability ) -> list[int]: - """Filter the given supported color modes, excluding all values that don't have the requested features.""" + """Filter the given supported color modes. + + Excluding all values that don't have the requested features. + """ return [mode for mode in supported if mode & features] @@ -161,7 +164,7 @@ class EsphomeLight(EsphomeEntity[LightInfo, LightState], LightEntity): try_keep_current_mode = False if (rgbw_ha := kwargs.get(ATTR_RGBW_COLOR)) is not None: - # pylint: disable=invalid-name + # pylint: disable-next=invalid-name *rgb, w = tuple(x / 255 for x in rgbw_ha) # type: ignore[assignment] color_bri = max(rgb) # normalize rgb @@ -174,7 +177,7 @@ class EsphomeLight(EsphomeEntity[LightInfo, LightState], LightEntity): try_keep_current_mode = False if (rgbww_ha := kwargs.get(ATTR_RGBWW_COLOR)) is not None: - # pylint: disable=invalid-name + # pylint: disable-next=invalid-name *rgb, cw, ww = tuple(x / 255 for x in rgbww_ha) # type: ignore[assignment] color_bri = max(rgb) # normalize rgb @@ -226,7 +229,8 @@ class EsphomeLight(EsphomeEntity[LightInfo, LightState], LightEntity): if (white_ha := kwargs.get(ATTR_WHITE)) is not None: # ESPHome multiplies brightness and white together for final brightness - # HA only sends `white` in turn_on, and reads total brightness through brightness property + # HA only sends `white` in turn_on, and reads total brightness + # through brightness property. data["brightness"] = white_ha / 255 data["white"] = 1.0 color_modes = _filter_color_modes( @@ -244,8 +248,10 @@ class EsphomeLight(EsphomeEntity[LightInfo, LightState], LightEntity): # if possible, stay with the color mode that is already set data["color_mode"] = self._state.color_mode else: - # otherwise try the color mode with the least complexity (fewest capabilities set) - # popcount with bin() function because it appears to be the best way: https://stackoverflow.com/a/9831671 + # otherwise try the color mode with the least complexity + # (fewest capabilities set) + # popcount with bin() function because it appears + # to be the best way: https://stackoverflow.com/a/9831671 color_modes.sort(key=lambda mode: bin(mode).count("1")) data["color_mode"] = color_modes[0] @@ -332,9 +338,9 @@ class EsphomeLight(EsphomeEntity[LightInfo, LightState], LightEntity): @property @esphome_state_property - def color_temp(self) -> float | None: # type: ignore[override] + def color_temp(self) -> int: """Return the CT color value in mireds.""" - return self._state.color_temperature + return round(self._state.color_temperature) @property @esphome_state_property @@ -377,11 +383,11 @@ class EsphomeLight(EsphomeEntity[LightInfo, LightState], LightEntity): return self._static_info.effects @property - def min_mireds(self) -> float: # type: ignore[override] + def min_mireds(self) -> int: """Return the coldest color_temp that this light supports.""" - return self._static_info.min_mireds + return round(self._static_info.min_mireds) @property - def max_mireds(self) -> float: # type: ignore[override] + def max_mireds(self) -> int: """Return the warmest color_temp that this light supports.""" - return self._static_info.max_mireds + return round(self._static_info.max_mireds) diff --git a/homeassistant/components/esphome/media_player.py b/homeassistant/components/esphome/media_player.py index 7f90f4e27d8..f8566e863c6 100644 --- a/homeassistant/components/esphome/media_player.py +++ b/homeassistant/components/esphome/media_player.py @@ -17,6 +17,7 @@ from homeassistant.components.media_player import ( MediaPlayerEntity, MediaPlayerEntityFeature, MediaPlayerState, + MediaType, async_process_play_media_url, ) from homeassistant.config_entries import ConfigEntry @@ -97,7 +98,7 @@ class EsphomeMediaPlayer( return flags async def async_play_media( - self, media_type: str, media_id: str, **kwargs: Any + self, media_type: MediaType | str, media_id: str, **kwargs: Any ) -> None: """Send the play command with media url to the media player.""" if media_source.is_media_source_id(media_id): diff --git a/homeassistant/components/esphome/sensor.py b/homeassistant/components/esphome/sensor.py index 29c661f0984..282bcb1fbee 100644 --- a/homeassistant/components/esphome/sensor.py +++ b/homeassistant/components/esphome/sensor.py @@ -113,7 +113,8 @@ class EsphomeSensor(EsphomeEntity[SensorInfo, SensorState], SensorEntity): state_class == EsphomeSensorStateClass.MEASUREMENT and reset_type == LastResetType.AUTO ): - # Legacy, last_reset_type auto was the equivalent to the TOTAL_INCREASING state class + # Legacy, last_reset_type auto was the equivalent to the + # TOTAL_INCREASING state class return SensorStateClass.TOTAL_INCREASING return _STATE_CLASSES.from_esphome(self._static_info.state_class)