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._state = ticker[self._currency].p15min
self._unit_of_measurement = self._currency self._unit_of_measurement = self._currency
elif self.type == "trade_volume_btc": 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": 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": 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": 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": elif self.type == "difficulty":
self._state = "{0:.0f}".format(stats.difficulty) self._state = f"{stats.difficulty:.0f}"
elif self.type == "minutes_between_blocks": 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": 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": 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": elif self.type == "timestamp":
self._state = stats.timestamp self._state = stats.timestamp
elif self.type == "mined_blocks": elif self.type == "mined_blocks":
self._state = "{}".format(stats.mined_blocks) self._state = str(stats.mined_blocks)
elif self.type == "blocks_size": 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": 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": 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": 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": 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": 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": 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": 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": 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": 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: class BitcoinData:

View File

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

View File

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

View File

@ -500,7 +500,7 @@ class BluesoundPlayer(MediaPlayerDevice):
"image": item.get("@image", ""), "image": item.get("@image", ""),
"is_raw_url": True, "is_raw_url": True,
"url2": item.get("@url", ""), "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 return
selected_source = items[0] selected_source = items[0]
url = "Play?url={}&preset_id&image={}".format( url = f"Play?url={selected_source['url']}&preset_id&image={selected_source['image']}"
selected_source["url"], selected_source["image"]
)
if "is_raw_url" in selected_source and selected_source["is_raw_url"]: if "is_raw_url" in selected_source and selected_source["is_raw_url"]:
url = selected_source["url"] url = selected_source["url"]
@ -1002,7 +1000,7 @@ class BluesoundPlayer(MediaPlayerDevice):
if self.is_grouped and not self.is_master: if self.is_grouped and not self.is_master:
return 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): 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 config.get(CONF_LOCATION) is None:
if not all(config.get(x) for x in (CONF_ID, CONF_DELTA, CONF_FRAMES)): if not all(config.get(x) for x in (CONF_ID, CONF_DELTA, CONF_FRAMES)):
raise vol.Invalid( raise vol.Invalid(
"Specify '{}', '{}' and '{}' when '{}' is unspecified".format( f"Specify '{CONF_ID}', '{CONF_DELTA}' and '{CONF_FRAMES}' when '{CONF_LOCATION}' is unspecified"
CONF_ID, CONF_DELTA, CONF_FRAMES, CONF_LOCATION
)
) )
return config return config
LOCATIONS_MSG = "Set '{}' to one of: {}".format( LOCATIONS_MSG = f"Set '{CONF_LOCATION}' to one of: {', '.join(sorted(LOCATIONS))}"
CONF_LOCATION, ", ".join(sorted(LOCATIONS))
)
XOR_MSG = f"Specify exactly one of '{CONF_ID}' or '{CONF_LOCATION}'" XOR_MSG = f"Specify exactly one of '{CONF_ID}' or '{CONF_LOCATION}'"
PLATFORM_SCHEMA = vol.All( PLATFORM_SCHEMA = vol.All(
@ -106,7 +102,7 @@ PLATFORM_SCHEMA = vol.All(
def setup_platform(hass, config, add_entities, discovery_info=None): def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up BOM radar-loop camera component.""" """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}" name = config.get(CONF_NAME) or f"BOM Radar Loop - {location}"
args = [ args = [
config.get(x) config.get(x)

View File

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

View File

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

View File

@ -44,9 +44,7 @@ DEFAULT_TIMEOUT = 5
SCAN_INTERVAL = timedelta(minutes=2) SCAN_INTERVAL = timedelta(minutes=2)
CODE_STORAGE_KEY = "broadlink_{}_codes"
CODE_STORAGE_VERSION = 1 CODE_STORAGE_VERSION = 1
FLAG_STORAGE_KEY = "broadlink_{}_flags"
FLAG_STORAGE_VERSION = 1 FLAG_STORAGE_VERSION = 1
FLAG_SAVE_DELAY = 15 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 = broadlink.rm((host, DEFAULT_PORT), mac_addr, None)
api.timeout = timeout api.timeout = timeout
code_storage = Store(hass, CODE_STORAGE_VERSION, CODE_STORAGE_KEY.format(unique_id)) code_storage = Store(hass, CODE_STORAGE_VERSION, f"broadlink_{unique_id}_codes")
flag_storage = Store(hass, FLAG_STORAGE_VERSION, FLAG_STORAGE_KEY.format(unique_id)) flag_storage = Store(hass, FLAG_STORAGE_VERSION, f"broadlink_{unique_id}_flags")
remote = BroadlinkRemote(name, unique_id, api, code_storage, flag_storage) remote = BroadlinkRemote(name, unique_id, api, code_storage, flag_storage)
connected, loaded = (False, False) connected, loaded = (False, False)

View File

@ -67,7 +67,7 @@ class BroadlinkSensor(Entity):
def __init__(self, name, broadlink_data, sensor_type): def __init__(self, name, broadlink_data, sensor_type):
"""Initialize the sensor.""" """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._state = None
self._is_available = False self._is_available = False
self._type = sensor_type self._type = sensor_type

View File

@ -7,11 +7,7 @@ import socket
import broadlink import broadlink
import voluptuous as vol import voluptuous as vol
from homeassistant.components.switch import ( from homeassistant.components.switch import DOMAIN, PLATFORM_SCHEMA, SwitchDevice
ENTITY_ID_FORMAT,
PLATFORM_SCHEMA,
SwitchDevice,
)
from homeassistant.const import ( from homeassistant.const import (
CONF_COMMAND_OFF, CONF_COMMAND_OFF,
CONF_COMMAND_ON, CONF_COMMAND_ON,
@ -159,7 +155,7 @@ class BroadlinkRMSwitch(SwitchDevice, RestoreEntity):
self, name, friendly_name, device, command_on, command_off, retry_times self, name, friendly_name, device, command_on, command_off, retry_times
): ):
"""Initialize the switch.""" """Initialize the switch."""
self.entity_id = ENTITY_ID_FORMAT.format(slugify(name)) self.entity_id = f"{DOMAIN}.{slugify(name)}"
self._name = friendly_name self._name = friendly_name
self._state = False self._state = False
self._command_on = command_on 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 # Every Home Assistant instance should have their own unique
# app parameter: https://brottsplatskartan.se/sida/api # app parameter: https://brottsplatskartan.se/sida/api
app = "ha-{}".format(uuid.getnode()) app = f"ha-{uuid.getnode()}"
bpk = brottsplatskartan.BrottsplatsKartan( bpk = brottsplatskartan.BrottsplatsKartan(
app=app, area=area, latitude=latitude, longitude=longitude 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: except (TypeError, KeyError, NameError, ValueError) as ex:
_LOGGER.error("%s", ex) _LOGGER.error("%s", ex)
hass.components.persistent_notification.create( hass.components.persistent_notification.create(
"Error: {}<br />" "Error: {ex}<br />You will need to restart hass after fixing.",
"You will need to restart hass after fixing."
"".format(ex),
title=NOTIFICATION_TITLE, title=NOTIFICATION_TITLE,
notification_id=NOTIFICATION_ID, notification_id=NOTIFICATION_ID,
) )

View File

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

View File

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

View File

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

View File

@ -65,9 +65,7 @@ class CO2Sensor(Entity):
if country_code is not None: if country_code is not None:
device_name = country_code device_name = country_code
else: else:
device_name = "{lat}/{lon}".format( device_name = f"{round(self._latitude, 2)}/{round(self._longitude, 2)}"
lat=round(self._latitude, 2), lon=round(self._longitude, 2)
)
self._friendly_name = f"CO2 intensity - {device_name}" 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 the state attributes of the sensor."""
return { return {
ATTR_ATTRIBUTION: ATTRIBUTION, ATTR_ATTRIBUTION: ATTRIBUTION,
ATTR_NATIVE_BALANCE: "{} {}".format( ATTR_NATIVE_BALANCE: f"{self._native_balance} {self._native_currency}",
self._native_balance, self._native_currency
),
} }
def update(self): def update(self):

View File

@ -237,7 +237,7 @@ class Configurator:
def _generate_unique_id(self): def _generate_unique_id(self):
"""Generate a unique configurator ID.""" """Generate a unique configurator ID."""
self._cur_id += 1 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): def _validate_request_id(self, request_id):
"""Validate that the request belongs to this instance.""" """Validate that the request belongs to this instance."""

View File

@ -47,9 +47,9 @@ class DaikinClimateSensor(Entity):
self._api = api self._api = api
self._sensor = SENSOR_TYPES.get(monitored_state) self._sensor = SENSOR_TYPES.get(monitored_state)
if name is None: 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 self._device_attribute = monitored_state
if self._sensor[CONF_TYPE] == SENSOR_TYPE_TEMPERATURE: if self._sensor[CONF_TYPE] == SENSOR_TYPE_TEMPERATURE:

View File

@ -54,7 +54,7 @@ class DaikinZoneSwitch(ToggleEntity):
@property @property
def name(self): def name(self):
"""Return the name of the sensor.""" """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 @property
def is_on(self): def is_on(self):

View File

@ -61,8 +61,8 @@ def setup(hass, config):
title="Home Assistant", title="Home Assistant",
text=f"%%% \n **{name}** {message} \n %%%", text=f"%%% \n **{name}** {message} \n %%%",
tags=[ tags=[
"entity:{}".format(event.data.get("entity_id")), f"entity:{event.data.get('entity_id')}",
"domain:{}".format(event.data.get("domain")), f"domain:{event.data.get('domain')}",
], ],
) )
@ -84,7 +84,7 @@ def setup(hass, config):
for key, value in states.items(): for key, value in states.items():
if isinstance(value, (float, int)): 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) statsd.gauge(attribute, value, sample_rate=sample_rate, tags=tags)
_LOGGER.debug("Sent metric %s: %s (tags: %s)", attribute, value, 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_SCENE = "scenes"
NEW_SENSOR = "sensors" 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_DARK = "dark"
ATTR_OFFSET = "offset" ATTR_OFFSET = "offset"
ATTR_ON = "on" ATTR_ON = "on"

View File

@ -19,8 +19,9 @@ from .const import (
DEFAULT_ALLOW_DECONZ_GROUPS, DEFAULT_ALLOW_DECONZ_GROUPS,
DOMAIN, DOMAIN,
LOGGER, LOGGER,
NEW_DEVICE,
NEW_GROUP, NEW_GROUP,
NEW_LIGHT,
NEW_SCENE,
NEW_SENSOR, NEW_SENSOR,
SUPPORTED_PLATFORMS, SUPPORTED_PLATFORMS,
) )
@ -186,7 +187,13 @@ class DeconzGateway:
@callback @callback
def async_signal_new_device(self, device_type) -> str: def async_signal_new_device(self, device_type) -> str:
"""Gateway specific event to signal new device.""" """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 @property
def signal_remove_entity(self) -> str: def signal_remove_entity(self) -> str:

View File

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

View File

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

View File

@ -26,7 +26,7 @@ class DemoMailbox(Mailbox):
txt = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " txt = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
for idx in range(0, 10): for idx in range(0, 10):
msgtime = int(dt.as_timestamp(dt.utcnow()) - 3600 * 24 * (10 - idx)) 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() msgsha = sha1(msgtxt.encode("utf-8")).hexdigest()
msg = { msg = {
"info": { "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) 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"] SOUND_MODE_LIST = ["Dummy Music", "Dummy Movie"]
DEFAULT_SOUND_MODE = "Dummy Music" DEFAULT_SOUND_MODE = "Dummy Music"
@ -238,7 +237,7 @@ class DemoYoutubePlayer(AbstractDemoPlayer):
@property @property
def media_image_url(self): def media_image_url(self):
"""Return the image url of current playing media.""" """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 @property
def media_title(self): def media_title(self):

View File

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

View File

@ -82,7 +82,7 @@ class DeutscheBahnSensor(Entity):
self.data.update() self.data.update()
self._state = self.data.connections[0].get("departure", "Unknown") self._state = self.data.connections[0].get("departure", "Unknown")
if self.data.connections[0].get("delay", 0) != 0: 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: class SchieneData:

View File

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

View File

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

View File

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

View File

@ -45,7 +45,7 @@ class DlibFaceDetectEntity(ImageProcessingFaceEntity):
if name: if name:
self._name = name self._name = name
else: 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 @property
def camera_entity(self): def camera_entity(self):

View File

@ -59,7 +59,7 @@ class DlibFaceIdentifyEntity(ImageProcessingFaceEntity):
if name: if name:
self._name = name self._name = name
else: 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 = {} self._faces = {}
for face_name, face_file in faces.items(): 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) custom_url = doorstation_config.get(CONF_CUSTOM_URL)
events = doorstation_config.get(CONF_EVENTS) events = doorstation_config.get(CONF_EVENTS)
token = doorstation_config.get(CONF_TOKEN) 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: try:
device = DoorBird(device_ip, username, password) device = DoorBird(device_ip, username, password)
@ -297,6 +297,6 @@ class DoorBirdRequestView(HomeAssistantView):
hass.bus.async_fire(f"{DOMAIN}_{event}", event_data) 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") 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 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_VISITOR_INTERVAL = datetime.timedelta(minutes=1)
_LAST_MOTION_INTERVAL = datetime.timedelta(minutes=1) _LAST_MOTION_INTERVAL = datetime.timedelta(minutes=1)
_LIVE_INTERVAL = datetime.timedelta(seconds=1) _LIVE_INTERVAL = datetime.timedelta(seconds=1)
@ -30,18 +27,18 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
[ [
DoorBirdCamera( DoorBirdCamera(
device.live_image_url, device.live_image_url,
_CAMERA_LIVE.format(doorstation.name), f"{doorstation.name} Live",
_LIVE_INTERVAL, _LIVE_INTERVAL,
device.rtsp_live_video_url, device.rtsp_live_video_url,
), ),
DoorBirdCamera( DoorBirdCamera(
device.history_image_url(1, "doorbell"), device.history_image_url(1, "doorbell"),
_CAMERA_LAST_VISITOR.format(doorstation.name), f"{doorstation.name} Last Ring",
_LAST_VISITOR_INTERVAL, _LAST_VISITOR_INTERVAL,
), ),
DoorBirdCamera( DoorBirdCamera(
device.history_image_url(1, "motionsensor"), device.history_image_url(1, "motionsensor"),
_CAMERA_LAST_MOTION.format(doorstation.name), f"{doorstation.name} Last Motion",
_LAST_MOTION_INTERVAL, _LAST_MOTION_INTERVAL,
), ),
] ]

View File

@ -85,7 +85,7 @@ class DovadoSensor(Entity):
@property @property
def name(self): def name(self):
"""Return the name of the sensor.""" """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 @property
def state(self): def state(self):

View File

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

View File

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

View File

@ -89,7 +89,7 @@ class DysonPureHotCoolLinkDevice(ClimateDevice):
if self._device.environmental_state: if self._device.environmental_state:
temperature_kelvin = self._device.environmental_state.temperature temperature_kelvin = self._device.environmental_state.temperature
if temperature_kelvin != 0: 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 return self._current_temp
@property @property

View File

@ -216,7 +216,7 @@ class DysonPureCoolLinkDevice(FanEntity):
if speed == FanSpeed.FAN_SPEED_AUTO.value: if speed == FanSpeed.FAN_SPEED_AUTO.value:
self._device.set_configuration(fan_mode=FanMode.AUTO) self._device.set_configuration(fan_mode=FanMode.AUTO)
else: 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) self._device.set_configuration(fan_mode=FanMode.FAN, fan_speed=fan_speed)
def turn_on(self, speed: str = None, **kwargs) -> None: def turn_on(self, speed: str = None, **kwargs) -> None:
@ -226,7 +226,7 @@ class DysonPureCoolLinkDevice(FanEntity):
if speed == FanSpeed.FAN_SPEED_AUTO.value: if speed == FanSpeed.FAN_SPEED_AUTO.value:
self._device.set_configuration(fan_mode=FanMode.AUTO) self._device.set_configuration(fan_mode=FanMode.AUTO)
else: else:
fan_speed = FanSpeed("{0:04d}".format(int(speed))) fan_speed = FanSpeed(f"{int(speed):04d}")
self._device.set_configuration( self._device.set_configuration(
fan_mode=FanMode.FAN, fan_speed=fan_speed fan_mode=FanMode.FAN, fan_speed=fan_speed
) )
@ -386,7 +386,7 @@ class DysonPureCoolDevice(FanEntity):
"""Set the exact speed of the purecool fan.""" """Set the exact speed of the purecool fan."""
_LOGGER.debug("Set exact speed for fan %s", self.name) _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) self._device.set_fan_speed(fan_speed)
def oscillate(self, oscillating: bool) -> None: 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]] device_ids = [device.unique_id for device in hass.data[DYSON_SENSOR_DEVICES]]
for device in hass.data[DYSON_DEVICES]: for device in hass.data[DYSON_DEVICES]:
if isinstance(device, DysonPureCool): 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)) 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)) devices.append(DysonHumiditySensor(device))
elif isinstance(device, DysonPureCoolLink): elif isinstance(device, DysonPureCoolLink):
devices.append(DysonFilterLifeSensor(device)) devices.append(DysonFilterLifeSensor(device))
@ -173,8 +173,8 @@ class DysonTemperatureSensor(DysonSensor):
if temperature_kelvin == 0: if temperature_kelvin == 0:
return STATE_OFF return STATE_OFF
if self._unit == TEMP_CELSIUS: if self._unit == TEMP_CELSIUS:
return float("{0:.1f}".format(temperature_kelvin - 273.15)) return float(f"{(temperature_kelvin - 273.15):.1f}")
return float("{0:.1f}".format(temperature_kelvin * 9 / 5 - 459.67)) return float(f"{(temperature_kelvin * 9 / 5 - 459.67):.1f}")
return None return None
@property @property

View File

@ -37,7 +37,7 @@ class EcobeeSensor(Entity):
def __init__(self, data, sensor_name, sensor_type, sensor_index): def __init__(self, data, sensor_name, sensor_type, sensor_index):
"""Initialize the sensor.""" """Initialize the sensor."""
self.data = data 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.sensor_name = sensor_name
self.type = sensor_type self.type = sensor_type
self.index = sensor_index self.index = sensor_index

View File

@ -56,10 +56,10 @@ class EcovacsVacuum(VacuumDevice):
self.device = device self.device = device
self.device.connect_and_wait_until_ready() self.device.connect_and_wait_until_ready()
if self.device.vacuum.get("nick", None) is not None: 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: else:
# In case there is no nickname defined, use the device id # 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._fan_speed = None
self._error = None self._error = None

View File

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

View File

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

View File

@ -178,7 +178,7 @@ class ElkZone(ElkSensor):
ZoneType.PHONE_KEY.value: "phone-classic", ZoneType.PHONE_KEY.value: "phone-classic",
ZoneType.INTERCOM_KEY.value: "deskphone", 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 @property
def device_state_attributes(self): def device_state_attributes(self):

View File

@ -81,12 +81,12 @@ class SmartPlugSwitch(SwitchDevice):
def update(self): def update(self):
"""Update the PCA switch's state.""" """Update the PCA switch's state."""
try: try:
self._emeter_params[ATTR_CURRENT_POWER_W] = "{:.1f}".format( self._emeter_params[
self._pca.get_current_power(self._device_id) ATTR_CURRENT_POWER_W
) ] = f"{self._pca.get_current_power(self._device_id):.1f}"
self._emeter_params[ATTR_TOTAL_ENERGY_KWH] = "{:.2f}".format( self._emeter_params[
self._pca.get_total_consumption(self._device_id) ATTR_TOTAL_ENERGY_KWH
) ] = f"{self._pca.get_total_consumption(self._device_id):.2f}"
self._available = True self._available = True
self._state = self._pca.get_state(self._device_id) 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): def get_id(sensorid, feedtag, feedname, feedid, feeduserid):
"""Return unique identifier for feed / sensor.""" """Return unique identifier for feed / sensor."""
return "emoncms{}_{}_{}_{}_{}".format( return f"emoncms{sensorid}_{feedtag}_{feedname}_{feedid}_{feeduserid}"
sensorid, feedtag, feedname, feedid, feeduserid
)
def setup_platform(hass, config, add_entities, discovery_info=None): def setup_platform(hass, config, add_entities, discovery_info=None):
@ -134,7 +132,7 @@ class EmonCmsSensor(Entity):
# ID if there's only one. # ID if there's only one.
id_for_name = "" if str(sensorid) == "1" else sensorid id_for_name = "" if str(sensorid) == "1" else sensorid
# Use the feed name assigned in EmonCMS or fall back to the feed ID # 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}" self._name = f"EmonCMS{id_for_name} {feed_name}"
else: else:
self._name = name self._name = name

View File

@ -617,16 +617,7 @@ def entity_to_json(config, entity):
"""Convert an entity to its Hue bridge JSON representation.""" """Convert an entity to its Hue bridge JSON representation."""
entity_features = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0) entity_features = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
unique_id = hashlib.md5(entity.entity_id.encode()).hexdigest() unique_id = hashlib.md5(entity.entity_id.encode()).hexdigest()
unique_id = "00:{}:{}:{}:{}:{}:{}:{}-{}".format( 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]}"
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) state = get_entity_state(config, entity)

View File

@ -26,16 +26,16 @@ class DescriptionXmlView(HomeAssistantView):
@core.callback @core.callback
def get(self, request): def get(self, request):
"""Handle a GET 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"> <root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion> <specVersion>
<major>1</major> <major>1</major>
<minor>0</minor> <minor>0</minor>
</specVersion> </specVersion>
<URLBase>http://{0}:{1}/</URLBase> <URLBase>http://{self.config.advertise_ip}:{self.config.advertise_port}/</URLBase>
<device> <device>
<deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType> <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> <manufacturer>Royal Philips Electronics</manufacturer>
<manufacturerURL>http://www.philips.com</manufacturerURL> <manufacturerURL>http://www.philips.com</manufacturerURL>
<modelDescription>Philips hue Personal Wireless Lighting</modelDescription> <modelDescription>Philips hue Personal Wireless Lighting</modelDescription>
@ -48,10 +48,6 @@ class DescriptionXmlView(HomeAssistantView):
</root> </root>
""" """
resp_text = xml_template.format(
self.config.advertise_ip, self.config.advertise_port
)
return web.Response(text=resp_text, content_type="text/xml") 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 # Note that the double newline at the end of
# this string is required per the SSDP spec # 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 CACHE-CONTROL: max-age=60
EXT: 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 SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/0.1
hue-bridgeid: 1234 hue-bridgeid: 1234
ST: urn:schemas-upnp-org:device:basic:1 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 = ( self.upnp_response = resp_template.replace("\n", "\r\n").encode("utf-8")
resp_template.format(advertise_ip, advertise_port)
.replace("\n", "\r\n")
.encode("utf-8")
)
def run(self): def run(self):
"""Run the server.""" """Run the server."""

View File

@ -38,7 +38,7 @@ class EmulatedRokuFlowHandler(config_entries.ConfigFlow):
servers_num = len(configured_servers(self.hass)) servers_num = len(configured_servers(self.hass))
if servers_num: 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 default_port = DEFAULT_PORT + servers_num
else: else:
default_name = DEFAULT_NAME default_name = DEFAULT_NAME

View File

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

View File

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

View File

@ -113,7 +113,7 @@ class ECSensor(Entity):
metadata = self.ec_data.metadata metadata = self.ec_data.metadata
sensor_data = conditions.get(self.sensor_type) 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._attr = {}
self._name = sensor_data.get("label") self._name = sensor_data.get("label")
value = sensor_data.get("value") 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 # Import config flow so that it's added to the registry
from .config_flow import EsphomeFlowHandler # noqa: F401 from .config_flow import EsphomeFlowHandler # noqa: F401
from .entry_data import ( from .entry_data import DATA_KEY, RuntimeEntryData
DATA_KEY,
DISPATCHER_ON_DEVICE_UPDATE,
DISPATCHER_ON_LIST,
DISPATCHER_ON_STATE,
DISPATCHER_REMOVE_ENTITY,
DISPATCHER_UPDATE_ENTITY,
RuntimeEntryData,
)
DOMAIN = "esphome" DOMAIN = "esphome"
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
STORAGE_KEY = "esphome.{}"
STORAGE_VERSION = 1 STORAGE_VERSION = 1
# No config schema - only configuration entry # 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 client in per-config-entry hass.data
store = Store( 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( entry_data = hass.data[DATA_KEY][entry.entry_id] = RuntimeEntryData(
client=cli, entry_id=entry.entry_id, store=store client=cli, entry_id=entry.entry_id, store=store
@ -403,7 +394,7 @@ async def platform_async_setup_entry(
# Add entities to Home Assistant # Add entities to Home Assistant
async_add_entities(add_entities) 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( entry_data.cleanup_callbacks.append(
async_dispatcher_connect(hass, signal, async_list_entities) 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.state[component_key][state.key] = state
entry_data.async_update_entity(hass, component_key, state.key) 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( entry_data.cleanup_callbacks.append(
async_dispatcher_connect(hass, signal, async_entity_state) async_dispatcher_connect(hass, signal, async_entity_state)
) )
@ -490,21 +481,29 @@ class EsphomeEntity(Entity):
self._remove_callbacks.append( self._remove_callbacks.append(
async_dispatcher_connect( async_dispatcher_connect(
self.hass, 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._on_state_update,
) )
) )
self._remove_callbacks.append( self._remove_callbacks.append(
async_dispatcher_connect( 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( self._remove_callbacks.append(
async_dispatcher_connect( async_dispatcher_connect(
self.hass, self.hass,
DISPATCHER_ON_DEVICE_UPDATE.format(**kwargs), f"esphome_{kwargs.get('entry_id')}_on_device_update",
self._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 from homeassistant.helpers.typing import HomeAssistantType
DATA_KEY = "esphome" 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 # Mapping from ESPHome info type to HA platform
INFO_TYPE_TO_PLATFORM = { INFO_TYPE_TO_PLATFORM = {
@ -77,9 +72,7 @@ class RuntimeEntryData:
self, hass: HomeAssistantType, component_key: str, key: int self, hass: HomeAssistantType, component_key: str, key: int
) -> None: ) -> None:
"""Schedule the update of an entity.""" """Schedule the update of an entity."""
signal = DISPATCHER_UPDATE_ENTITY.format( signal = f"esphome_{self.entry_id}_update_{component_key}_{key}"
entry_id=self.entry_id, component_key=component_key, key=key
)
async_dispatcher_send(hass, signal) async_dispatcher_send(hass, signal)
@callback @callback
@ -87,9 +80,7 @@ class RuntimeEntryData:
self, hass: HomeAssistantType, component_key: str, key: int self, hass: HomeAssistantType, component_key: str, key: int
) -> None: ) -> None:
"""Schedule the removal of an entity.""" """Schedule the removal of an entity."""
signal = DISPATCHER_REMOVE_ENTITY.format( signal = f"esphome_{self.entry_id}_remove_{component_key}_{key}"
entry_id=self.entry_id, component_key=component_key, key=key
)
async_dispatcher_send(hass, signal) async_dispatcher_send(hass, signal)
async def _ensure_platforms_loaded( async def _ensure_platforms_loaded(
@ -120,19 +111,19 @@ class RuntimeEntryData:
await self._ensure_platforms_loaded(hass, entry, needed_platforms) await self._ensure_platforms_loaded(hass, entry, needed_platforms)
# Then send dispatcher event # 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) async_dispatcher_send(hass, signal, infos)
@callback @callback
def async_update_state(self, hass: HomeAssistantType, state: EntityState) -> None: def async_update_state(self, hass: HomeAssistantType, state: EntityState) -> None:
"""Distribute an update of state information to all platforms.""" """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) async_dispatcher_send(hass, signal, state)
@callback @callback
def async_update_device_state(self, hass: HomeAssistantType) -> None: def async_update_device_state(self, hass: HomeAssistantType) -> None:
"""Distribute an update of a core device state like availability.""" """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_dispatcher_send(hass, signal)
async def async_load_from_store(self) -> Tuple[List[EntityInfo], List[UserService]]: async def async_load_from_store(self) -> Tuple[List[EntityInfo], List[UserService]]:

View File

@ -69,9 +69,7 @@ class EsphomeSensor(EsphomeEntity):
return None return None
if self._state.missing_state: if self._state.missing_state:
return None return None
return "{:.{prec}f}".format( return f"{self._state.state:.{self._static_info.accuracy_decimals}f}"
self._state.state, prec=self._static_info.accuracy_decimals
)
@property @property
def unit_of_measurement(self) -> str: 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])} {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: def color_rgb_to_int(red: int, green: int, blue: int) -> int:
"""Return a RGB color as an integer.""" """Return a RGB color as an integer."""
@ -96,7 +94,7 @@ class EverLightsLight(Light):
@property @property
def name(self): def name(self):
"""Return the name of the device.""" """Return the name of the device."""
return NAME_FORMAT.format(self._mac, self._channel) return f"EverLights {self._mac} Zone {self._channel}"
@property @property
def is_on(self): def is_on(self):

View File

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

View File

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

View File

@ -11,9 +11,7 @@ from homeassistant.components import (
group, group,
light, light,
) )
from homeassistant.components.device_tracker.const import ( from homeassistant.components.device_tracker.const import DOMAIN
ENTITY_ID_FORMAT as DT_ENTITY_ID_FORMAT,
)
from homeassistant.const import CONF_PLATFORM, STATE_HOME, STATE_NOT_HOME from homeassistant.const import CONF_PLATFORM, STATE_HOME, STATE_NOT_HOME
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util 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, 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() 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): 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.""" """Test lights turn on when coming home after sun set."""
device_1 = DT_ENTITY_ID_FORMAT.format("device_1") device_1 = f"{DOMAIN}.device_1"
device_2 = DT_ENTITY_ID_FORMAT.format("device_2") device_2 = f"{DOMAIN}.device_2"
test_time = datetime(2017, 4, 5, 3, 2, 3, tzinfo=dt_util.UTC) test_time = datetime(2017, 4, 5, 3, 2, 3, tzinfo=dt_util.UTC)
with patch("homeassistant.util.dt.utcnow", return_value=test_time): 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): async def test_is_on(hass):
"""Test is_on method.""" """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) 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.""" """Test the entity attributes."""
devices = mock_device_tracker_conf devices = mock_device_tracker_conf
dev_id = "test_entity" dev_id = "test_entity"
entity_id = const.ENTITY_ID_FORMAT.format(dev_id) entity_id = f"{const.DOMAIN}.{dev_id}"
friendly_name = "Paulus" friendly_name = "Paulus"
picture = "http://placehold.it/200x200" picture = "http://placehold.it/200x200"
icon = "mdi:kettle" icon = "mdi:kettle"
@ -303,7 +303,7 @@ async def test_device_hidden(hass, mock_device_tracker_conf):
"""Test hidden devices.""" """Test hidden devices."""
devices = mock_device_tracker_conf devices = mock_device_tracker_conf
dev_id = "test_entity" dev_id = "test_entity"
entity_id = const.ENTITY_ID_FORMAT.format(dev_id) entity_id = f"{const.DOMAIN}.{dev_id}"
device = legacy.Device( device = legacy.Device(
hass, timedelta(seconds=180), True, dev_id, None, hide_if_away=True 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.""" """Test the guard if the device is registered in the entity registry."""
mock_entry = Mock() mock_entry = Mock()
dev_id = "test" 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}) mock_registry(hass, {entity_id: mock_entry})
devices = mock_device_tracker_conf devices = mock_device_tracker_conf
assert await async_setup_component(hass, device_tracker.DOMAIN, TEST_PLATFORM) assert await async_setup_component(hass, device_tracker.DOMAIN, TEST_PLATFORM)

View File

@ -2,11 +2,7 @@
from asynctest import patch from asynctest import patch
import pytest import pytest
from homeassistant.components import device_tracker from homeassistant.components.device_tracker.const import DOMAIN, SOURCE_TYPE_BLUETOOTH
from homeassistant.components.device_tracker.const import (
ENTITY_ID_FORMAT,
SOURCE_TYPE_BLUETOOTH,
)
from homeassistant.const import CONF_PLATFORM, STATE_HOME, STATE_NOT_HOME from homeassistant.const import CONF_PLATFORM, STATE_HOME, STATE_NOT_HOME
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
@ -35,14 +31,7 @@ async def test_ensure_device_tracker_platform_validation(hass):
dev_id = "paulus" dev_id = "paulus"
topic = "/location/paulus" topic = "/location/paulus"
assert await async_setup_component( assert await async_setup_component(
hass, hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "mqtt", "devices": {dev_id: topic}}}
device_tracker.DOMAIN,
{
device_tracker.DOMAIN: {
CONF_PLATFORM: "mqtt",
"devices": {dev_id: topic},
}
},
) )
assert mock_sp.call_count == 1 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): async def test_new_message(hass, mock_device_tracker_conf):
"""Test new message.""" """Test new message."""
dev_id = "paulus" dev_id = "paulus"
entity_id = ENTITY_ID_FORMAT.format(dev_id) entity_id = f"{DOMAIN}.{dev_id}"
topic = "/location/paulus" topic = "/location/paulus"
location = "work" location = "work"
hass.config.components = set(["mqtt", "zone"]) hass.config.components = set(["mqtt", "zone"])
assert await async_setup_component( assert await async_setup_component(
hass, hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "mqtt", "devices": {dev_id: topic}}}
device_tracker.DOMAIN,
{device_tracker.DOMAIN: {CONF_PLATFORM: "mqtt", "devices": {dev_id: topic}}},
) )
async_fire_mqtt_message(hass, topic, location) async_fire_mqtt_message(hass, topic, location)
await hass.async_block_till_done() 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): async def test_single_level_wildcard_topic(hass, mock_device_tracker_conf):
"""Test single level wildcard topic.""" """Test single level wildcard topic."""
dev_id = "paulus" dev_id = "paulus"
entity_id = ENTITY_ID_FORMAT.format(dev_id) entity_id = f"{DOMAIN}.{dev_id}"
subscription = "/location/+/paulus" subscription = "/location/+/paulus"
topic = "/location/room/paulus" topic = "/location/room/paulus"
location = "work" location = "work"
@ -76,13 +63,8 @@ async def test_single_level_wildcard_topic(hass, mock_device_tracker_conf):
hass.config.components = set(["mqtt", "zone"]) hass.config.components = set(["mqtt", "zone"])
assert await async_setup_component( assert await async_setup_component(
hass, hass,
device_tracker.DOMAIN, DOMAIN,
{ {DOMAIN: {CONF_PLATFORM: "mqtt", "devices": {dev_id: subscription}}},
device_tracker.DOMAIN: {
CONF_PLATFORM: "mqtt",
"devices": {dev_id: subscription},
}
},
) )
async_fire_mqtt_message(hass, topic, location) async_fire_mqtt_message(hass, topic, location)
await hass.async_block_till_done() 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): async def test_multi_level_wildcard_topic(hass, mock_device_tracker_conf):
"""Test multi level wildcard topic.""" """Test multi level wildcard topic."""
dev_id = "paulus" dev_id = "paulus"
entity_id = ENTITY_ID_FORMAT.format(dev_id) entity_id = f"{DOMAIN}.{dev_id}"
subscription = "/location/#" subscription = "/location/#"
topic = "/location/room/paulus" topic = "/location/room/paulus"
location = "work" location = "work"
@ -100,13 +82,8 @@ async def test_multi_level_wildcard_topic(hass, mock_device_tracker_conf):
hass.config.components = set(["mqtt", "zone"]) hass.config.components = set(["mqtt", "zone"])
assert await async_setup_component( assert await async_setup_component(
hass, hass,
device_tracker.DOMAIN, DOMAIN,
{ {DOMAIN: {CONF_PLATFORM: "mqtt", "devices": {dev_id: subscription}}},
device_tracker.DOMAIN: {
CONF_PLATFORM: "mqtt",
"devices": {dev_id: subscription},
}
},
) )
async_fire_mqtt_message(hass, topic, location) async_fire_mqtt_message(hass, topic, location)
await hass.async_block_till_done() 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): async def test_single_level_wildcard_topic_not_matching(hass, mock_device_tracker_conf):
"""Test not matching single level wildcard topic.""" """Test not matching single level wildcard topic."""
dev_id = "paulus" dev_id = "paulus"
entity_id = ENTITY_ID_FORMAT.format(dev_id) entity_id = f"{DOMAIN}.{dev_id}"
subscription = "/location/+/paulus" subscription = "/location/+/paulus"
topic = "/location/paulus" topic = "/location/paulus"
location = "work" 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"]) hass.config.components = set(["mqtt", "zone"])
assert await async_setup_component( assert await async_setup_component(
hass, hass,
device_tracker.DOMAIN, DOMAIN,
{ {DOMAIN: {CONF_PLATFORM: "mqtt", "devices": {dev_id: subscription}}},
device_tracker.DOMAIN: {
CONF_PLATFORM: "mqtt",
"devices": {dev_id: subscription},
}
},
) )
async_fire_mqtt_message(hass, topic, location) async_fire_mqtt_message(hass, topic, location)
await hass.async_block_till_done() 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): async def test_multi_level_wildcard_topic_not_matching(hass, mock_device_tracker_conf):
"""Test not matching multi level wildcard topic.""" """Test not matching multi level wildcard topic."""
dev_id = "paulus" dev_id = "paulus"
entity_id = ENTITY_ID_FORMAT.format(dev_id) entity_id = f"{DOMAIN}.{dev_id}"
subscription = "/location/#" subscription = "/location/#"
topic = "/somewhere/room/paulus" topic = "/somewhere/room/paulus"
location = "work" 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"]) hass.config.components = set(["mqtt", "zone"])
assert await async_setup_component( assert await async_setup_component(
hass, hass,
device_tracker.DOMAIN, DOMAIN,
{ {DOMAIN: {CONF_PLATFORM: "mqtt", "devices": {dev_id: subscription}}},
device_tracker.DOMAIN: {
CONF_PLATFORM: "mqtt",
"devices": {dev_id: subscription},
}
},
) )
async_fire_mqtt_message(hass, topic, location) async_fire_mqtt_message(hass, topic, location)
await hass.async_block_till_done() 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.""" """Test custom payload_home sets state to home and custom payload_not_home sets state to not_home."""
dev_id = "paulus" dev_id = "paulus"
entity_id = ENTITY_ID_FORMAT.format(dev_id) entity_id = f"{DOMAIN}.{dev_id}"
topic = "/location/paulus" topic = "/location/paulus"
payload_home = "present" payload_home = "present"
payload_not_home = "not 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"]) hass.config.components = set(["mqtt", "zone"])
assert await async_setup_component( assert await async_setup_component(
hass, hass,
device_tracker.DOMAIN, DOMAIN,
{ {
device_tracker.DOMAIN: { DOMAIN: {
CONF_PLATFORM: "mqtt", CONF_PLATFORM: "mqtt",
"devices": {dev_id: topic}, "devices": {dev_id: topic},
"payload_home": payload_home, "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.""" """Test not matching payload does not set state to home or not_home."""
dev_id = "paulus" dev_id = "paulus"
entity_id = ENTITY_ID_FORMAT.format(dev_id) entity_id = f"{DOMAIN}.{dev_id}"
topic = "/location/paulus" topic = "/location/paulus"
payload_home = "present" payload_home = "present"
payload_not_home = "not 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"]) hass.config.components = set(["mqtt", "zone"])
assert await async_setup_component( assert await async_setup_component(
hass, hass,
device_tracker.DOMAIN, DOMAIN,
{ {
device_tracker.DOMAIN: { DOMAIN: {
CONF_PLATFORM: "mqtt", CONF_PLATFORM: "mqtt",
"devices": {dev_id: topic}, "devices": {dev_id: topic},
"payload_home": payload_home, "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): async def test_matching_source_type(hass, mock_device_tracker_conf):
"""Test setting source type.""" """Test setting source type."""
dev_id = "paulus" dev_id = "paulus"
entity_id = ENTITY_ID_FORMAT.format(dev_id) entity_id = f"{DOMAIN}.{dev_id}"
topic = "/location/paulus" topic = "/location/paulus"
source_type = SOURCE_TYPE_BLUETOOTH source_type = SOURCE_TYPE_BLUETOOTH
location = "work" location = "work"
@ -234,9 +201,9 @@ async def test_matching_source_type(hass, mock_device_tracker_conf):
hass.config.components = set(["mqtt", "zone"]) hass.config.components = set(["mqtt", "zone"])
assert await async_setup_component( assert await async_setup_component(
hass, hass,
device_tracker.DOMAIN, DOMAIN,
{ {
device_tracker.DOMAIN: { DOMAIN: {
CONF_PLATFORM: "mqtt", CONF_PLATFORM: "mqtt",
"devices": {dev_id: topic}, "devices": {dev_id: topic},
"source_type": source_type, "source_type": source_type,

View File

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