Use f-strings in integrations starting with "B"-"E" (#32121)

* Use f-strings in integrations starting with B

* Use f-strings in integrations starting with C

* Use f-strings in integrations starting with D

* Use f-strings in integrations starting with E

* Fix pylint errors

* Fix pylint errors v2

* Fix tests

* Fix tests v2
This commit is contained in:
springstan 2020-02-24 17:47:52 +01:00 committed by GitHub
parent 07fa844c43
commit 9801810552
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
66 changed files with 201 additions and 315 deletions

View File

@ -124,45 +124,45 @@ class BitcoinSensor(Entity):
self._state = ticker[self._currency].p15min
self._unit_of_measurement = self._currency
elif self.type == "trade_volume_btc":
self._state = "{0:.1f}".format(stats.trade_volume_btc)
self._state = f"{stats.trade_volume_btc:.1f}"
elif self.type == "miners_revenue_usd":
self._state = "{0:.0f}".format(stats.miners_revenue_usd)
self._state = f"{stats.miners_revenue_usd:.0f}"
elif self.type == "btc_mined":
self._state = "{}".format(stats.btc_mined * 0.00000001)
self._state = str(stats.btc_mined * 0.00000001)
elif self.type == "trade_volume_usd":
self._state = "{0:.1f}".format(stats.trade_volume_usd)
self._state = f"{stats.trade_volume_usd:.1f}"
elif self.type == "difficulty":
self._state = "{0:.0f}".format(stats.difficulty)
self._state = f"{stats.difficulty:.0f}"
elif self.type == "minutes_between_blocks":
self._state = "{0:.2f}".format(stats.minutes_between_blocks)
self._state = f"{stats.minutes_between_blocks:.2f}"
elif self.type == "number_of_transactions":
self._state = "{}".format(stats.number_of_transactions)
self._state = str(stats.number_of_transactions)
elif self.type == "hash_rate":
self._state = "{0:.1f}".format(stats.hash_rate * 0.000001)
self._state = f"{stats.hash_rate * 0.000001:.1f}"
elif self.type == "timestamp":
self._state = stats.timestamp
elif self.type == "mined_blocks":
self._state = "{}".format(stats.mined_blocks)
self._state = str(stats.mined_blocks)
elif self.type == "blocks_size":
self._state = "{0:.1f}".format(stats.blocks_size)
self._state = f"{stats.blocks_size:.1f}"
elif self.type == "total_fees_btc":
self._state = "{0:.2f}".format(stats.total_fees_btc * 0.00000001)
self._state = f"{stats.total_fees_btc * 0.00000001:.2f}"
elif self.type == "total_btc_sent":
self._state = "{0:.2f}".format(stats.total_btc_sent * 0.00000001)
self._state = f"{stats.total_btc_sent * 0.00000001:.2f}"
elif self.type == "estimated_btc_sent":
self._state = "{0:.2f}".format(stats.estimated_btc_sent * 0.00000001)
self._state = f"{stats.estimated_btc_sent * 0.00000001:.2f}"
elif self.type == "total_btc":
self._state = "{0:.2f}".format(stats.total_btc * 0.00000001)
self._state = f"{stats.total_btc * 0.00000001:.2f}"
elif self.type == "total_blocks":
self._state = "{0:.0f}".format(stats.total_blocks)
self._state = f"{stats.total_blocks:.0f}"
elif self.type == "next_retarget":
self._state = "{0:.2f}".format(stats.next_retarget)
self._state = f"{stats.next_retarget:.2f}"
elif self.type == "estimated_transaction_volume_usd":
self._state = "{0:.2f}".format(stats.estimated_transaction_volume_usd)
self._state = f"{stats.estimated_transaction_volume_usd:.2f}"
elif self.type == "miners_revenue_btc":
self._state = "{0:.1f}".format(stats.miners_revenue_btc * 0.00000001)
self._state = f"{stats.miners_revenue_btc * 0.00000001:.1f}"
elif self.type == "market_price_usd":
self._state = "{0:.2f}".format(stats.market_price_usd)
self._state = f"{stats.market_price_usd:.2f}"
class BitcoinData:

View File

@ -40,7 +40,7 @@ class BloomSkySensor(BinarySensorDevice):
self._bloomsky = bs
self._device_id = device["DeviceID"]
self._sensor_name = sensor_name
self._name = "{} {}".format(device["DeviceName"], sensor_name)
self._name = f"{device['DeviceName']} {sensor_name}"
self._state = None
self._unique_id = f"{self._device_id}-{self._sensor_name}"

View File

@ -70,7 +70,7 @@ class BloomSkySensor(Entity):
self._bloomsky = bs
self._device_id = device["DeviceID"]
self._sensor_name = sensor_name
self._name = "{} {}".format(device["DeviceName"], sensor_name)
self._name = f"{device['DeviceName']} {sensor_name}"
self._state = None
self._unique_id = f"{self._device_id}-{self._sensor_name}"

View File

@ -500,7 +500,7 @@ class BluesoundPlayer(MediaPlayerDevice):
"image": item.get("@image", ""),
"is_raw_url": True,
"url2": item.get("@url", ""),
"url": "Preset?id={}".format(item.get("@id", "")),
"url": f"Preset?id={item.get('@id', '')}",
}
)
@ -934,9 +934,7 @@ class BluesoundPlayer(MediaPlayerDevice):
return
selected_source = items[0]
url = "Play?url={}&preset_id&image={}".format(
selected_source["url"], selected_source["image"]
)
url = f"Play?url={selected_source['url']}&preset_id&image={selected_source['image']}"
if "is_raw_url" in selected_source and selected_source["is_raw_url"]:
url = selected_source["url"]
@ -1002,7 +1000,7 @@ class BluesoundPlayer(MediaPlayerDevice):
if self.is_grouped and not self.is_master:
return
return await self.send_bluesound_command("Play?seek={}".format(float(position)))
return await self.send_bluesound_command(f"Play?seek={float(position)}")
async def async_play_media(self, media_type, media_id, **kwargs):
"""

View File

@ -75,16 +75,12 @@ def _validate_schema(config):
if config.get(CONF_LOCATION) is None:
if not all(config.get(x) for x in (CONF_ID, CONF_DELTA, CONF_FRAMES)):
raise vol.Invalid(
"Specify '{}', '{}' and '{}' when '{}' is unspecified".format(
CONF_ID, CONF_DELTA, CONF_FRAMES, CONF_LOCATION
)
f"Specify '{CONF_ID}', '{CONF_DELTA}' and '{CONF_FRAMES}' when '{CONF_LOCATION}' is unspecified"
)
return config
LOCATIONS_MSG = "Set '{}' to one of: {}".format(
CONF_LOCATION, ", ".join(sorted(LOCATIONS))
)
LOCATIONS_MSG = f"Set '{CONF_LOCATION}' to one of: {', '.join(sorted(LOCATIONS))}"
XOR_MSG = f"Specify exactly one of '{CONF_ID}' or '{CONF_LOCATION}'"
PLATFORM_SCHEMA = vol.All(
@ -106,7 +102,7 @@ PLATFORM_SCHEMA = vol.All(
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up BOM radar-loop camera component."""
location = config.get(CONF_LOCATION) or "ID {}".format(config.get(CONF_ID))
location = config.get(CONF_LOCATION) or f"ID {config.get(CONF_ID)}"
name = config.get(CONF_NAME) or f"BOM Radar Loop - {location}"
args = [
config.get(x)

View File

@ -27,7 +27,6 @@ from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle
import homeassistant.util.dt as dt_util
_RESOURCE = "http://www.bom.gov.au/fwo/{}/{}.{}.json"
_LOGGER = logging.getLogger(__name__)
ATTR_LAST_UPDATE = "last_update"
@ -159,9 +158,9 @@ class BOMCurrentSensor(Entity):
def name(self):
"""Return the name of the sensor."""
if self.stationname is None:
return "BOM {}".format(SENSOR_TYPES[self._condition][0])
return f"BOM {SENSOR_TYPES[self._condition][0]}"
return "BOM {} {}".format(self.stationname, SENSOR_TYPES[self._condition][0])
return f"BOM {self.stationname} {SENSOR_TYPES[self._condition][0]}"
@property
def state(self):
@ -203,7 +202,10 @@ class BOMCurrentData:
def _build_url(self):
"""Build the URL for the requests."""
url = _RESOURCE.format(self._zone_id, self._zone_id, self._wmo_id)
url = (
f"http://www.bom.gov.au/fwo/{self._zone_id}"
f"/{self._zone_id}.{self._wmo_id}.json"
)
_LOGGER.debug("BOM URL: %s", url)
return url
@ -310,10 +312,10 @@ def _get_bom_stations():
r'(?P=zone)\.(?P<wmo>\d\d\d\d\d).shtml">'
)
for state in ("nsw", "vic", "qld", "wa", "tas", "nt"):
url = "http://www.bom.gov.au/{0}/observations/{0}all.shtml".format(state)
url = f"http://www.bom.gov.au/{state}/observations/{state}all.shtml"
for zone_id, wmo_id in re.findall(pattern, requests.get(url).text):
zones[wmo_id] = zone_id
return {"{}.{}".format(zones[k], k): latlon[k] for k in set(latlon) & set(zones)}
return {f"{zones[k]}.{k}": latlon[k] for k in set(latlon) & set(zones)}
def bom_stations(cache_dir):

View File

@ -49,7 +49,7 @@ class BOMWeather(WeatherEntity):
@property
def name(self):
"""Return the name of the sensor."""
return "BOM {}".format(self.stationname or "(unknown station)")
return f"BOM {self.stationname or '(unknown station)'}"
@property
def condition(self):

View File

@ -44,9 +44,7 @@ DEFAULT_TIMEOUT = 5
SCAN_INTERVAL = timedelta(minutes=2)
CODE_STORAGE_KEY = "broadlink_{}_codes"
CODE_STORAGE_VERSION = 1
FLAG_STORAGE_KEY = "broadlink_{}_flags"
FLAG_STORAGE_VERSION = 1
FLAG_SAVE_DELAY = 15
@ -96,8 +94,8 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
api = broadlink.rm((host, DEFAULT_PORT), mac_addr, None)
api.timeout = timeout
code_storage = Store(hass, CODE_STORAGE_VERSION, CODE_STORAGE_KEY.format(unique_id))
flag_storage = Store(hass, FLAG_STORAGE_VERSION, FLAG_STORAGE_KEY.format(unique_id))
code_storage = Store(hass, CODE_STORAGE_VERSION, f"broadlink_{unique_id}_codes")
flag_storage = Store(hass, FLAG_STORAGE_VERSION, f"broadlink_{unique_id}_flags")
remote = BroadlinkRemote(name, unique_id, api, code_storage, flag_storage)
connected, loaded = (False, False)

View File

@ -67,7 +67,7 @@ class BroadlinkSensor(Entity):
def __init__(self, name, broadlink_data, sensor_type):
"""Initialize the sensor."""
self._name = "{} {}".format(name, SENSOR_TYPES[sensor_type][0])
self._name = f"{name} {SENSOR_TYPES[sensor_type][0]}"
self._state = None
self._is_available = False
self._type = sensor_type

View File

@ -7,11 +7,7 @@ import socket
import broadlink
import voluptuous as vol
from homeassistant.components.switch import (
ENTITY_ID_FORMAT,
PLATFORM_SCHEMA,
SwitchDevice,
)
from homeassistant.components.switch import DOMAIN, PLATFORM_SCHEMA, SwitchDevice
from homeassistant.const import (
CONF_COMMAND_OFF,
CONF_COMMAND_ON,
@ -159,7 +155,7 @@ class BroadlinkRMSwitch(SwitchDevice, RestoreEntity):
self, name, friendly_name, device, command_on, command_off, retry_times
):
"""Initialize the switch."""
self.entity_id = ENTITY_ID_FORMAT.format(slugify(name))
self.entity_id = f"{DOMAIN}.{slugify(name)}"
self._name = friendly_name
self._state = False
self._command_on = command_on

View File

@ -69,7 +69,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
# Every Home Assistant instance should have their own unique
# app parameter: https://brottsplatskartan.se/sida/api
app = "ha-{}".format(uuid.getnode())
app = f"ha-{uuid.getnode()}"
bpk = brottsplatskartan.BrottsplatsKartan(
app=app, area=area, latitude=latitude, longitude=longitude

View File

@ -56,9 +56,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
except (TypeError, KeyError, NameError, ValueError) as ex:
_LOGGER.error("%s", ex)
hass.components.persistent_notification.create(
"Error: {}<br />"
"You will need to restart hass after fixing."
"".format(ex),
"Error: {ex}<br />You will need to restart hass after fixing.",
title=NOTIFICATION_TITLE,
notification_id=NOTIFICATION_ID,
)

View File

@ -17,8 +17,6 @@ CONF_DIMENSION = "dimension"
CONF_DELTA = "delta"
CONF_COUNTRY = "country_code"
RADAR_MAP_URL_TEMPLATE = "https://api.buienradar.nl/image/1.0/RadarMap{c}?w={w}&h={h}"
_LOG = logging.getLogger(__name__)
# Maximum range according to docs
@ -112,8 +110,9 @@ class BuienradarCam(Camera):
"""Retrieve new radar image and return whether this succeeded."""
session = async_get_clientsession(self.hass)
url = RADAR_MAP_URL_TEMPLATE.format(
c=self._country, w=self._dimension, h=self._dimension
url = (
f"https://api.buienradar.nl/image/1.0/RadarMap{self._country}"
f"?w={self._dimension}&h={self._dimension}"
)
if self._last_modified:

View File

@ -113,8 +113,8 @@ class BrWeather(WeatherEntity):
@property
def name(self):
"""Return the name of the sensor."""
return self._stationname or "BR {}".format(
self._data.stationname or "(unknown station)"
return (
self._stationname or f"BR {self._data.stationname or '(unknown station)'}"
)
@property

View File

@ -88,9 +88,7 @@ def setup_platform(hass, config, add_entities, disc_info=None):
continue
name = cust_calendar[CONF_NAME]
device_id = "{} {}".format(
cust_calendar[CONF_CALENDAR], cust_calendar[CONF_NAME]
)
device_id = f"{cust_calendar[CONF_CALENDAR]} {cust_calendar[CONF_NAME]}"
entity_id = generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass)
calendar_devices.append(
WebDavCalendarEventDevice(

View File

@ -65,9 +65,7 @@ class CO2Sensor(Entity):
if country_code is not None:
device_name = country_code
else:
device_name = "{lat}/{lon}".format(
lat=round(self._latitude, 2), lon=round(self._longitude, 2)
)
device_name = f"{round(self._latitude, 2)}/{round(self._longitude, 2)}"
self._friendly_name = f"CO2 intensity - {device_name}"

View File

@ -75,9 +75,7 @@ class AccountSensor(Entity):
"""Return the state attributes of the sensor."""
return {
ATTR_ATTRIBUTION: ATTRIBUTION,
ATTR_NATIVE_BALANCE: "{} {}".format(
self._native_balance, self._native_currency
),
ATTR_NATIVE_BALANCE: f"{self._native_balance} {self._native_currency}",
}
def update(self):

View File

@ -237,7 +237,7 @@ class Configurator:
def _generate_unique_id(self):
"""Generate a unique configurator ID."""
self._cur_id += 1
return "{}-{}".format(id(self), self._cur_id)
return f"{id(self)}-{self._cur_id}"
def _validate_request_id(self, request_id):
"""Validate that the request belongs to this instance."""

View File

@ -47,9 +47,9 @@ class DaikinClimateSensor(Entity):
self._api = api
self._sensor = SENSOR_TYPES.get(monitored_state)
if name is None:
name = "{} {}".format(self._sensor[CONF_NAME], api.name)
name = f"{self._sensor[CONF_NAME]} {api.name}"
self._name = "{} {}".format(name, monitored_state.replace("_", " "))
self._name = f"{name} {monitored_state.replace('_', ' ')}"
self._device_attribute = monitored_state
if self._sensor[CONF_TYPE] == SENSOR_TYPE_TEMPERATURE:

View File

@ -54,7 +54,7 @@ class DaikinZoneSwitch(ToggleEntity):
@property
def name(self):
"""Return the name of the sensor."""
return "{} {}".format(self._api.name, self._api.device.zones[self._zone_id][0])
return f"{self._api.name} {self._api.device.zones[self._zone_id][0]}"
@property
def is_on(self):

View File

@ -61,8 +61,8 @@ def setup(hass, config):
title="Home Assistant",
text=f"%%% \n **{name}** {message} \n %%%",
tags=[
"entity:{}".format(event.data.get("entity_id")),
"domain:{}".format(event.data.get("domain")),
f"entity:{event.data.get('entity_id')}",
f"domain:{event.data.get('domain')}",
],
)
@ -84,7 +84,7 @@ def setup(hass, config):
for key, value in states.items():
if isinstance(value, (float, int)):
attribute = "{}.{}".format(metric, key.replace(" ", "_"))
attribute = f"{metric}.{key.replace(' ', '_')}"
statsd.gauge(attribute, value, sample_rate=sample_rate, tags=tags)
_LOGGER.debug("Sent metric %s: %s (tags: %s)", attribute, value, tags)

View File

@ -31,13 +31,6 @@ NEW_LIGHT = "lights"
NEW_SCENE = "scenes"
NEW_SENSOR = "sensors"
NEW_DEVICE = {
NEW_GROUP: "deconz_new_group_{}",
NEW_LIGHT: "deconz_new_light_{}",
NEW_SCENE: "deconz_new_scene_{}",
NEW_SENSOR: "deconz_new_sensor_{}",
}
ATTR_DARK = "dark"
ATTR_OFFSET = "offset"
ATTR_ON = "on"

View File

@ -19,8 +19,9 @@ from .const import (
DEFAULT_ALLOW_DECONZ_GROUPS,
DOMAIN,
LOGGER,
NEW_DEVICE,
NEW_GROUP,
NEW_LIGHT,
NEW_SCENE,
NEW_SENSOR,
SUPPORTED_PLATFORMS,
)
@ -186,7 +187,13 @@ class DeconzGateway:
@callback
def async_signal_new_device(self, device_type) -> str:
"""Gateway specific event to signal new device."""
return NEW_DEVICE[device_type].format(self.bridgeid)
new_device = {
NEW_GROUP: f"deconz_new_group_{self.bridgeid}",
NEW_LIGHT: f"deconz_new_light_{self.bridgeid}",
NEW_SCENE: f"deconz_new_scene_{self.bridgeid}",
NEW_SENSOR: f"deconz_new_sensor_{self.bridgeid}",
}
return new_device[device_type]
@property
def signal_remove_entity(self) -> str:

View File

@ -203,7 +203,7 @@ async def finish_setup(hass, config):
{
"script": {
"demo": {
"alias": "Toggle {}".format(lights[0].split(".")[1]),
"alias": f"Toggle {lights[0].split('.')[1]}",
"sequence": [
{
"service": "light.turn_off",

View File

@ -27,7 +27,7 @@ class DemoAirQuality(AirQualityEntity):
@property
def name(self):
"""Return the name of the sensor."""
return "{} {}".format("Demo Air Quality", self._name)
return f"Demo Air Quality {self._name}"
@property
def should_poll(self):

View File

@ -26,7 +26,7 @@ class DemoMailbox(Mailbox):
txt = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
for idx in range(0, 10):
msgtime = int(dt.as_timestamp(dt.utcnow()) - 3600 * 24 * (10 - idx))
msgtxt = "Message {}. {}".format(idx + 1, txt * (1 + idx * (idx % 2)))
msgtxt = f"Message {idx + 1}. {txt * (1 + idx * (idx % 2))}"
msgsha = sha1(msgtxt.encode("utf-8")).hexdigest()
msg = {
"info": {

View File

@ -48,7 +48,6 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
await async_setup_platform(hass, {}, async_add_entities)
YOUTUBE_COVER_URL_FORMAT = "https://img.youtube.com/vi/{}/hqdefault.jpg"
SOUND_MODE_LIST = ["Dummy Music", "Dummy Movie"]
DEFAULT_SOUND_MODE = "Dummy Music"
@ -238,7 +237,7 @@ class DemoYoutubePlayer(AbstractDemoPlayer):
@property
def media_image_url(self):
"""Return the image url of current playing media."""
return YOUTUBE_COVER_URL_FORMAT.format(self.youtube_id)
return f"https://img.youtube.com/vi/{self.youtube_id}/hqdefault.jpg"
@property
def media_title(self):

View File

@ -106,7 +106,7 @@ class DemoWeather(WeatherEntity):
@property
def name(self):
"""Return the name of the sensor."""
return "{} {}".format("Demo Weather", self._name)
return f"Demo Weather {self._name}"
@property
def should_poll(self):

View File

@ -82,7 +82,7 @@ class DeutscheBahnSensor(Entity):
self.data.update()
self._state = self.data.connections[0].get("departure", "Unknown")
if self.data.connections[0].get("delay", 0) != 0:
self._state += " + {}".format(self.data.connections[0]["delay"])
self._state += f" + {self.data.connections[0]['delay']}"
class SchieneData:

View File

@ -5,7 +5,6 @@ import logging
LOGGER = logging.getLogger(__package__)
DOMAIN = "device_tracker"
ENTITY_ID_FORMAT = DOMAIN + ".{}"
PLATFORM_TYPE_LEGACY = "legacy"
PLATFORM_TYPE_ENTITY = "entity_platform"

View File

@ -45,7 +45,6 @@ from .const import (
DEFAULT_CONSIDER_HOME,
DEFAULT_TRACK_NEW,
DOMAIN,
ENTITY_ID_FORMAT,
LOGGER,
SOURCE_TYPE_GPS,
)
@ -182,7 +181,7 @@ class DeviceTracker:
return
# Guard from calling see on entity registry entities.
entity_id = ENTITY_ID_FORMAT.format(dev_id)
entity_id = f"{DOMAIN}.{dev_id}"
if registry.async_is_registered(entity_id):
LOGGER.error(
"The see service is not supported for this entity %s", entity_id
@ -308,7 +307,7 @@ class Device(RestoreEntity):
) -> None:
"""Initialize a device."""
self.hass = hass
self.entity_id = ENTITY_ID_FORMAT.format(dev_id)
self.entity_id = f"{DOMAIN}.{dev_id}"
# Timedelta object how long we consider a device home if it is not
# detected anymore.
@ -579,5 +578,7 @@ def get_gravatar_for_email(email: str):
Async friendly.
"""
url = "https://www.gravatar.com/avatar/{}.jpg?s=80&d=wavatar"
return url.format(hashlib.md5(email.encode("utf-8").lower()).hexdigest())
return (
f"https://www.gravatar.com/avatar/"
f"{hashlib.md5(email.encode('utf-8').lower()).hexdigest()}.jpg?s=80&d=wavatar"
)

View File

@ -109,9 +109,7 @@ async def async_extract_config(hass, config):
legacy.append(platform)
else:
raise ValueError(
"Unable to determine type for {}: {}".format(
platform.name, platform.type
)
f"Unable to determine type for {platform.name}: {platform.type}"
)
return legacy

View File

@ -97,7 +97,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
elif discovery_info:
host = discovery_info.get("host")
name = "DirecTV_{}".format(discovery_info.get("serial", ""))
name = f"DirecTV_{discovery_info.get('serial', '')}"
# Attempt to discover additional RVU units
_LOGGER.debug("Doing discovery of DirecTV devices on %s", host)
@ -219,9 +219,7 @@ class DirecTvDevice(MediaPlayerDevice):
else:
# If an error is received then only set to unavailable if
# this started at least 1 minute ago.
log_message = "{}: Invalid status {} received".format(
self.entity_id, self._current["status"]["code"]
)
log_message = f"{self.entity_id}: Invalid status {self._current['status']['code']} received"
if self._check_state_available():
_LOGGER.debug(log_message)
else:
@ -370,7 +368,7 @@ class DirecTvDevice(MediaPlayerDevice):
if self._is_standby:
return None
return "{} ({})".format(self._current["callsign"], self._current["major"])
return f"{self._current['callsign']} ({self._current['major']})"
@property
def source(self):

View File

@ -45,7 +45,7 @@ class DlibFaceDetectEntity(ImageProcessingFaceEntity):
if name:
self._name = name
else:
self._name = "Dlib Face {0}".format(split_entity_id(camera_entity)[1])
self._name = f"Dlib Face {split_entity_id(camera_entity)[1]}"
@property
def camera_entity(self):

View File

@ -59,7 +59,7 @@ class DlibFaceIdentifyEntity(ImageProcessingFaceEntity):
if name:
self._name = name
else:
self._name = "Dlib Face {0}".format(split_entity_id(camera_entity)[1])
self._name = f"Dlib Face {split_entity_id(camera_entity)[1]}"
self._faces = {}
for face_name, face_file in faces.items():

View File

@ -66,7 +66,7 @@ def setup(hass, config):
custom_url = doorstation_config.get(CONF_CUSTOM_URL)
events = doorstation_config.get(CONF_EVENTS)
token = doorstation_config.get(CONF_TOKEN)
name = doorstation_config.get(CONF_NAME) or "DoorBird {}".format(index + 1)
name = doorstation_config.get(CONF_NAME) or f"DoorBird {index + 1}"
try:
device = DoorBird(device_ip, username, password)
@ -297,6 +297,6 @@ class DoorBirdRequestView(HomeAssistantView):
hass.bus.async_fire(f"{DOMAIN}_{event}", event_data)
log_entry(hass, "Doorbird {}".format(event), "event was fired.", DOMAIN)
log_entry(hass, f"Doorbird {event}", "event was fired.", DOMAIN)
return web.Response(status=200, text="OK")

View File

@ -12,9 +12,6 @@ import homeassistant.util.dt as dt_util
from . import DOMAIN as DOORBIRD_DOMAIN
_CAMERA_LAST_VISITOR = "{} Last Ring"
_CAMERA_LAST_MOTION = "{} Last Motion"
_CAMERA_LIVE = "{} Live"
_LAST_VISITOR_INTERVAL = datetime.timedelta(minutes=1)
_LAST_MOTION_INTERVAL = datetime.timedelta(minutes=1)
_LIVE_INTERVAL = datetime.timedelta(seconds=1)
@ -30,18 +27,18 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
[
DoorBirdCamera(
device.live_image_url,
_CAMERA_LIVE.format(doorstation.name),
f"{doorstation.name} Live",
_LIVE_INTERVAL,
device.rtsp_live_video_url,
),
DoorBirdCamera(
device.history_image_url(1, "doorbell"),
_CAMERA_LAST_VISITOR.format(doorstation.name),
f"{doorstation.name} Last Ring",
_LAST_VISITOR_INTERVAL,
),
DoorBirdCamera(
device.history_image_url(1, "motionsensor"),
_CAMERA_LAST_MOTION.format(doorstation.name),
f"{doorstation.name} Last Motion",
_LAST_MOTION_INTERVAL,
),
]

View File

@ -85,7 +85,7 @@ class DovadoSensor(Entity):
@property
def name(self):
"""Return the name of the sensor."""
return "{} {}".format(self._data.name, SENSORS[self._sensor][1])
return f"{self._data.name} {SENSORS[self._sensor][1]}"
@property
def state(self):

View File

@ -47,11 +47,9 @@ class DteEnergyBridgeSensor(Entity):
self._version = version
if self._version == 1:
url_template = "http://{}/instantaneousdemand"
self._url = f"http://{ip_address}/instantaneousdemand"
elif self._version == 2:
url_template = "http://{}:8888/zigbee/se/instantaneousdemand"
self._url = url_template.format(ip_address)
self._url = f"http://{ip_address}:8888/zigbee/se/instantaneousdemand"
self._name = name
self._unit_of_measurement = "kW"

View File

@ -175,12 +175,7 @@ class DwdWeatherWarningsAPI:
def __init__(self, region_name):
"""Initialize the data object."""
resource = "{}{}{}?{}".format(
"https://",
"www.dwd.de",
"/DWD/warnungen/warnapp_landkreise/json/warnings.json",
"jsonp=loadWarnings",
)
resource = "https://www.dwd.de/DWD/warnungen/warnapp_landkreise/json/warnings.json?jsonp=loadWarnings"
# a User-Agent is necessary for this rest api endpoint (#29496)
headers = {"User-Agent": HA_USER_AGENT}

View File

@ -89,7 +89,7 @@ class DysonPureHotCoolLinkDevice(ClimateDevice):
if self._device.environmental_state:
temperature_kelvin = self._device.environmental_state.temperature
if temperature_kelvin != 0:
self._current_temp = float("{0:.1f}".format(temperature_kelvin - 273))
self._current_temp = float(f"{(temperature_kelvin - 273):.1f}")
return self._current_temp
@property

View File

@ -216,7 +216,7 @@ class DysonPureCoolLinkDevice(FanEntity):
if speed == FanSpeed.FAN_SPEED_AUTO.value:
self._device.set_configuration(fan_mode=FanMode.AUTO)
else:
fan_speed = FanSpeed("{0:04d}".format(int(speed)))
fan_speed = FanSpeed(f"{int(speed):04d}")
self._device.set_configuration(fan_mode=FanMode.FAN, fan_speed=fan_speed)
def turn_on(self, speed: str = None, **kwargs) -> None:
@ -226,7 +226,7 @@ class DysonPureCoolLinkDevice(FanEntity):
if speed == FanSpeed.FAN_SPEED_AUTO.value:
self._device.set_configuration(fan_mode=FanMode.AUTO)
else:
fan_speed = FanSpeed("{0:04d}".format(int(speed)))
fan_speed = FanSpeed(f"{int(speed):04d}")
self._device.set_configuration(
fan_mode=FanMode.FAN, fan_speed=fan_speed
)
@ -386,7 +386,7 @@ class DysonPureCoolDevice(FanEntity):
"""Set the exact speed of the purecool fan."""
_LOGGER.debug("Set exact speed for fan %s", self.name)
fan_speed = FanSpeed("{0:04d}".format(int(speed)))
fan_speed = FanSpeed(f"{int(speed):04d}")
self._device.set_fan_speed(fan_speed)
def oscillate(self, oscillating: bool) -> None:

View File

@ -43,9 +43,9 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
device_ids = [device.unique_id for device in hass.data[DYSON_SENSOR_DEVICES]]
for device in hass.data[DYSON_DEVICES]:
if isinstance(device, DysonPureCool):
if "{}-{}".format(device.serial, "temperature") not in device_ids:
if f"{device.serial}-temperature" not in device_ids:
devices.append(DysonTemperatureSensor(device, unit))
if "{}-{}".format(device.serial, "humidity") not in device_ids:
if f"{device.serial}-humidity" not in device_ids:
devices.append(DysonHumiditySensor(device))
elif isinstance(device, DysonPureCoolLink):
devices.append(DysonFilterLifeSensor(device))
@ -173,8 +173,8 @@ class DysonTemperatureSensor(DysonSensor):
if temperature_kelvin == 0:
return STATE_OFF
if self._unit == TEMP_CELSIUS:
return float("{0:.1f}".format(temperature_kelvin - 273.15))
return float("{0:.1f}".format(temperature_kelvin * 9 / 5 - 459.67))
return float(f"{(temperature_kelvin - 273.15):.1f}")
return float(f"{(temperature_kelvin * 9 / 5 - 459.67):.1f}")
return None
@property

View File

@ -37,7 +37,7 @@ class EcobeeSensor(Entity):
def __init__(self, data, sensor_name, sensor_type, sensor_index):
"""Initialize the sensor."""
self.data = data
self._name = "{} {}".format(sensor_name, SENSOR_TYPES[sensor_type][0])
self._name = f"{sensor_name} {SENSOR_TYPES[sensor_type][0]}"
self.sensor_name = sensor_name
self.type = sensor_type
self.index = sensor_index

View File

@ -56,10 +56,10 @@ class EcovacsVacuum(VacuumDevice):
self.device = device
self.device.connect_and_wait_until_ready()
if self.device.vacuum.get("nick", None) is not None:
self._name = "{}".format(self.device.vacuum["nick"])
self._name = str(self.device.vacuum["nick"])
else:
# In case there is no nickname defined, use the device id
self._name = "{}".format(self.device.vacuum["did"])
self._name = str(format(self.device.vacuum["did"]))
self._fan_speed = None
self._error = None

View File

@ -63,9 +63,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
dev = []
for variable in config[CONF_MONITORED_VARIABLES]:
if variable[CONF_SENSOR_TYPE] == CONF_CURRENT_VALUES:
url_string = "{}getCurrentValuesSummary?token={}".format(
_RESOURCE, app_token
)
url_string = f"{_RESOURCE}getCurrentValuesSummary?token={app_token}"
response = requests.get(url_string, timeout=10)
for sensor in response.json():
sid = sensor["sid"]
@ -136,9 +134,7 @@ class EfergySensor(Entity):
response = requests.get(url_string, timeout=10)
self._state = response.json()["reading"]
elif self.type == "amount":
url_string = "{}getEnergy?token={}&offset={}&period={}".format(
_RESOURCE, self.app_token, self.utc_offset, self.period
)
url_string = f"{_RESOURCE}getEnergy?token={self.app_token}&offset={self.utc_offset}&period={self.period}"
response = requests.get(url_string, timeout=10)
self._state = response.json()["sum"]
elif self.type == "budget":
@ -146,14 +142,12 @@ class EfergySensor(Entity):
response = requests.get(url_string, timeout=10)
self._state = response.json()["status"]
elif self.type == "cost":
url_string = "{}getCost?token={}&offset={}&period={}".format(
_RESOURCE, self.app_token, self.utc_offset, self.period
)
url_string = f"{_RESOURCE}getCost?token={self.app_token}&offset={self.utc_offset}&period={self.period}"
response = requests.get(url_string, timeout=10)
self._state = response.json()["sum"]
elif self.type == "current_values":
url_string = "{}getCurrentValuesSummary?token={}".format(
_RESOURCE, self.app_token
url_string = (
f"{_RESOURCE}getCurrentValuesSummary?token={self.app_token}"
)
response = requests.get(url_string, timeout=10)
for sensor in response.json():

View File

@ -257,9 +257,7 @@ class ElkEntity(Entity):
uid_start = f"elkm1m_{self._prefix}"
else:
uid_start = "elkm1"
self._unique_id = "{uid_start}_{name}".format(
uid_start=uid_start, name=self._element.default_name("_")
).lower()
self._unique_id = f"{uid_start}_{self._element.default_name('_')}".lower()
@property
def name(self):

View File

@ -178,7 +178,7 @@ class ElkZone(ElkSensor):
ZoneType.PHONE_KEY.value: "phone-classic",
ZoneType.INTERCOM_KEY.value: "deskphone",
}
return "mdi:{}".format(zone_icons.get(self._element.definition, "alarm-bell"))
return f"mdi:{zone_icons.get(self._element.definition, 'alarm-bell')}"
@property
def device_state_attributes(self):

View File

@ -81,12 +81,12 @@ class SmartPlugSwitch(SwitchDevice):
def update(self):
"""Update the PCA switch's state."""
try:
self._emeter_params[ATTR_CURRENT_POWER_W] = "{:.1f}".format(
self._pca.get_current_power(self._device_id)
)
self._emeter_params[ATTR_TOTAL_ENERGY_KWH] = "{:.2f}".format(
self._pca.get_total_consumption(self._device_id)
)
self._emeter_params[
ATTR_CURRENT_POWER_W
] = f"{self._pca.get_current_power(self._device_id):.1f}"
self._emeter_params[
ATTR_TOTAL_ENERGY_KWH
] = f"{self._pca.get_total_consumption(self._device_id):.2f}"
self._available = True
self._state = self._pca.get_state(self._device_id)

View File

@ -64,9 +64,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
def get_id(sensorid, feedtag, feedname, feedid, feeduserid):
"""Return unique identifier for feed / sensor."""
return "emoncms{}_{}_{}_{}_{}".format(
sensorid, feedtag, feedname, feedid, feeduserid
)
return f"emoncms{sensorid}_{feedtag}_{feedname}_{feedid}_{feeduserid}"
def setup_platform(hass, config, add_entities, discovery_info=None):
@ -134,7 +132,7 @@ class EmonCmsSensor(Entity):
# ID if there's only one.
id_for_name = "" if str(sensorid) == "1" else sensorid
# Use the feed name assigned in EmonCMS or fall back to the feed ID
feed_name = elem.get("name") or "Feed {}".format(elem["id"])
feed_name = elem.get("name") or f"Feed {elem['id']}"
self._name = f"EmonCMS{id_for_name} {feed_name}"
else:
self._name = name

View File

@ -617,16 +617,7 @@ def entity_to_json(config, entity):
"""Convert an entity to its Hue bridge JSON representation."""
entity_features = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
unique_id = hashlib.md5(entity.entity_id.encode()).hexdigest()
unique_id = "00:{}:{}:{}:{}:{}:{}:{}-{}".format(
unique_id[0:2],
unique_id[2:4],
unique_id[4:6],
unique_id[6:8],
unique_id[8:10],
unique_id[10:12],
unique_id[12:14],
unique_id[14:16],
)
unique_id = f"00:{unique_id[0:2]}:{unique_id[2:4]}:{unique_id[4:6]}:{unique_id[6:8]}:{unique_id[8:10]}:{unique_id[10:12]}:{unique_id[12:14]}-{unique_id[14:16]}"
state = get_entity_state(config, entity)

View File

@ -26,16 +26,16 @@ class DescriptionXmlView(HomeAssistantView):
@core.callback
def get(self, request):
"""Handle a GET request."""
xml_template = """<?xml version="1.0" encoding="UTF-8" ?>
resp_text = f"""<?xml version="1.0" encoding="UTF-8" ?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<URLBase>http://{0}:{1}/</URLBase>
<URLBase>http://{self.config.advertise_ip}:{self.config.advertise_port}/</URLBase>
<device>
<deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>
<friendlyName>Home Assistant Bridge ({0})</friendlyName>
<friendlyName>Home Assistant Bridge ({self.config.advertise_ip})</friendlyName>
<manufacturer>Royal Philips Electronics</manufacturer>
<manufacturerURL>http://www.philips.com</manufacturerURL>
<modelDescription>Philips hue Personal Wireless Lighting</modelDescription>
@ -48,10 +48,6 @@ class DescriptionXmlView(HomeAssistantView):
</root>
"""
resp_text = xml_template.format(
self.config.advertise_ip, self.config.advertise_port
)
return web.Response(text=resp_text, content_type="text/xml")
@ -77,10 +73,10 @@ class UPNPResponderThread(threading.Thread):
# Note that the double newline at the end of
# this string is required per the SSDP spec
resp_template = """HTTP/1.1 200 OK
resp_template = f"""HTTP/1.1 200 OK
CACHE-CONTROL: max-age=60
EXT:
LOCATION: http://{0}:{1}/description.xml
LOCATION: http://{advertise_ip}:{advertise_port}/description.xml
SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/0.1
hue-bridgeid: 1234
ST: urn:schemas-upnp-org:device:basic:1
@ -88,11 +84,7 @@ USN: uuid:Socket-1_0-221438K0100073::urn:schemas-upnp-org:device:basic:1
"""
self.upnp_response = (
resp_template.format(advertise_ip, advertise_port)
.replace("\n", "\r\n")
.encode("utf-8")
)
self.upnp_response = resp_template.replace("\n", "\r\n").encode("utf-8")
def run(self):
"""Run the server."""

View File

@ -38,7 +38,7 @@ class EmulatedRokuFlowHandler(config_entries.ConfigFlow):
servers_num = len(configured_servers(self.hass))
if servers_num:
default_name = "{} {}".format(DEFAULT_NAME, servers_num + 1)
default_name = f"{DEFAULT_NAME} {servers_num + 1}"
default_port = DEFAULT_PORT + servers_num
else:
default_name = DEFAULT_NAME

View File

@ -111,9 +111,7 @@ class EnOceanSensor(enocean.EnOceanDevice):
super().__init__(dev_id, dev_name)
self._sensor_type = sensor_type
self._device_class = SENSOR_TYPES[self._sensor_type]["class"]
self._dev_name = "{} {}".format(
SENSOR_TYPES[self._sensor_type]["name"], dev_name
)
self._dev_name = f"{SENSOR_TYPES[self._sensor_type]['name']} {dev_name}"
self._unit_of_measurement = SENSOR_TYPES[self._sensor_type]["unit"]
self._icon = SENSOR_TYPES[self._sensor_type]["icon"]
self._state = None

View File

@ -120,7 +120,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
entities = []
for place in data.all_stop_places_quays():
try:
given_name = "{} {}".format(name, data.get_stop_info(place).name)
given_name = f"{name} {data.get_stop_info(place).name}"
except KeyError:
given_name = f"{name} {place}"
@ -231,9 +231,9 @@ class EnturPublicTransportSensor(Entity):
self._attributes[ATTR_NEXT_UP_AT] = calls[1].expected_departure_time.strftime(
"%H:%M"
)
self._attributes[ATTR_NEXT_UP_IN] = "{} min".format(
due_in_minutes(calls[1].expected_departure_time)
)
self._attributes[
ATTR_NEXT_UP_IN
] = f"{due_in_minutes(calls[1].expected_departure_time)} min"
self._attributes[ATTR_NEXT_UP_REALTIME] = calls[1].is_realtime
self._attributes[ATTR_NEXT_UP_DELAY] = calls[1].delay_in_min
@ -242,8 +242,7 @@ class EnturPublicTransportSensor(Entity):
for i, call in enumerate(calls[2:]):
key_name = "departure_#" + str(i + 3)
self._attributes[key_name] = "{}{} {}".format(
"" if bool(call.is_realtime) else "ca. ",
call.expected_departure_time.strftime("%H:%M"),
call.front_display,
self._attributes[key_name] = (
f"{'' if bool(call.is_realtime) else 'ca. '}"
f"{call.expected_departure_time.strftime('%H:%M')} {call.front_display}"
)

View File

@ -113,7 +113,7 @@ class ECSensor(Entity):
metadata = self.ec_data.metadata
sensor_data = conditions.get(self.sensor_type)
self._unique_id = "{}-{}".format(metadata["location"], self.sensor_type)
self._unique_id = f"{metadata['location']}-{self.sensor_type}"
self._attr = {}
self._name = sensor_data.get("label")
value = sensor_data.get("value")

View File

@ -39,20 +39,11 @@ from homeassistant.helpers.typing import ConfigType, HomeAssistantType
# Import config flow so that it's added to the registry
from .config_flow import EsphomeFlowHandler # noqa: F401
from .entry_data import (
DATA_KEY,
DISPATCHER_ON_DEVICE_UPDATE,
DISPATCHER_ON_LIST,
DISPATCHER_ON_STATE,
DISPATCHER_REMOVE_ENTITY,
DISPATCHER_UPDATE_ENTITY,
RuntimeEntryData,
)
from .entry_data import DATA_KEY, RuntimeEntryData
DOMAIN = "esphome"
_LOGGER = logging.getLogger(__name__)
STORAGE_KEY = "esphome.{}"
STORAGE_VERSION = 1
# No config schema - only configuration entry
@ -85,7 +76,7 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool
# Store client in per-config-entry hass.data
store = Store(
hass, STORAGE_VERSION, STORAGE_KEY.format(entry.entry_id), encoder=JSONEncoder
hass, STORAGE_VERSION, f"esphome.{entry.entry_id}", encoder=JSONEncoder
)
entry_data = hass.data[DATA_KEY][entry.entry_id] = RuntimeEntryData(
client=cli, entry_id=entry.entry_id, store=store
@ -403,7 +394,7 @@ async def platform_async_setup_entry(
# Add entities to Home Assistant
async_add_entities(add_entities)
signal = DISPATCHER_ON_LIST.format(entry_id=entry.entry_id)
signal = f"esphome_{entry.entry_id}_on_list"
entry_data.cleanup_callbacks.append(
async_dispatcher_connect(hass, signal, async_list_entities)
)
@ -416,7 +407,7 @@ async def platform_async_setup_entry(
entry_data.state[component_key][state.key] = state
entry_data.async_update_entity(hass, component_key, state.key)
signal = DISPATCHER_ON_STATE.format(entry_id=entry.entry_id)
signal = f"esphome_{entry.entry_id}_on_state"
entry_data.cleanup_callbacks.append(
async_dispatcher_connect(hass, signal, async_entity_state)
)
@ -490,21 +481,29 @@ class EsphomeEntity(Entity):
self._remove_callbacks.append(
async_dispatcher_connect(
self.hass,
DISPATCHER_UPDATE_ENTITY.format(**kwargs),
(
f"esphome_{kwargs.get('entry_id')}"
f"_update_{kwargs.get('component_key')}_{kwargs.get('key')}"
),
self._on_state_update,
)
)
self._remove_callbacks.append(
async_dispatcher_connect(
self.hass, DISPATCHER_REMOVE_ENTITY.format(**kwargs), self.async_remove
self.hass,
(
f"esphome_{kwargs.get('entry_id')}_remove_"
f"{kwargs.get('component_key')}_{kwargs.get('key')}"
),
self.async_remove,
)
)
self._remove_callbacks.append(
async_dispatcher_connect(
self.hass,
DISPATCHER_ON_DEVICE_UPDATE.format(**kwargs),
f"esphome_{kwargs.get('entry_id')}_on_device_update",
self._on_device_update,
)
)

View File

@ -27,11 +27,6 @@ from homeassistant.helpers.storage import Store
from homeassistant.helpers.typing import HomeAssistantType
DATA_KEY = "esphome"
DISPATCHER_UPDATE_ENTITY = "esphome_{entry_id}_update_{component_key}_{key}"
DISPATCHER_REMOVE_ENTITY = "esphome_{entry_id}_remove_{component_key}_{key}"
DISPATCHER_ON_LIST = "esphome_{entry_id}_on_list"
DISPATCHER_ON_DEVICE_UPDATE = "esphome_{entry_id}_on_device_update"
DISPATCHER_ON_STATE = "esphome_{entry_id}_on_state"
# Mapping from ESPHome info type to HA platform
INFO_TYPE_TO_PLATFORM = {
@ -77,9 +72,7 @@ class RuntimeEntryData:
self, hass: HomeAssistantType, component_key: str, key: int
) -> None:
"""Schedule the update of an entity."""
signal = DISPATCHER_UPDATE_ENTITY.format(
entry_id=self.entry_id, component_key=component_key, key=key
)
signal = f"esphome_{self.entry_id}_update_{component_key}_{key}"
async_dispatcher_send(hass, signal)
@callback
@ -87,9 +80,7 @@ class RuntimeEntryData:
self, hass: HomeAssistantType, component_key: str, key: int
) -> None:
"""Schedule the removal of an entity."""
signal = DISPATCHER_REMOVE_ENTITY.format(
entry_id=self.entry_id, component_key=component_key, key=key
)
signal = f"esphome_{self.entry_id}_remove_{component_key}_{key}"
async_dispatcher_send(hass, signal)
async def _ensure_platforms_loaded(
@ -120,19 +111,19 @@ class RuntimeEntryData:
await self._ensure_platforms_loaded(hass, entry, needed_platforms)
# Then send dispatcher event
signal = DISPATCHER_ON_LIST.format(entry_id=self.entry_id)
signal = f"esphome_{self.entry_id}_on_list"
async_dispatcher_send(hass, signal, infos)
@callback
def async_update_state(self, hass: HomeAssistantType, state: EntityState) -> None:
"""Distribute an update of state information to all platforms."""
signal = DISPATCHER_ON_STATE.format(entry_id=self.entry_id)
signal = f"esphome_{self.entry_id}_on_state"
async_dispatcher_send(hass, signal, state)
@callback
def async_update_device_state(self, hass: HomeAssistantType) -> None:
"""Distribute an update of a core device state like availability."""
signal = DISPATCHER_ON_DEVICE_UPDATE.format(entry_id=self.entry_id)
signal = f"esphome_{self.entry_id}_on_device_update"
async_dispatcher_send(hass, signal)
async def async_load_from_store(self) -> Tuple[List[EntityInfo], List[UserService]]:

View File

@ -69,9 +69,7 @@ class EsphomeSensor(EsphomeEntity):
return None
if self._state.missing_state:
return None
return "{:.{prec}f}".format(
self._state.state, prec=self._static_info.accuracy_decimals
)
return f"{self._state.state:.{self._static_info.accuracy_decimals}f}"
@property
def unit_of_measurement(self) -> str:

View File

@ -32,8 +32,6 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{vol.Required(CONF_HOSTS): vol.All(cv.ensure_list, [cv.string])}
)
NAME_FORMAT = "EverLights {} Zone {}"
def color_rgb_to_int(red: int, green: int, blue: int) -> int:
"""Return a RGB color as an integer."""
@ -96,7 +94,7 @@ class EverLightsLight(Light):
@property
def name(self):
"""Return the name of the device."""
return NAME_FORMAT.format(self._mac, self._channel)
return f"EverLights {self._mac} Zone {self._channel}"
@property
def is_on(self):

View File

@ -5,9 +5,9 @@ import logging
from life360 import Life360Error
import voluptuous as vol
from homeassistant.components.device_tracker import CONF_SCAN_INTERVAL
from homeassistant.components.device_tracker.const import (
ENTITY_ID_FORMAT as DT_ENTITY_ID_FORMAT,
from homeassistant.components.device_tracker import (
CONF_SCAN_INTERVAL,
DOMAIN as DEVICE_TRACKER_DOMAIN,
)
from homeassistant.components.zone import async_active_zone
from homeassistant.const import (
@ -180,14 +180,14 @@ class Life360Scanner:
if overdue and not reported and now - self._started > EVENT_DELAY:
self._hass.bus.fire(
EVENT_UPDATE_OVERDUE,
{ATTR_ENTITY_ID: DT_ENTITY_ID_FORMAT.format(dev_id)},
{ATTR_ENTITY_ID: f"{DEVICE_TRACKER_DOMAIN}.{dev_id}"},
)
reported = True
elif not overdue and reported:
self._hass.bus.fire(
EVENT_UPDATE_RESTORED,
{
ATTR_ENTITY_ID: DT_ENTITY_ID_FORMAT.format(dev_id),
ATTR_ENTITY_ID: f"{DEVICE_TRACKER_DOMAIN}.{dev_id}",
ATTR_WAIT: str(last_seen - (prev_seen or self._started)).split(
"."
)[0],

View File

@ -4,7 +4,7 @@ import logging
from homeassistant.components.device_tracker.config_entry import TrackerEntity
from homeassistant.components.device_tracker.const import (
ATTR_SOURCE_TYPE,
ENTITY_ID_FORMAT,
DOMAIN,
SOURCE_TYPE_GPS,
)
from homeassistant.const import (
@ -68,7 +68,7 @@ class OwnTracksEntity(TrackerEntity, RestoreEntity):
"""Set up OwnTracks entity."""
self._dev_id = dev_id
self._data = data or {}
self.entity_id = ENTITY_ID_FORMAT.format(dev_id)
self.entity_id = f"{DOMAIN}.{dev_id}"
@property
def unique_id(self):

View File

@ -11,9 +11,7 @@ from homeassistant.components import (
group,
light,
)
from homeassistant.components.device_tracker.const import (
ENTITY_ID_FORMAT as DT_ENTITY_ID_FORMAT,
)
from homeassistant.components.device_tracker.const import DOMAIN
from homeassistant.const import CONF_PLATFORM, STATE_HOME, STATE_NOT_HOME
from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util
@ -122,7 +120,7 @@ async def test_lights_turn_on_when_coming_home_after_sun_set(hass, scanner):
hass, device_sun_light_trigger.DOMAIN, {device_sun_light_trigger.DOMAIN: {}}
)
hass.states.async_set(DT_ENTITY_ID_FORMAT.format("device_2"), STATE_HOME)
hass.states.async_set(f"{DOMAIN}.device_2", STATE_HOME)
await hass.async_block_till_done()
@ -133,8 +131,8 @@ async def test_lights_turn_on_when_coming_home_after_sun_set(hass, scanner):
async def test_lights_turn_on_when_coming_home_after_sun_set_person(hass, scanner):
"""Test lights turn on when coming home after sun set."""
device_1 = DT_ENTITY_ID_FORMAT.format("device_1")
device_2 = DT_ENTITY_ID_FORMAT.format("device_2")
device_1 = f"{DOMAIN}.device_1"
device_2 = f"{DOMAIN}.device_2"
test_time = datetime(2017, 4, 5, 3, 2, 3, tzinfo=dt_util.UTC)
with patch("homeassistant.util.dt.utcnow", return_value=test_time):

View File

@ -57,7 +57,7 @@ def mock_yaml_devices(hass):
async def test_is_on(hass):
"""Test is_on method."""
entity_id = const.ENTITY_ID_FORMAT.format("test")
entity_id = f"{const.DOMAIN}.test"
hass.states.async_set(entity_id, STATE_HOME)
@ -271,7 +271,7 @@ async def test_entity_attributes(hass, mock_device_tracker_conf):
"""Test the entity attributes."""
devices = mock_device_tracker_conf
dev_id = "test_entity"
entity_id = const.ENTITY_ID_FORMAT.format(dev_id)
entity_id = f"{const.DOMAIN}.{dev_id}"
friendly_name = "Paulus"
picture = "http://placehold.it/200x200"
icon = "mdi:kettle"
@ -303,7 +303,7 @@ async def test_device_hidden(hass, mock_device_tracker_conf):
"""Test hidden devices."""
devices = mock_device_tracker_conf
dev_id = "test_entity"
entity_id = const.ENTITY_ID_FORMAT.format(dev_id)
entity_id = f"{const.DOMAIN}.{dev_id}"
device = legacy.Device(
hass, timedelta(seconds=180), True, dev_id, None, hide_if_away=True
)
@ -350,7 +350,7 @@ async def test_see_service_guard_config_entry(hass, mock_device_tracker_conf):
"""Test the guard if the device is registered in the entity registry."""
mock_entry = Mock()
dev_id = "test"
entity_id = const.ENTITY_ID_FORMAT.format(dev_id)
entity_id = f"{const.DOMAIN}.{dev_id}"
mock_registry(hass, {entity_id: mock_entry})
devices = mock_device_tracker_conf
assert await async_setup_component(hass, device_tracker.DOMAIN, TEST_PLATFORM)

View File

@ -2,11 +2,7 @@
from asynctest import patch
import pytest
from homeassistant.components import device_tracker
from homeassistant.components.device_tracker.const import (
ENTITY_ID_FORMAT,
SOURCE_TYPE_BLUETOOTH,
)
from homeassistant.components.device_tracker.const import DOMAIN, SOURCE_TYPE_BLUETOOTH
from homeassistant.const import CONF_PLATFORM, STATE_HOME, STATE_NOT_HOME
from homeassistant.setup import async_setup_component
@ -35,14 +31,7 @@ async def test_ensure_device_tracker_platform_validation(hass):
dev_id = "paulus"
topic = "/location/paulus"
assert await async_setup_component(
hass,
device_tracker.DOMAIN,
{
device_tracker.DOMAIN: {
CONF_PLATFORM: "mqtt",
"devices": {dev_id: topic},
}
},
hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "mqtt", "devices": {dev_id: topic}}}
)
assert mock_sp.call_count == 1
@ -50,15 +39,13 @@ async def test_ensure_device_tracker_platform_validation(hass):
async def test_new_message(hass, mock_device_tracker_conf):
"""Test new message."""
dev_id = "paulus"
entity_id = ENTITY_ID_FORMAT.format(dev_id)
entity_id = f"{DOMAIN}.{dev_id}"
topic = "/location/paulus"
location = "work"
hass.config.components = set(["mqtt", "zone"])
assert await async_setup_component(
hass,
device_tracker.DOMAIN,
{device_tracker.DOMAIN: {CONF_PLATFORM: "mqtt", "devices": {dev_id: topic}}},
hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "mqtt", "devices": {dev_id: topic}}}
)
async_fire_mqtt_message(hass, topic, location)
await hass.async_block_till_done()
@ -68,7 +55,7 @@ async def test_new_message(hass, mock_device_tracker_conf):
async def test_single_level_wildcard_topic(hass, mock_device_tracker_conf):
"""Test single level wildcard topic."""
dev_id = "paulus"
entity_id = ENTITY_ID_FORMAT.format(dev_id)
entity_id = f"{DOMAIN}.{dev_id}"
subscription = "/location/+/paulus"
topic = "/location/room/paulus"
location = "work"
@ -76,13 +63,8 @@ async def test_single_level_wildcard_topic(hass, mock_device_tracker_conf):
hass.config.components = set(["mqtt", "zone"])
assert await async_setup_component(
hass,
device_tracker.DOMAIN,
{
device_tracker.DOMAIN: {
CONF_PLATFORM: "mqtt",
"devices": {dev_id: subscription},
}
},
DOMAIN,
{DOMAIN: {CONF_PLATFORM: "mqtt", "devices": {dev_id: subscription}}},
)
async_fire_mqtt_message(hass, topic, location)
await hass.async_block_till_done()
@ -92,7 +74,7 @@ async def test_single_level_wildcard_topic(hass, mock_device_tracker_conf):
async def test_multi_level_wildcard_topic(hass, mock_device_tracker_conf):
"""Test multi level wildcard topic."""
dev_id = "paulus"
entity_id = ENTITY_ID_FORMAT.format(dev_id)
entity_id = f"{DOMAIN}.{dev_id}"
subscription = "/location/#"
topic = "/location/room/paulus"
location = "work"
@ -100,13 +82,8 @@ async def test_multi_level_wildcard_topic(hass, mock_device_tracker_conf):
hass.config.components = set(["mqtt", "zone"])
assert await async_setup_component(
hass,
device_tracker.DOMAIN,
{
device_tracker.DOMAIN: {
CONF_PLATFORM: "mqtt",
"devices": {dev_id: subscription},
}
},
DOMAIN,
{DOMAIN: {CONF_PLATFORM: "mqtt", "devices": {dev_id: subscription}}},
)
async_fire_mqtt_message(hass, topic, location)
await hass.async_block_till_done()
@ -116,7 +93,7 @@ async def test_multi_level_wildcard_topic(hass, mock_device_tracker_conf):
async def test_single_level_wildcard_topic_not_matching(hass, mock_device_tracker_conf):
"""Test not matching single level wildcard topic."""
dev_id = "paulus"
entity_id = ENTITY_ID_FORMAT.format(dev_id)
entity_id = f"{DOMAIN}.{dev_id}"
subscription = "/location/+/paulus"
topic = "/location/paulus"
location = "work"
@ -124,13 +101,8 @@ async def test_single_level_wildcard_topic_not_matching(hass, mock_device_tracke
hass.config.components = set(["mqtt", "zone"])
assert await async_setup_component(
hass,
device_tracker.DOMAIN,
{
device_tracker.DOMAIN: {
CONF_PLATFORM: "mqtt",
"devices": {dev_id: subscription},
}
},
DOMAIN,
{DOMAIN: {CONF_PLATFORM: "mqtt", "devices": {dev_id: subscription}}},
)
async_fire_mqtt_message(hass, topic, location)
await hass.async_block_till_done()
@ -140,7 +112,7 @@ async def test_single_level_wildcard_topic_not_matching(hass, mock_device_tracke
async def test_multi_level_wildcard_topic_not_matching(hass, mock_device_tracker_conf):
"""Test not matching multi level wildcard topic."""
dev_id = "paulus"
entity_id = ENTITY_ID_FORMAT.format(dev_id)
entity_id = f"{DOMAIN}.{dev_id}"
subscription = "/location/#"
topic = "/somewhere/room/paulus"
location = "work"
@ -148,13 +120,8 @@ async def test_multi_level_wildcard_topic_not_matching(hass, mock_device_tracker
hass.config.components = set(["mqtt", "zone"])
assert await async_setup_component(
hass,
device_tracker.DOMAIN,
{
device_tracker.DOMAIN: {
CONF_PLATFORM: "mqtt",
"devices": {dev_id: subscription},
}
},
DOMAIN,
{DOMAIN: {CONF_PLATFORM: "mqtt", "devices": {dev_id: subscription}}},
)
async_fire_mqtt_message(hass, topic, location)
await hass.async_block_till_done()
@ -166,7 +133,7 @@ async def test_matching_custom_payload_for_home_and_not_home(
):
"""Test custom payload_home sets state to home and custom payload_not_home sets state to not_home."""
dev_id = "paulus"
entity_id = ENTITY_ID_FORMAT.format(dev_id)
entity_id = f"{DOMAIN}.{dev_id}"
topic = "/location/paulus"
payload_home = "present"
payload_not_home = "not present"
@ -174,9 +141,9 @@ async def test_matching_custom_payload_for_home_and_not_home(
hass.config.components = set(["mqtt", "zone"])
assert await async_setup_component(
hass,
device_tracker.DOMAIN,
DOMAIN,
{
device_tracker.DOMAIN: {
DOMAIN: {
CONF_PLATFORM: "mqtt",
"devices": {dev_id: topic},
"payload_home": payload_home,
@ -198,7 +165,7 @@ async def test_not_matching_custom_payload_for_home_and_not_home(
):
"""Test not matching payload does not set state to home or not_home."""
dev_id = "paulus"
entity_id = ENTITY_ID_FORMAT.format(dev_id)
entity_id = f"{DOMAIN}.{dev_id}"
topic = "/location/paulus"
payload_home = "present"
payload_not_home = "not present"
@ -207,9 +174,9 @@ async def test_not_matching_custom_payload_for_home_and_not_home(
hass.config.components = set(["mqtt", "zone"])
assert await async_setup_component(
hass,
device_tracker.DOMAIN,
DOMAIN,
{
device_tracker.DOMAIN: {
DOMAIN: {
CONF_PLATFORM: "mqtt",
"devices": {dev_id: topic},
"payload_home": payload_home,
@ -226,7 +193,7 @@ async def test_not_matching_custom_payload_for_home_and_not_home(
async def test_matching_source_type(hass, mock_device_tracker_conf):
"""Test setting source type."""
dev_id = "paulus"
entity_id = ENTITY_ID_FORMAT.format(dev_id)
entity_id = f"{DOMAIN}.{dev_id}"
topic = "/location/paulus"
source_type = SOURCE_TYPE_BLUETOOTH
location = "work"
@ -234,9 +201,9 @@ async def test_matching_source_type(hass, mock_device_tracker_conf):
hass.config.components = set(["mqtt", "zone"])
assert await async_setup_component(
hass,
device_tracker.DOMAIN,
DOMAIN,
{
device_tracker.DOMAIN: {
DOMAIN: {
CONF_PLATFORM: "mqtt",
"devices": {dev_id: topic},
"source_type": source_type,

View File

@ -8,7 +8,6 @@ import pytest
from homeassistant.components.device_tracker.legacy import (
DOMAIN as DT_DOMAIN,
ENTITY_ID_FORMAT,
YAML_DEVICES,
)
from homeassistant.const import CONF_PLATFORM
@ -161,7 +160,7 @@ async def test_multi_level_wildcard_topic(hass):
async def test_single_level_wildcard_topic_not_matching(hass):
"""Test not matching single level wildcard topic."""
dev_id = "zanzito"
entity_id = ENTITY_ID_FORMAT.format(dev_id)
entity_id = f"{DT_DOMAIN}.{dev_id}"
subscription = "location/+/zanzito"
topic = "location/zanzito"
location = json.dumps(LOCATION_MESSAGE)
@ -179,7 +178,7 @@ async def test_single_level_wildcard_topic_not_matching(hass):
async def test_multi_level_wildcard_topic_not_matching(hass):
"""Test not matching multi level wildcard topic."""
dev_id = "zanzito"
entity_id = ENTITY_ID_FORMAT.format(dev_id)
entity_id = f"{DT_DOMAIN}.{dev_id}"
subscription = "location/#"
topic = "somewhere/zanzito"
location = json.dumps(LOCATION_MESSAGE)