Merge pull request #44297 from home-assistant/rc

This commit is contained in:
Paulus Schoutsen 2020-12-16 22:31:37 +01:00 committed by GitHub
commit 4ec81d4b67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 98 additions and 58 deletions

View File

@ -29,3 +29,8 @@ async def async_setup_entry(hass, entry: config_entries.ConfigEntry):
hass.config_entries.async_forward_entry_setup(entry, "media_player")
)
return True
async def async_remove_entry(hass, entry):
"""Remove Home Assistant Cast user."""
await home_assistant_cast.async_remove_user(hass, entry)

View File

@ -72,3 +72,14 @@ async def async_setup_ha_cast(
}
),
)
async def async_remove_user(
hass: core.HomeAssistant, entry: config_entries.ConfigEntry
):
"""Remove Home Assistant Cast user."""
user_id: Optional[str] = entry.data.get("user_id")
if user_id is not None:
user = await hass.auth.async_get_user(user_id)
await hass.auth.async_remove_user(user)

View File

@ -2,7 +2,7 @@
"domain": "dsmr",
"name": "DSMR Slimme Meter",
"documentation": "https://www.home-assistant.io/integrations/dsmr",
"requirements": ["dsmr_parser==0.23"],
"requirements": ["dsmr_parser==0.25"],
"codeowners": ["@Robbie1221"],
"config_flow": false
}

View File

@ -2,7 +2,7 @@
"domain": "enphase_envoy",
"name": "Enphase Envoy",
"documentation": "https://www.home-assistant.io/integrations/enphase_envoy",
"requirements": ["envoy_reader==0.17.0"],
"requirements": ["envoy_reader==0.17.3"],
"codeowners": [
"@gtdiehl"
]

View File

@ -365,9 +365,7 @@ class InputDatetime(RestoreEntity):
def async_set_datetime(self, date=None, time=None, datetime=None, timestamp=None):
"""Set a new date / time."""
if timestamp:
datetime = dt_util.as_local(dt_util.utc_from_timestamp(timestamp)).replace(
tzinfo=None
)
datetime = dt_util.as_local(dt_util.utc_from_timestamp(timestamp))
if datetime:
date = datetime.date()
@ -388,8 +386,8 @@ class InputDatetime(RestoreEntity):
if not time:
time = self._current_datetime.time()
self._current_datetime = py_datetime.datetime.combine(date, time).replace(
tzinfo=dt_util.DEFAULT_TIME_ZONE
self._current_datetime = dt_util.DEFAULT_TIME_ZONE.localize(
py_datetime.datetime.combine(date, time)
)
self.async_write_ha_state()

View File

@ -4,7 +4,7 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/recollect_waste",
"requirements": [
"aiorecollect==0.2.2"
"aiorecollect==1.0.1"
],
"codeowners": [
"@bachya"

View File

@ -120,9 +120,11 @@ class RecollectWasteSensor(CoordinatorEntity):
self._state = pickup_event.date
self._attributes.update(
{
ATTR_PICKUP_TYPES: pickup_event.pickup_types,
ATTR_PICKUP_TYPES: [t.name for t in pickup_event.pickup_types],
ATTR_AREA_NAME: pickup_event.area_name,
ATTR_NEXT_PICKUP_TYPES: next_pickup_event.pickup_types,
ATTR_NEXT_PICKUP_TYPES: [
t.name for t in next_pickup_event.pickup_types
],
ATTR_NEXT_PICKUP_DATE: next_date,
}
)

View File

@ -27,12 +27,6 @@ HOST_SCHEMA = vol.Schema({vol.Required(CONF_HOST): str})
HTTP_CONNECT_ERRORS = (asyncio.TimeoutError, aiohttp.ClientError)
def _remove_prefix(shelly_str):
if shelly_str.startswith("shellyswitch"):
return shelly_str[6:]
return shelly_str
async def validate_input(hass: core.HomeAssistant, host, data):
"""Validate the user input allows us to connect.
@ -159,7 +153,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
self.host = zeroconf_info["host"]
# pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
self.context["title_placeholders"] = {
"name": _remove_prefix(zeroconf_info["properties"]["id"])
"name": zeroconf_info.get("name", "").split(".")[0]
}
return await self.async_step_confirm_discovery()

View File

@ -3,7 +3,7 @@
"name": "Tasmota (beta)",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/tasmota",
"requirements": ["hatasmota==0.1.4"],
"requirements": ["hatasmota==0.1.6"],
"dependencies": ["mqtt"],
"mqtt": ["tasmota/discovery/#"],
"codeowners": ["@emontnemery"]

View File

@ -89,12 +89,12 @@ class Metering(ZigbeeChannel):
@property
def divisor(self) -> int:
"""Return divisor for the value."""
return self.cluster.get("divisor")
return self.cluster.get("divisor") or 1
@property
def multiplier(self) -> int:
"""Return multiplier for the value."""
return self.cluster.get("multiplier")
return self.cluster.get("multiplier") or 1
async def async_configure(self) -> None:
"""Configure channel."""

View File

@ -1,7 +1,7 @@
"""Constants used by Home Assistant components."""
MAJOR_VERSION = 2020
MINOR_VERSION = 12
PATCH_VERSION = "0"
PATCH_VERSION = "1"
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
__version__ = f"{__short_version__}.{PATCH_VERSION}"
REQUIRED_PYTHON_VER = (3, 7, 1)

View File

@ -215,7 +215,7 @@ aiopvpc==2.0.2
aiopylgtv==0.3.3
# homeassistant.components.recollect_waste
aiorecollect==0.2.2
aiorecollect==1.0.1
# homeassistant.components.shelly
aioshelly==0.5.1
@ -508,7 +508,7 @@ doorbirdpy==2.1.0
dovado==0.4.1
# homeassistant.components.dsmr
dsmr_parser==0.23
dsmr_parser==0.25
# homeassistant.components.dwd_weather_warnings
dwdwfsapi==1.0.3
@ -559,7 +559,7 @@ env_canada==0.2.4
# envirophat==0.0.6
# homeassistant.components.enphase_envoy
envoy_reader==0.17.0
envoy_reader==0.17.3
# homeassistant.components.season
ephem==3.7.7.0
@ -738,7 +738,7 @@ hass-nabucasa==0.39.0
hass_splunk==0.1.1
# homeassistant.components.tasmota
hatasmota==0.1.4
hatasmota==0.1.6
# homeassistant.components.jewish_calendar
hdate==0.9.12

View File

@ -131,7 +131,7 @@ aiopvpc==2.0.2
aiopylgtv==0.3.3
# homeassistant.components.recollect_waste
aiorecollect==0.2.2
aiorecollect==1.0.1
# homeassistant.components.shelly
aioshelly==0.5.1
@ -269,7 +269,7 @@ distro==1.5.0
doorbirdpy==2.1.0
# homeassistant.components.dsmr
dsmr_parser==0.23
dsmr_parser==0.25
# homeassistant.components.dynalite
dynalite_devices==0.1.46
@ -376,7 +376,7 @@ hangups==0.4.11
hass-nabucasa==0.39.0
# homeassistant.components.tasmota
hatasmota==0.1.4
hatasmota==0.1.6
# homeassistant.components.jewish_calendar
hdate==0.9.12

View File

@ -1,5 +1,6 @@
"""Test Home Assistant Cast."""
from homeassistant import config_entries
from homeassistant.components.cast import home_assistant_cast
from homeassistant.config import async_process_ha_core_config
@ -86,3 +87,32 @@ async def test_use_cloud_url(hass, mock_zeroconf):
assert len(calls) == 1
controller = calls[0][0]
assert controller.hass_url == "https://something.nabu.casa"
async def test_remove_entry(hass, mock_zeroconf):
"""Test removing config entry removes user."""
entry = MockConfigEntry(
connection_class=config_entries.CONN_CLASS_LOCAL_PUSH,
data={},
domain="cast",
title="Google Cast",
)
entry.add_to_hass(hass)
with patch(
"homeassistant.components.cast.media_player._async_setup_platform"
), patch(
"pychromecast.discovery.discover_chromecasts", return_value=(True, None)
), patch(
"pychromecast.discovery.stop_discovery"
):
assert await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert "cast" in hass.config.components
user_id = entry.data.get("user_id")
assert await hass.auth.async_get_user(user_id)
assert await hass.config_entries.async_remove(entry.entry_id)
assert not await hass.auth.async_get_user(user_id)

View File

@ -44,7 +44,7 @@ async def test_setup_provide_implementation(hass):
"homeassistant.components.cloud.account_link._get_services",
return_value=[
{"service": "test", "min_version": "0.1.0"},
{"service": "too_new", "min_version": "100.0.0"},
{"service": "too_new", "min_version": "1000000.0.0"},
],
):
assert (

View File

@ -697,6 +697,15 @@ async def test_timestamp(hass):
).strftime(FMT_DATETIME)
== "2020-12-13 10:00:00"
)
# Use datetime.datetime.fromtimestamp
assert (
dt_util.as_local(
datetime.datetime.fromtimestamp(
state_without_tz.attributes[ATTR_TIMESTAMP]
)
).strftime(FMT_DATETIME)
== "2020-12-13 10:00:00"
)
# Test initial time sets timestamp correctly.
state_time = hass.states.get("input_datetime.test_time_initial")
@ -704,5 +713,24 @@ async def test_timestamp(hass):
assert state_time.state == "10:00:00"
assert state_time.attributes[ATTR_TIMESTAMP] == 10 * 60 * 60
# Test that setting the timestamp of an entity works.
await hass.services.async_call(
DOMAIN,
"set_datetime",
{
ATTR_ENTITY_ID: "input_datetime.test_datetime_initial_with_tz",
ATTR_TIMESTAMP: state_without_tz.attributes[ATTR_TIMESTAMP],
},
blocking=True,
)
state_with_tz_updated = hass.states.get(
"input_datetime.test_datetime_initial_with_tz"
)
assert state_with_tz_updated.state == "2020-12-13 10:00:00"
assert (
state_with_tz_updated.attributes[ATTR_TIMESTAMP]
== state_without_tz.attributes[ATTR_TIMESTAMP]
)
finally:
dt_util.set_default_time_zone(ORIG_TIMEZONE)

View File

@ -20,11 +20,6 @@ DISCOVERY_INFO = {
"name": "shelly1pm-12345",
"properties": {"id": "shelly1pm-12345"},
}
SWITCH25_DISCOVERY_INFO = {
"host": "1.1.1.1",
"name": "shellyswitch25-12345",
"properties": {"id": "shellyswitch25-12345"},
}
async def test_form(hass):
@ -67,7 +62,7 @@ async def test_form(hass):
assert len(mock_setup_entry.mock_calls) == 1
async def test_title_without_name_and_prefix(hass):
async def test_title_without_name(hass):
"""Test we set the title to the hostname when the device doesn't have a name."""
await setup.async_setup_component(hass, "persistent_notification", {})
result = await hass.config_entries.flow.async_init(
@ -330,29 +325,6 @@ async def test_zeroconf(hass):
assert len(mock_setup_entry.mock_calls) == 1
async def test_zeroconf_with_switch_prefix(hass):
"""Test we get remove shelly from the prefix."""
await setup.async_setup_component(hass, "persistent_notification", {})
with patch(
"aioshelly.get_info",
return_value={"mac": "test-mac", "type": "SHSW-1", "auth": False},
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
data=SWITCH25_DISCOVERY_INFO,
context={"source": config_entries.SOURCE_ZEROCONF},
)
assert result["type"] == "form"
assert result["errors"] == {}
context = next(
flow["context"]
for flow in hass.config_entries.flow.async_progress()
if flow["flow_id"] == result["flow_id"]
)
assert context["title_placeholders"]["name"] == "switch25-12345"
@pytest.mark.parametrize(
"error", [(asyncio.TimeoutError, "cannot_connect"), (ValueError, "unknown")]
)