Merge pull request #74760 from home-assistant/rc

This commit is contained in:
Paulus Schoutsen 2022-07-08 16:08:11 -07:00 committed by GitHub
commit 5080246fb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 125 additions and 49 deletions

View File

@ -2,7 +2,7 @@
"domain": "cloud", "domain": "cloud",
"name": "Home Assistant Cloud", "name": "Home Assistant Cloud",
"documentation": "https://www.home-assistant.io/integrations/cloud", "documentation": "https://www.home-assistant.io/integrations/cloud",
"requirements": ["hass-nabucasa==0.54.0"], "requirements": ["hass-nabucasa==0.54.1"],
"dependencies": ["http", "webhook"], "dependencies": ["http", "webhook"],
"after_dependencies": ["google_assistant", "alexa"], "after_dependencies": ["google_assistant", "alexa"],
"codeowners": ["@home-assistant/cloud"], "codeowners": ["@home-assistant/cloud"],

View File

@ -3,7 +3,7 @@
"name": "deCONZ", "name": "deCONZ",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/deconz", "documentation": "https://www.home-assistant.io/integrations/deconz",
"requirements": ["pydeconz==96"], "requirements": ["pydeconz==97"],
"ssdp": [ "ssdp": [
{ {
"manufacturer": "Royal Philips Electronics", "manufacturer": "Royal Philips Electronics",

View File

@ -113,7 +113,7 @@ class FreeboxRouter:
# According to the doc `syst_datas["sensors"]` is temperature sensors in celsius degree. # According to the doc `syst_datas["sensors"]` is temperature sensors in celsius degree.
# Name and id of sensors may vary under Freebox devices. # Name and id of sensors may vary under Freebox devices.
for sensor in syst_datas["sensors"]: for sensor in syst_datas["sensors"]:
self.sensors_temperature[sensor["name"]] = sensor["value"] self.sensors_temperature[sensor["name"]] = sensor.get("value")
# Connection sensors # Connection sensors
connection_datas: dict[str, Any] = await self._api.connection.get_status() connection_datas: dict[str, Any] = await self._api.connection.get_status()

View File

@ -159,7 +159,7 @@ class FreeboxDiskSensor(FreeboxSensor):
self._disk = disk self._disk = disk
self._partition = partition self._partition = partition
self._attr_name = f"{partition['label']} {description.name}" self._attr_name = f"{partition['label']} {description.name}"
self._unique_id = f"{self._router.mac} {description.key} {self._disk['id']} {self._partition['id']}" self._attr_unique_id = f"{self._router.mac} {description.key} {self._disk['id']} {self._partition['id']}"
@property @property
def device_info(self) -> DeviceInfo: def device_info(self) -> DeviceInfo:

View File

@ -8,6 +8,13 @@
"mode": "Travel Mode" "mode": "Travel Mode"
} }
}, },
"origin_menu": {
"title": "Choose Origin",
"menu_options": {
"origin_coordinates": "Using a map location",
"origin_entity": "Using an entity"
}
},
"origin_coordinates": { "origin_coordinates": {
"title": "Choose Origin", "title": "Choose Origin",
"data": { "data": {

View File

@ -39,6 +39,13 @@
}, },
"title": "Choose Origin" "title": "Choose Origin"
}, },
"origin_menu": {
"menu_options": {
"origin_coordinates": "Using a map location",
"origin_entity": "Using an entity"
},
"title": "Choose Origin"
},
"user": { "user": {
"data": { "data": {
"api_key": "API Key", "api_key": "API Key",

View File

@ -183,7 +183,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
entry.data[CONF_IP_ADDRESS], entry.data[CONF_IP_ADDRESS],
entry.data[CONF_PASSWORD], entry.data[CONF_PASSWORD],
port=entry.data[CONF_PORT], port=entry.data[CONF_PORT],
ssl=entry.data.get(CONF_SSL, DEFAULT_SSL), use_ssl=entry.data.get(CONF_SSL, DEFAULT_SSL),
) )
except RainMachineError as err: except RainMachineError as err:
raise ConfigEntryNotReady from err raise ConfigEntryNotReady from err

View File

@ -32,7 +32,7 @@ async def async_get_controller(
websession = aiohttp_client.async_get_clientsession(hass) websession = aiohttp_client.async_get_clientsession(hass)
client = Client(session=websession) client = Client(session=websession)
try: try:
await client.load_local(ip_address, password, port=port, ssl=ssl) await client.load_local(ip_address, password, port=port, use_ssl=ssl)
except RainMachineError: except RainMachineError:
return None return None
else: else:

View File

@ -3,7 +3,7 @@
"name": "RainMachine", "name": "RainMachine",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/rainmachine", "documentation": "https://www.home-assistant.io/integrations/rainmachine",
"requirements": ["regenmaschine==2022.06.1"], "requirements": ["regenmaschine==2022.07.0"],
"codeowners": ["@bachya"], "codeowners": ["@bachya"],
"iot_class": "local_polling", "iot_class": "local_polling",
"homekit": { "homekit": {

View File

@ -80,7 +80,7 @@ class UnifiDeviceScanner(DeviceScanner):
def _connect(self): def _connect(self):
"""Connect to the Unifi AP SSH server.""" """Connect to the Unifi AP SSH server."""
self.ssh = pxssh.pxssh() self.ssh = pxssh.pxssh(options={"HostKeyAlgorithms": "ssh-rsa"})
try: try:
self.ssh.login( self.ssh.login(
self.host, self.username, password=self.password, port=self.port self.host, self.username, password=self.password, port=self.port

View File

@ -141,7 +141,7 @@ class BaseLight(LogMixin, light.LightEntity):
self._color_channel = None self._color_channel = None
self._identify_channel = None self._identify_channel = None
self._default_transition = None self._default_transition = None
self._color_mode = ColorMode.UNKNOWN # Set by sub classes self._attr_color_mode = ColorMode.UNKNOWN # Set by sub classes
@property @property
def extra_state_attributes(self) -> dict[str, Any]: def extra_state_attributes(self) -> dict[str, Any]:
@ -159,11 +159,6 @@ class BaseLight(LogMixin, light.LightEntity):
return False return False
return self._state return self._state
@property
def color_mode(self):
"""Return the color mode of this light."""
return self._color_mode
@property @property
def brightness(self): def brightness(self):
"""Return the brightness of this light.""" """Return the brightness of this light."""
@ -309,7 +304,7 @@ class BaseLight(LogMixin, light.LightEntity):
if isinstance(result, Exception) or result[1] is not Status.SUCCESS: if isinstance(result, Exception) or result[1] is not Status.SUCCESS:
self.debug("turned on: %s", t_log) self.debug("turned on: %s", t_log)
return return
self._color_mode = ColorMode.COLOR_TEMP self._attr_color_mode = ColorMode.COLOR_TEMP
self._color_temp = temperature self._color_temp = temperature
self._hs_color = None self._hs_color = None
@ -323,7 +318,7 @@ class BaseLight(LogMixin, light.LightEntity):
if isinstance(result, Exception) or result[1] is not Status.SUCCESS: if isinstance(result, Exception) or result[1] is not Status.SUCCESS:
self.debug("turned on: %s", t_log) self.debug("turned on: %s", t_log)
return return
self._color_mode = ColorMode.HS self._attr_color_mode = ColorMode.HS
self._hs_color = hs_color self._hs_color = hs_color
self._color_temp = None self._color_temp = None
@ -451,13 +446,13 @@ class Light(BaseLight, ZhaEntity):
self._attr_supported_color_modes self._attr_supported_color_modes
) )
if len(self._attr_supported_color_modes) == 1: if len(self._attr_supported_color_modes) == 1:
self._color_mode = next(iter(self._attr_supported_color_modes)) self._attr_color_mode = next(iter(self._attr_supported_color_modes))
else: # Light supports color_temp + hs, determine which mode the light is in else: # Light supports color_temp + hs, determine which mode the light is in
assert self._color_channel assert self._color_channel
if self._color_channel.color_mode == Color.ColorMode.Color_temperature: if self._color_channel.color_mode == Color.ColorMode.Color_temperature:
self._color_mode = ColorMode.COLOR_TEMP self._attr_color_mode = ColorMode.COLOR_TEMP
else: else:
self._color_mode = ColorMode.HS self._attr_color_mode = ColorMode.HS
if self._identify_channel: if self._identify_channel:
self._supported_features |= light.LightEntityFeature.FLASH self._supported_features |= light.LightEntityFeature.FLASH
@ -518,7 +513,7 @@ class Light(BaseLight, ZhaEntity):
if "off_brightness" in last_state.attributes: if "off_brightness" in last_state.attributes:
self._off_brightness = last_state.attributes["off_brightness"] self._off_brightness = last_state.attributes["off_brightness"]
if "color_mode" in last_state.attributes: if "color_mode" in last_state.attributes:
self._color_mode = ColorMode(last_state.attributes["color_mode"]) self._attr_color_mode = ColorMode(last_state.attributes["color_mode"])
if "color_temp" in last_state.attributes: if "color_temp" in last_state.attributes:
self._color_temp = last_state.attributes["color_temp"] self._color_temp = last_state.attributes["color_temp"]
if "hs_color" in last_state.attributes: if "hs_color" in last_state.attributes:
@ -558,13 +553,13 @@ class Light(BaseLight, ZhaEntity):
if (color_mode := results.get("color_mode")) is not None: if (color_mode := results.get("color_mode")) is not None:
if color_mode == Color.ColorMode.Color_temperature: if color_mode == Color.ColorMode.Color_temperature:
self._color_mode = ColorMode.COLOR_TEMP self._attr_color_mode = ColorMode.COLOR_TEMP
color_temp = results.get("color_temperature") color_temp = results.get("color_temperature")
if color_temp is not None and color_mode: if color_temp is not None and color_mode:
self._color_temp = color_temp self._color_temp = color_temp
self._hs_color = None self._hs_color = None
else: else:
self._color_mode = ColorMode.HS self._attr_color_mode = ColorMode.HS
color_x = results.get("current_x") color_x = results.get("current_x")
color_y = results.get("current_y") color_y = results.get("current_y")
if color_x is not None and color_y is not None: if color_x is not None and color_y is not None:
@ -650,7 +645,7 @@ class LightGroup(BaseLight, ZhaGroupEntity):
CONF_DEFAULT_LIGHT_TRANSITION, CONF_DEFAULT_LIGHT_TRANSITION,
0, 0,
) )
self._color_mode = None self._attr_color_mode = None
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Run when about to be added to hass.""" """Run when about to be added to hass."""

View File

@ -7,7 +7,7 @@ from .backports.enum import StrEnum
MAJOR_VERSION: Final = 2022 MAJOR_VERSION: Final = 2022
MINOR_VERSION: Final = 7 MINOR_VERSION: Final = 7
PATCH_VERSION: Final = "1" PATCH_VERSION: Final = "2"
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}" __short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
__version__: Final = f"{__short_version__}.{PATCH_VERSION}" __version__: Final = f"{__short_version__}.{PATCH_VERSION}"
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 9, 0) REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 9, 0)

View File

@ -6,7 +6,7 @@ aiohttp_cors==0.7.0
astral==2.2 astral==2.2
async-upnp-client==0.31.2 async-upnp-client==0.31.2
async_timeout==4.0.2 async_timeout==4.0.2
atomicwrites==1.4.0 atomicwrites-homeassistant==1.4.1
attrs==21.2.0 attrs==21.2.0
awesomeversion==22.6.0 awesomeversion==22.6.0
bcrypt==3.1.7 bcrypt==3.1.7
@ -14,7 +14,7 @@ certifi>=2021.5.30
ciso8601==2.2.0 ciso8601==2.2.0
cryptography==36.0.2 cryptography==36.0.2
fnvhash==0.1.0 fnvhash==0.1.0
hass-nabucasa==0.54.0 hass-nabucasa==0.54.1
home-assistant-frontend==20220707.0 home-assistant-frontend==20220707.0
httpx==0.23.0 httpx==0.23.0
ifaddr==0.1.7 ifaddr==0.1.7

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "homeassistant" name = "homeassistant"
version = "2022.7.1" version = "2022.7.2"
license = {text = "Apache-2.0"} license = {text = "Apache-2.0"}
description = "Open-source home automation platform running on Python 3." description = "Open-source home automation platform running on Python 3."
readme = "README.rst" readme = "README.rst"
@ -28,7 +28,7 @@ dependencies = [
"astral==2.2", "astral==2.2",
"async_timeout==4.0.2", "async_timeout==4.0.2",
"attrs==21.2.0", "attrs==21.2.0",
"atomicwrites==1.4.0", "atomicwrites-homeassistant==1.4.1",
"awesomeversion==22.6.0", "awesomeversion==22.6.0",
"bcrypt==3.1.7", "bcrypt==3.1.7",
"certifi>=2021.5.30", "certifi>=2021.5.30",

View File

@ -5,7 +5,7 @@ aiohttp==3.8.1
astral==2.2 astral==2.2
async_timeout==4.0.2 async_timeout==4.0.2
attrs==21.2.0 attrs==21.2.0
atomicwrites==1.4.0 atomicwrites-homeassistant==1.4.1
awesomeversion==22.6.0 awesomeversion==22.6.0
bcrypt==3.1.7 bcrypt==3.1.7
certifi>=2021.5.30 certifi>=2021.5.30

View File

@ -795,7 +795,7 @@ habitipy==0.2.0
hangups==0.4.18 hangups==0.4.18
# homeassistant.components.cloud # homeassistant.components.cloud
hass-nabucasa==0.54.0 hass-nabucasa==0.54.1
# homeassistant.components.splunk # homeassistant.components.splunk
hass_splunk==0.1.1 hass_splunk==0.1.1
@ -1444,7 +1444,7 @@ pydaikin==2.7.0
pydanfossair==0.1.0 pydanfossair==0.1.0
# homeassistant.components.deconz # homeassistant.components.deconz
pydeconz==96 pydeconz==97
# homeassistant.components.delijn # homeassistant.components.delijn
pydelijn==1.0.0 pydelijn==1.0.0
@ -2065,7 +2065,7 @@ raincloudy==0.0.7
raspyrfm-client==1.2.8 raspyrfm-client==1.2.8
# homeassistant.components.rainmachine # homeassistant.components.rainmachine
regenmaschine==2022.06.1 regenmaschine==2022.07.0
# homeassistant.components.renault # homeassistant.components.renault
renault-api==0.1.11 renault-api==0.1.11

View File

@ -574,7 +574,7 @@ habitipy==0.2.0
hangups==0.4.18 hangups==0.4.18
# homeassistant.components.cloud # homeassistant.components.cloud
hass-nabucasa==0.54.0 hass-nabucasa==0.54.1
# homeassistant.components.tasmota # homeassistant.components.tasmota
hatasmota==0.5.1 hatasmota==0.5.1
@ -974,7 +974,7 @@ pycoolmasternet-async==0.1.2
pydaikin==2.7.0 pydaikin==2.7.0
# homeassistant.components.deconz # homeassistant.components.deconz
pydeconz==96 pydeconz==97
# homeassistant.components.dexcom # homeassistant.components.dexcom
pydexcom==0.2.3 pydexcom==0.2.3
@ -1376,7 +1376,7 @@ radios==0.1.1
radiotherm==2.1.0 radiotherm==2.1.0
# homeassistant.components.rainmachine # homeassistant.components.rainmachine
regenmaschine==2022.06.1 regenmaschine==2022.07.0
# homeassistant.components.renault # homeassistant.components.renault
renault-api==0.1.11 renault-api==0.1.11

View File

@ -816,6 +816,37 @@ async def test_dont_add_sensor_if_state_is_none(
assert len(hass.states.async_all()) == 0 assert len(hass.states.async_all()) == 0
async def test_air_quality_sensor_without_ppb(hass, aioclient_mock):
"""Test sensor with scaled data is not created if state is None."""
data = {
"sensors": {
"1": {
"config": {
"on": True,
"reachable": True,
},
"ep": 2,
"etag": "c2d2e42396f7c78e11e46c66e2ec0200",
"lastseen": "2020-11-20T22:48Z",
"manufacturername": "BOSCH",
"modelid": "AIR",
"name": "BOSCH Air quality sensor",
"state": {
"airquality": "poor",
"lastupdated": "2020-11-20T22:48:00.209",
},
"swversion": "20200402",
"type": "ZHAAirQuality",
"uniqueid": "00:00:00:00:00:00:00:00-02-fdef",
}
}
}
with patch.dict(DECONZ_WEB_REQUEST, data):
await setup_deconz_integration(hass, aioclient_mock)
assert len(hass.states.async_all()) == 1
async def test_add_battery_later(hass, aioclient_mock, mock_deconz_websocket): async def test_add_battery_later(hass, aioclient_mock, mock_deconz_websocket):
"""Test that a sensor without an initial battery state creates a battery sensor once state exist.""" """Test that a sensor without an initial battery state creates a battery sensor once state exist."""
data = { data = {

View File

@ -1,12 +1,10 @@
"""The tests for the Demo component.""" """The tests for the Demo component."""
from contextlib import suppress
import json import json
import os from unittest.mock import patch
import pytest import pytest
from homeassistant.components.demo import DOMAIN from homeassistant.components.demo import DOMAIN
from homeassistant.components.device_tracker.legacy import YAML_DEVICES
from homeassistant.components.recorder import get_instance from homeassistant.components.recorder import get_instance
from homeassistant.components.recorder.statistics import list_statistic_ids from homeassistant.components.recorder.statistics import list_statistic_ids
from homeassistant.helpers.json import JSONEncoder from homeassistant.helpers.json import JSONEncoder
@ -22,11 +20,10 @@ def mock_history(hass):
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def demo_cleanup(hass): def mock_device_tracker_update_config(hass):
"""Clean up device tracker demo file.""" """Prevent device tracker from creating known devices file."""
yield with patch("homeassistant.components.device_tracker.legacy.update_config"):
with suppress(FileNotFoundError): yield
os.remove(hass.config.path(YAML_DEVICES))
async def test_setting_up_demo(hass): async def test_setting_up_demo(hass):

View File

@ -28,6 +28,8 @@ from homeassistant.helpers.json import JSONEncoder
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from . import common
from tests.common import ( from tests.common import (
assert_setup_component, assert_setup_component,
async_fire_time_changed, async_fire_time_changed,
@ -35,7 +37,6 @@ from tests.common import (
mock_restore_cache, mock_restore_cache,
patch_yaml_files, patch_yaml_files,
) )
from tests.components.device_tracker import common
TEST_PLATFORM = {device_tracker.DOMAIN: {CONF_PLATFORM: "test"}} TEST_PLATFORM = {device_tracker.DOMAIN: {CONF_PLATFORM: "test"}}
@ -165,6 +166,7 @@ async def test_setup_without_yaml_file(hass, enable_custom_integrations):
"""Test with no YAML file.""" """Test with no YAML file."""
with assert_setup_component(1, device_tracker.DOMAIN): with assert_setup_component(1, device_tracker.DOMAIN):
assert await async_setup_component(hass, device_tracker.DOMAIN, TEST_PLATFORM) assert await async_setup_component(hass, device_tracker.DOMAIN, TEST_PLATFORM)
await hass.async_block_till_done()
async def test_gravatar(hass): async def test_gravatar(hass):
@ -210,10 +212,11 @@ async def test_gravatar_and_picture(hass):
@patch("homeassistant.components.demo.device_tracker.setup_scanner", autospec=True) @patch("homeassistant.components.demo.device_tracker.setup_scanner", autospec=True)
async def test_discover_platform(mock_demo_setup_scanner, mock_see, hass): async def test_discover_platform(mock_demo_setup_scanner, mock_see, hass):
"""Test discovery of device_tracker demo platform.""" """Test discovery of device_tracker demo platform."""
await discovery.async_load_platform( with patch("homeassistant.components.device_tracker.legacy.update_config"):
hass, device_tracker.DOMAIN, "demo", {"test_key": "test_val"}, {"bla": {}} await discovery.async_load_platform(
) hass, device_tracker.DOMAIN, "demo", {"test_key": "test_val"}, {"bla": {}}
await hass.async_block_till_done() )
await hass.async_block_till_done()
assert device_tracker.DOMAIN in hass.config.components assert device_tracker.DOMAIN in hass.config.components
assert mock_demo_setup_scanner.called assert mock_demo_setup_scanner.called
assert mock_demo_setup_scanner.call_args[0] == ( assert mock_demo_setup_scanner.call_args[0] == (

View File

@ -22,6 +22,7 @@ DATA_SYSTEM_GET_CONFIG = {
"fans": [{"id": "fan0_speed", "name": "Ventilateur 1", "value": 2130}], "fans": [{"id": "fan0_speed", "name": "Ventilateur 1", "value": 2130}],
"sensors": [ "sensors": [
{"id": "temp_hdd", "name": "Disque dur", "value": 40}, {"id": "temp_hdd", "name": "Disque dur", "value": 40},
{"id": "temp_hdd2", "name": "Disque dur 2"},
{"id": "temp_sw", "name": "Température Switch", "value": 50}, {"id": "temp_sw", "name": "Température Switch", "value": 50},
{"id": "temp_cpum", "name": "Température CPU M", "value": 60}, {"id": "temp_cpum", "name": "Température CPU M", "value": 60},
{"id": "temp_cpub", "name": "Température CPU B", "value": 56}, {"id": "temp_cpub", "name": "Température CPU B", "value": 56},
@ -123,7 +124,42 @@ DATA_STORAGE_GET_DISKS = [
"path": "L0Rpc3F1ZSBkdXI=", "path": "L0Rpc3F1ZSBkdXI=",
} }
], ],
} },
{
"idle_duration": 8290,
"read_error_requests": 0,
"read_requests": 2326826,
"spinning": False,
"table_type": "gpt",
"firmware": "0001",
"type": "sata",
"idle": True,
"connector": 0,
"id": 2000,
"write_error_requests": 0,
"state": "enabled",
"write_requests": 122733632,
"total_bytes": 2000000000000,
"model": "ST2000LM015-2E8174",
"active_duration": 0,
"temp": 0,
"serial": "WDZYJ27Q",
"partitions": [
{
"fstype": "ext4",
"total_bytes": 1960000000000,
"label": "Disque 2",
"id": 2001,
"internal": False,
"fsck_result": "no_run_yet",
"state": "mounted",
"disk_id": 2000,
"free_bytes": 1880000000000,
"used_bytes": 85410000000,
"path": "L0Rpc3F1ZSAy",
}
],
},
] ]
# switch # switch