Merge pull request #59753 from home-assistant/rc

This commit is contained in:
Paulus Schoutsen 2021-11-15 16:02:30 -08:00 committed by GitHub
commit 6069899179
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 81 additions and 29 deletions

View File

@ -105,9 +105,10 @@ def async_get_cloud_coordinators_by_api_key(
) -> list[DataUpdateCoordinator]:
"""Get all DataUpdateCoordinator objects related to a particular API key."""
return [
attrs[DATA_COORDINATOR]
coordinator
for entry_id, attrs in hass.data[DOMAIN].items()
if (entry := hass.config_entries.async_get_entry(entry_id))
and (coordinator := attrs.get(DATA_COORDINATOR))
and entry.data.get(CONF_API_KEY) == api_key
]

View File

@ -141,6 +141,9 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
existing_entry = await self.async_set_unique_id(self._geo_id)
if existing_entry:
self.hass.config_entries.async_update_entry(existing_entry, data=user_input)
self.hass.async_create_task(
self.hass.config_entries.async_reload(existing_entry.entry_id)
)
return self.async_abort(reason="reauth_successful")
return self.async_create_entry(
@ -237,7 +240,7 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
step_id="reauth_confirm", data_schema=API_KEY_DATA_SCHEMA
)
conf = {CONF_API_KEY: user_input[CONF_API_KEY], **self._entry_data_for_reauth}
conf = {**self._entry_data_for_reauth, CONF_API_KEY: user_input[CONF_API_KEY]}
return await self._async_finish_geography(
conf, self._entry_data_for_reauth[CONF_INTEGRATION_TYPE]

View File

@ -375,13 +375,21 @@ class FluxLight(FluxEntity, CoordinatorEntity, LightEntity):
async def _async_turn_on(self, **kwargs: Any) -> None:
"""Turn the specified or all lights on."""
if (brightness := kwargs.get(ATTR_BRIGHTNESS)) is None:
brightness = self.brightness
if not self.is_on:
await self._device.async_turn_on()
if not kwargs:
return
if (brightness := kwargs.get(ATTR_BRIGHTNESS)) is None:
brightness = self.brightness
# If the brightness was previously 0, the light
# will not turn on unless brightness is at least 1
if not brightness:
brightness = 1
elif not brightness:
# If the device was on and brightness was not
# set, it means it was masked by an effect
brightness = 255
# Handle switch to CCT Color Mode
if ATTR_COLOR_TEMP in kwargs:

View File

@ -3,7 +3,7 @@
"name": "Flux LED/MagicHome",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/flux_led",
"requirements": ["flux_led==0.24.17"],
"requirements": ["flux_led==0.24.24"],
"quality_scale": "platinum",
"codeowners": ["@icemanch"],
"iot_class": "local_push",

View File

@ -257,10 +257,10 @@ class FritzBoxTools:
def _update_device_info(self) -> tuple[bool, str | None]:
"""Retrieve latest device information from the FRITZ!Box."""
userinterface = self.connection.call_action("UserInterface1", "GetInfo")
return userinterface.get("NewUpgradeAvailable"), userinterface.get(
version = self.connection.call_action("UserInterface1", "GetInfo").get(
"NewX_AVM-DE_Version"
)
return bool(version), version
def scan_devices(self, now: datetime | None = None) -> None:
"""Scan for new devices and return a list of found device ids."""

View File

@ -3,7 +3,7 @@
"name": "Gree Climate",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/gree",
"requirements": ["greeclimate==0.12.3"],
"requirements": ["greeclimate==0.12.5"],
"codeowners": ["@cmroche"],
"iot_class": "local_polling"
}

View File

@ -3,7 +3,7 @@
"name": "LOOKin",
"documentation": "https://www.home-assistant.io/integrations/lookin/",
"codeowners": ["@ANMalko"],
"requirements": ["aiolookin==0.0.3"],
"requirements": ["aiolookin==0.0.4"],
"zeroconf": ["_lookin._tcp.local."],
"config_flow": true,
"iot_class": "local_push"

View File

@ -3,7 +3,7 @@
"name": "Meteorologisk institutt (Met.no)",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/met",
"requirements": ["pyMetno==0.8.3"],
"requirements": ["pyMetno==0.8.4"],
"codeowners": ["@danielhiversen", "@thimic"],
"iot_class": "cloud_polling"
}

View File

@ -24,6 +24,8 @@ CONF_FORECAST = "forecast"
DEFAULT_FORECAST = 0
DEFAULT_NAME = "Air quality Norway"
OVERRIDE_URL = "https://aa015h6buqvih86i1.api.met.no/weatherapi/airqualityforecast/0.1/"
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_FORECAST, default=DEFAULT_FORECAST): vol.Coerce(int),
@ -72,7 +74,9 @@ class AirSensor(AirQualityEntity):
def __init__(self, name, coordinates, forecast, session):
"""Initialize the sensor."""
self._name = name
self._api = metno.AirQualityData(coordinates, forecast, session)
self._api = metno.AirQualityData(
coordinates, forecast, session, api_url=OVERRIDE_URL
)
@property
def attribution(self) -> str:

View File

@ -2,7 +2,7 @@
"domain": "norway_air",
"name": "Om Luftkvalitet i Norge (Norway Air)",
"documentation": "https://www.home-assistant.io/integrations/norway_air",
"requirements": ["pyMetno==0.8.3"],
"requirements": ["pyMetno==0.8.4"],
"codeowners": [],
"iot_class": "cloud_polling"
}

View File

@ -4,7 +4,7 @@
"single_instance_allowed": "D\u00e9j\u00e0 configur\u00e9. Une seule configuration possible."
},
"create_entry": {
"default": "\n\n Sous Android, ouvrez [l'application OwnTracks] ( {android_url} ), acc\u00e9dez \u00e0 Pr\u00e9f\u00e9rences - > Connexion. Modifiez les param\u00e8tres suivants: \n - Mode: HTTP priv\u00e9 \n - H\u00f4te: {webhook_url} \n - Identification: \n - Nom d'utilisateur: ` <Your name> ` \n - ID de p\u00e9riph\u00e9rique: ` <Your device name> ` \n\n Sur iOS, ouvrez [l'application OwnTracks] ( {ios_url} ), appuyez sur l'ic\u00f4ne (i) en haut \u00e0 gauche - > param\u00e8tres. Modifiez les param\u00e8tres suivants: \n - Mode: HTTP \n - URL: {webhook_url} \n - Activer l'authentification \n - ID utilisateur: ` <Your name> ` \n\n {secret} \n \n Voir [la documentation] ( {docs_url} ) pour plus d'informations."
"default": "\n\n Sous Android, ouvrez [l'application OwnTracks]({android_url}), acc\u00e9dez \u00e0 Pr\u00e9f\u00e9rences - > Connexion. Modifiez les param\u00e8tres suivants: \n - Mode: HTTP priv\u00e9 \n - H\u00f4te: {webhook_url} \n - Identification: \n - Nom d'utilisateur: `'<Votre nom>'` \n - ID de p\u00e9riph\u00e9rique: `'<Nom de votre appareil>'` \n\n Sur iOS, ouvrez [l'application OwnTracks]({ios_url}), appuyez sur l'ic\u00f4ne (i) en haut \u00e0 gauche - > param\u00e8tres. Modifiez les param\u00e8tres suivants: \n - Mode: HTTP \n - URL: {webhook_url} \n - Activer l'authentification \n - ID utilisateur: `'<Votre nom>'` \n\n {secret} \n \n Voir [la documentation]({docs_url}) pour plus d'informations."
},
"step": {
"user": {

View File

@ -177,7 +177,7 @@ NUMBER_TYPES = {
icon="mdi:star-cog",
unit_of_measurement="rpm",
min_value=300,
max_value=2300,
max_value=2200,
step=10,
method="async_set_favorite_rpm",
entity_category=ENTITY_CATEGORY_CONFIG,

View File

@ -2,7 +2,7 @@
"domain": "zeroconf",
"name": "Zero-configuration networking (zeroconf)",
"documentation": "https://www.home-assistant.io/integrations/zeroconf",
"requirements": ["zeroconf==0.36.11"],
"requirements": ["zeroconf==0.36.13"],
"dependencies": ["network", "api"],
"codeowners": ["@bdraco"],
"quality_scale": "internal",

View File

@ -103,6 +103,11 @@ class ZwaveFan(ZWaveBaseEntity, FanEntity):
return None
return ranged_value_to_percentage(SPEED_RANGE, self.info.primary_value.value)
@property
def percentage_step(self) -> float:
"""Return the step size for percentage."""
return 1
@property
def speed_count(self) -> int:
"""Return the number of speeds the fan supports."""

View File

@ -5,7 +5,7 @@ from typing import Final
MAJOR_VERSION: Final = 2021
MINOR_VERSION: Final = 11
PATCH_VERSION: Final = "3"
PATCH_VERSION: Final = "4"
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
__version__: Final = f"{__short_version__}.{PATCH_VERSION}"
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 8, 0)

View File

@ -32,7 +32,7 @@ sqlalchemy==1.4.23
voluptuous-serialize==2.4.0
voluptuous==0.12.2
yarl==1.6.3
zeroconf==0.36.11
zeroconf==0.36.13
pycryptodome>=3.6.6

View File

@ -207,7 +207,7 @@ aiolifx_effects==0.2.2
aiolip==1.1.6
# homeassistant.components.lookin
aiolookin==0.0.3
aiolookin==0.0.4
# homeassistant.components.lyric
aiolyric==1.0.7
@ -652,7 +652,7 @@ fjaraskupan==1.0.2
flipr-api==1.4.1
# homeassistant.components.flux_led
flux_led==0.24.17
flux_led==0.24.24
# homeassistant.components.homekit
fnvhash==0.1.0
@ -747,7 +747,7 @@ gpiozero==1.5.1
gps3==0.33.3
# homeassistant.components.gree
greeclimate==0.12.3
greeclimate==0.12.5
# homeassistant.components.greeneye_monitor
greeneye_monitor==2.1
@ -1312,7 +1312,7 @@ pyMetEireann==2021.8.0
# homeassistant.components.met
# homeassistant.components.norway_air
pyMetno==0.8.3
pyMetno==0.8.4
# homeassistant.components.rfxtrx
pyRFXtrx==0.27.0
@ -2465,7 +2465,7 @@ youtube_dl==2021.06.06
zengge==0.2
# homeassistant.components.zeroconf
zeroconf==0.36.11
zeroconf==0.36.13
# homeassistant.components.zha
zha-quirks==0.0.63

View File

@ -137,7 +137,7 @@ aiokafka==0.6.0
aiolip==1.1.6
# homeassistant.components.lookin
aiolookin==0.0.3
aiolookin==0.0.4
# homeassistant.components.lyric
aiolyric==1.0.7
@ -387,7 +387,7 @@ fjaraskupan==1.0.2
flipr-api==1.4.1
# homeassistant.components.flux_led
flux_led==0.24.17
flux_led==0.24.24
# homeassistant.components.homekit
fnvhash==0.1.0
@ -455,7 +455,7 @@ google-nest-sdm==0.3.8
googlemaps==2.5.1
# homeassistant.components.gree
greeclimate==0.12.3
greeclimate==0.12.5
# homeassistant.components.growatt_server
growattServer==1.1.0
@ -784,7 +784,7 @@ pyMetEireann==2021.8.0
# homeassistant.components.met
# homeassistant.components.norway_air
pyMetno==0.8.3
pyMetno==0.8.4
# homeassistant.components.rfxtrx
pyRFXtrx==0.27.0
@ -1430,7 +1430,7 @@ yeelight==0.7.8
youless-api==0.15
# homeassistant.components.zeroconf
zeroconf==0.36.11
zeroconf==0.36.13
# homeassistant.components.zha
zha-quirks==0.0.63

View File

@ -355,16 +355,19 @@ async def test_step_reauth(hass):
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "reauth_confirm"
new_api_key = "defgh67890"
with patch(
"homeassistant.components.airvisual.async_setup_entry", return_value=True
), patch("pyairvisual.air_quality.AirQuality.nearest_city", return_value=True):
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={CONF_API_KEY: "defgh67890"}
result["flow_id"], user_input={CONF_API_KEY: new_api_key}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == "reauth_successful"
assert len(hass.config_entries.async_entries()) == 1
assert hass.config_entries.async_entries()[0].data[CONF_API_KEY] == new_api_key
async def test_step_user(hass):

View File

@ -214,11 +214,26 @@ async def test_rgb_light(hass: HomeAssistant) -> None:
await async_mock_device_turn_off(hass, bulb)
assert hass.states.get(entity_id).state == STATE_OFF
bulb.brightness = 0
await hass.services.async_call(
LIGHT_DOMAIN,
"turn_on",
{ATTR_ENTITY_ID: entity_id, ATTR_RGB_COLOR: (10, 10, 30)},
blocking=True,
)
# If the bulb is off and we are using existing brightness
# it has to be at least 1 or the bulb won't turn on
bulb.async_set_levels.assert_called_with(10, 10, 30, brightness=1)
bulb.async_set_levels.reset_mock()
bulb.async_turn_on.reset_mock()
await hass.services.async_call(
LIGHT_DOMAIN, "turn_on", {ATTR_ENTITY_ID: entity_id}, blocking=True
)
bulb.async_turn_on.assert_called_once()
bulb.async_turn_on.reset_mock()
await async_mock_device_turn_on(hass, bulb)
assert hass.states.get(entity_id).state == STATE_ON
await hass.services.async_call(
LIGHT_DOMAIN,
@ -229,6 +244,19 @@ async def test_rgb_light(hass: HomeAssistant) -> None:
bulb.async_set_levels.assert_called_with(255, 0, 0, brightness=100)
bulb.async_set_levels.reset_mock()
await hass.services.async_call(
LIGHT_DOMAIN,
"turn_on",
{ATTR_ENTITY_ID: entity_id, ATTR_RGB_COLOR: (10, 10, 30)},
blocking=True,
)
# If the bulb is on and we are using existing brightness
# and brightness was 0 it means we could not read it because
# an effect is in progress so we use 255
bulb.async_set_levels.assert_called_with(10, 10, 30, brightness=255)
bulb.async_set_levels.reset_mock()
bulb.brightness = 128
await hass.services.async_call(
LIGHT_DOMAIN,
"turn_on",