Merge pull request #43561 from home-assistant/rc

This commit is contained in:
Paulus Schoutsen 2020-11-23 15:37:34 +01:00 committed by GitHub
commit d84d819b62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 57 additions and 21 deletions

View File

@ -1,11 +1,11 @@
{ {
"image": "homeassistant/{arch}-homeassistant", "image": "homeassistant/{arch}-homeassistant",
"build_from": { "build_from": {
"aarch64": "homeassistant/aarch64-homeassistant-base:2020.10.1", "aarch64": "homeassistant/aarch64-homeassistant-base:2020.11.2",
"armhf": "homeassistant/armhf-homeassistant-base:2020.10.1", "armhf": "homeassistant/armhf-homeassistant-base:2020.11.2",
"armv7": "homeassistant/armv7-homeassistant-base:2020.10.1", "armv7": "homeassistant/armv7-homeassistant-base:2020.11.2",
"amd64": "homeassistant/amd64-homeassistant-base:2020.10.1", "amd64": "homeassistant/amd64-homeassistant-base:2020.11.2",
"i386": "homeassistant/i386-homeassistant-base:2020.10.1" "i386": "homeassistant/i386-homeassistant-base:2020.11.2"
}, },
"labels": { "labels": {
"io.hass.type": "core" "io.hass.type": "core"

View File

@ -155,6 +155,9 @@ class IQVIAEntity(CoordinatorEntity):
@callback @callback
def _handle_coordinator_update(self) -> None: def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator.""" """Handle updated data from the coordinator."""
if not self.coordinator.last_update_success:
return
self.update_from_latest_data() self.update_from_latest_data()
self.async_write_ha_state() self.async_write_ha_state()

View File

@ -105,6 +105,7 @@ class ForecastSensor(IQVIAEntity):
def update_from_latest_data(self): def update_from_latest_data(self):
"""Update the sensor.""" """Update the sensor."""
data = self.coordinator.data.get("Location") data = self.coordinator.data.get("Location")
if not data or not data.get("periods"): if not data or not data.get("periods"):
return return
@ -142,6 +143,9 @@ class IndexSensor(IQVIAEntity):
@callback @callback
def update_from_latest_data(self): def update_from_latest_data(self):
"""Update the sensor.""" """Update the sensor."""
if not self.coordinator.last_update_success:
return
try: try:
if self._type in (TYPE_ALLERGY_TODAY, TYPE_ALLERGY_TOMORROW): if self._type in (TYPE_ALLERGY_TODAY, TYPE_ALLERGY_TOMORROW):
data = self.coordinator.data.get("Location") data = self.coordinator.data.get("Location")

View File

@ -104,7 +104,10 @@ class KodiConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
self._host = discovery_info["host"] self._host = discovery_info["host"]
self._port = int(discovery_info["port"]) self._port = int(discovery_info["port"])
self._name = discovery_info["hostname"][: -len(".local.")] self._name = discovery_info["hostname"][: -len(".local.")]
uuid = discovery_info["properties"]["uuid"] uuid = discovery_info["properties"].get("uuid")
if not uuid:
return self.async_abort(reason="no_uuid")
self._discovery_name = discovery_info["name"] self._discovery_name = discovery_info["name"]
await self.async_set_unique_id(uuid) await self.async_set_unique_id(uuid)

View File

@ -37,7 +37,8 @@
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]", "already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]", "invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"unknown": "[%key:common::config_flow::error::unknown%]" "unknown": "[%key:common::config_flow::error::unknown%]",
"no_uuid": "Kodi instance does not have a unique id. This is most likely due to an old Kodi version (17.x or below). You can configure the integration manually or upgrade to a more recent Kodi version."
} }
}, },
"device_automation": { "device_automation": {

View File

@ -163,14 +163,17 @@ class NotionEntity(CoordinatorEntity):
self._sensor_id = sensor_id self._sensor_id = sensor_id
self._state = None self._state = None
self._system_id = system_id self._system_id = system_id
self._task_id = task_id self._unique_id = (
f'{sensor_id}_{self.coordinator.data["tasks"][task_id]["task_type"]}'
)
self.task_id = task_id
@property @property
def available(self) -> bool: def available(self) -> bool:
"""Return True if entity is available.""" """Return True if entity is available."""
return ( return (
self.coordinator.last_update_success self.coordinator.last_update_success
and self._task_id in self.coordinator.data["tasks"] and self.task_id in self.coordinator.data["tasks"]
) )
@property @property
@ -207,8 +210,7 @@ class NotionEntity(CoordinatorEntity):
@property @property
def unique_id(self) -> str: def unique_id(self) -> str:
"""Return a unique, unchanging string that represents this entity.""" """Return a unique, unchanging string that represents this entity."""
task = self.coordinator.data["tasks"][self._task_id] return self._unique_id
return f'{self._sensor_id}_{task["task_type"]}'
async def _async_update_bridge_id(self) -> None: async def _async_update_bridge_id(self) -> None:
"""Update the entity's bridge ID if it has changed. """Update the entity's bridge ID if it has changed.
@ -249,8 +251,10 @@ class NotionEntity(CoordinatorEntity):
@callback @callback
def _handle_coordinator_update(self): def _handle_coordinator_update(self):
"""Respond to a DataUpdateCoordinator update.""" """Respond to a DataUpdateCoordinator update."""
if self.task_id in self.coordinator.data["tasks"]:
self.hass.async_create_task(self._async_update_bridge_id()) self.hass.async_create_task(self._async_update_bridge_id())
self._async_update_from_latest_data() self._async_update_from_latest_data()
self.async_write_ha_state() self.async_write_ha_state()
async def async_added_to_hass(self): async def async_added_to_hass(self):

View File

@ -77,7 +77,7 @@ class NotionBinarySensor(NotionEntity, BinarySensorEntity):
@callback @callback
def _async_update_from_latest_data(self) -> None: def _async_update_from_latest_data(self) -> None:
"""Fetch new state data for the sensor.""" """Fetch new state data for the sensor."""
task = self.coordinator.data["tasks"][self._task_id] task = self.coordinator.data["tasks"][self.task_id]
if "value" in task["status"]: if "value" in task["status"]:
self._state = task["status"]["value"] self._state = task["status"]["value"]
@ -87,7 +87,7 @@ class NotionBinarySensor(NotionEntity, BinarySensorEntity):
@property @property
def is_on(self) -> bool: def is_on(self) -> bool:
"""Return whether the sensor is on or off.""" """Return whether the sensor is on or off."""
task = self.coordinator.data["tasks"][self._task_id] task = self.coordinator.data["tasks"][self.task_id]
if task["task_type"] == SENSOR_BATTERY: if task["task_type"] == SENSOR_BATTERY:
return self._state == "critical" return self._state == "critical"

View File

@ -79,7 +79,7 @@ class NotionSensor(NotionEntity):
@callback @callback
def _async_update_from_latest_data(self) -> None: def _async_update_from_latest_data(self) -> None:
"""Fetch new state data for the sensor.""" """Fetch new state data for the sensor."""
task = self.coordinator.data["tasks"][self._task_id] task = self.coordinator.data["tasks"][self.task_id]
if task["task_type"] == SENSOR_TEMPERATURE: if task["task_type"] == SENSOR_TEMPERATURE:
self._state = round(float(task["status"]["value"]), 1) self._state = round(float(task["status"]["value"]), 1)

View File

@ -227,7 +227,7 @@ async def async_setup_entry(hass, entry):
play_on_sonos_schema = vol.Schema( play_on_sonos_schema = vol.Schema(
{ {
vol.Required(ATTR_ENTITY_ID): cv.entity_id, vol.Required(ATTR_ENTITY_ID): cv.entity_id,
vol.Required(ATTR_MEDIA_CONTENT_ID): str, vol.Required(ATTR_MEDIA_CONTENT_ID): cv.string,
vol.Optional(ATTR_MEDIA_CONTENT_TYPE): vol.In("music"), vol.Optional(ATTR_MEDIA_CONTENT_TYPE): vol.In("music"),
} }
) )

View File

@ -2,6 +2,6 @@
"domain": "sleepiq", "domain": "sleepiq",
"name": "SleepIQ", "name": "SleepIQ",
"documentation": "https://www.home-assistant.io/integrations/sleepiq", "documentation": "https://www.home-assistant.io/integrations/sleepiq",
"requirements": ["sleepyq==0.7"], "requirements": ["sleepyq==0.8.1"],
"codeowners": [] "codeowners": []
} }

View File

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

View File

@ -2033,7 +2033,7 @@ skybellpy==0.6.1
slackclient==2.5.0 slackclient==2.5.0
# homeassistant.components.sleepiq # homeassistant.components.sleepiq
sleepyq==0.7 sleepyq==0.8.1
# homeassistant.components.xmpp # homeassistant.components.xmpp
slixmpp==1.5.2 slixmpp==1.5.2

View File

@ -978,7 +978,7 @@ simplisafe-python==9.6.0
slackclient==2.5.0 slackclient==2.5.0
# homeassistant.components.sleepiq # homeassistant.components.sleepiq
sleepyq==0.7 sleepyq==0.8.1
# homeassistant.components.smart_meter_texas # homeassistant.components.smart_meter_texas
smart-meter-texas==0.4.0 smart-meter-texas==0.4.0

View File

@ -11,6 +11,7 @@ from homeassistant.components.kodi.const import DEFAULT_TIMEOUT, DOMAIN
from .util import ( from .util import (
TEST_CREDENTIALS, TEST_CREDENTIALS,
TEST_DISCOVERY, TEST_DISCOVERY,
TEST_DISCOVERY_WO_UUID,
TEST_HOST, TEST_HOST,
TEST_IMPORT, TEST_IMPORT,
TEST_WS_PORT, TEST_WS_PORT,
@ -573,6 +574,16 @@ async def test_discovery_updates_unique_id(hass):
assert entry.data["name"] == "hostname" assert entry.data["name"] == "hostname"
async def test_discovery_without_unique_id(hass):
"""Test a discovery flow with no unique id aborts."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "zeroconf"}, data=TEST_DISCOVERY_WO_UUID
)
assert result["type"] == "abort"
assert result["reason"] == "no_uuid"
async def test_form_import(hass): async def test_form_import(hass):
"""Test we get the form with import source.""" """Test we get the form with import source."""
with patch( with patch(

View File

@ -24,6 +24,16 @@ TEST_DISCOVERY = {
} }
TEST_DISCOVERY_WO_UUID = {
"host": "1.1.1.1",
"port": 8080,
"hostname": "hostname.local.",
"type": "_xbmc-jsonrpc-h._tcp.local.",
"name": "hostname._xbmc-jsonrpc-h._tcp.local.",
"properties": {},
}
TEST_IMPORT = { TEST_IMPORT = {
"name": "name", "name": "name",
"host": "1.1.1.1", "host": "1.1.1.1",