Merge pull request #51449 from home-assistant/rc

This commit is contained in:
Paulus Schoutsen 2021-06-03 17:09:29 -07:00 committed by GitHub
commit 1aa6266fb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 1323 additions and 39 deletions

View File

@ -217,21 +217,22 @@ class FritzDevice:
"""Update device info.""" """Update device info."""
utc_point_in_time = dt_util.utcnow() utc_point_in_time = dt_util.utcnow()
if not self._name: if self._last_activity:
self._name = dev_info.name or self._mac.replace(":", "_") consider_home_evaluated = (
if not dev_home and self._last_activity:
self._connected = (
utc_point_in_time - self._last_activity utc_point_in_time - self._last_activity
).total_seconds() < consider_home ).total_seconds() < consider_home
else: else:
self._connected = dev_home consider_home_evaluated = dev_home
if self._connected: if not self._name:
self._ip_address = dev_info.ip_address self._name = dev_info.name or self._mac.replace(":", "_")
self._connected = dev_home or consider_home_evaluated
if dev_home:
self._last_activity = utc_point_in_time self._last_activity = utc_point_in_time
else:
self._ip_address = None self._ip_address = dev_info.ip_address if self._connected else None
@property @property
def is_connected(self): def is_connected(self):

View File

@ -3,7 +3,7 @@
"name": "Home Assistant Frontend", "name": "Home Assistant Frontend",
"documentation": "https://www.home-assistant.io/integrations/frontend", "documentation": "https://www.home-assistant.io/integrations/frontend",
"requirements": [ "requirements": [
"home-assistant-frontend==20210601.1" "home-assistant-frontend==20210603.0"
], ],
"dependencies": [ "dependencies": [
"api", "api",

View File

@ -3,7 +3,7 @@
"name": "HomeKit Controller", "name": "HomeKit Controller",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/homekit_controller", "documentation": "https://www.home-assistant.io/integrations/homekit_controller",
"requirements": ["aiohomekit==0.2.66"], "requirements": ["aiohomekit==0.2.67"],
"zeroconf": ["_hap._tcp.local."], "zeroconf": ["_hap._tcp.local."],
"after_dependencies": ["zeroconf"], "after_dependencies": ["zeroconf"],
"codeowners": ["@Jc2k", "@bdraco"], "codeowners": ["@Jc2k", "@bdraco"],

View File

@ -34,7 +34,7 @@ incomplete_item:
text: text:
complete_all: complete_all:
name: Complete call name: Complete all
description: Marks all items as completed in the shopping list. It does not remove the items. description: Marks all items as completed in the shopping list. It does not remove the items.
incomplete_all: incomplete_all:

View File

@ -5,6 +5,7 @@ import datetime
import logging import logging
from pysonos.core import SoCo from pysonos.core import SoCo
from pysonos.exceptions import SoCoException
import homeassistant.helpers.device_registry as dr import homeassistant.helpers.device_registry as dr
from homeassistant.helpers.dispatcher import ( from homeassistant.helpers.dispatcher import (
@ -70,7 +71,10 @@ class SonosEntity(Entity):
self.speaker.subscription_address, self.speaker.subscription_address,
) )
self.speaker.is_first_poll = False self.speaker.is_first_poll = False
await self.async_update() # pylint: disable=no-member try:
await self.async_update() # pylint: disable=no-member
except (OSError, SoCoException) as ex:
_LOGGER.debug("Error connecting to %s: %s", self.entity_id, ex)
@property @property
def soco(self) -> SoCo: def soco(self) -> SoCo:

View File

@ -13,7 +13,7 @@ from pysonos.core import (
PLAY_MODE_BY_MEANING, PLAY_MODE_BY_MEANING,
PLAY_MODES, PLAY_MODES,
) )
from pysonos.exceptions import SoCoException, SoCoUPnPException from pysonos.exceptions import SoCoUPnPException
import voluptuous as vol import voluptuous as vol
from homeassistant.components.media_player import MediaPlayerEntity from homeassistant.components.media_player import MediaPlayerEntity
@ -293,18 +293,15 @@ class SonosMediaPlayerEntity(SonosEntity, MediaPlayerEntity):
return STATE_IDLE return STATE_IDLE
async def async_update(self) -> None: async def async_update(self) -> None:
"""Retrieve latest state.""" """Retrieve latest state by polling."""
await self.hass.async_add_executor_job(self._update) await self.hass.async_add_executor_job(self._update)
def _update(self) -> None: def _update(self) -> None:
"""Retrieve latest state.""" """Retrieve latest state by polling."""
try: self.speaker.update_groups()
self.speaker.update_groups() self.speaker.update_volume()
self.speaker.update_volume() if self.speaker.is_coordinator:
if self.speaker.is_coordinator: self.speaker.update_media()
self.speaker.update_media()
except SoCoException:
pass
@property @property
def volume_level(self) -> float | None: def volume_level(self) -> float | None:

View File

@ -186,6 +186,7 @@ class TibberSensor(SensorEntity):
"""Initialize the sensor.""" """Initialize the sensor."""
self._tibber_home = tibber_home self._tibber_home = tibber_home
self._home_name = tibber_home.info["viewer"]["home"]["appNickname"] self._home_name = tibber_home.info["viewer"]["home"]["appNickname"]
self._device_name = None
if self._home_name is None: if self._home_name is None:
self._home_name = tibber_home.info["viewer"]["home"]["address"].get( self._home_name = tibber_home.info["viewer"]["home"]["address"].get(
"address1", "" "address1", ""
@ -202,7 +203,7 @@ class TibberSensor(SensorEntity):
"""Return the device_info of the device.""" """Return the device_info of the device."""
device_info = { device_info = {
"identifiers": {(TIBBER_DOMAIN, self.device_id)}, "identifiers": {(TIBBER_DOMAIN, self.device_id)},
"name": self.name, "name": self._device_name,
"manufacturer": MANUFACTURER, "manufacturer": MANUFACTURER,
} }
if self._model is not None: if self._model is not None:
@ -237,6 +238,8 @@ class TibberSensorElPrice(TibberSensor):
self._attr_unique_id = f"{self._tibber_home.home_id}" self._attr_unique_id = f"{self._tibber_home.home_id}"
self._model = "Price Sensor" self._model = "Price Sensor"
self._device_name = self._attr_name
async def async_update(self): async def async_update(self):
"""Get the latest data and updates the states.""" """Get the latest data and updates the states."""
now = dt_util.now() now = dt_util.now()
@ -295,6 +298,7 @@ class TibberSensorRT(TibberSensor):
super().__init__(tibber_home) super().__init__(tibber_home)
self._sensor_name = sensor_name self._sensor_name = sensor_name
self._model = "Tibber Pulse" self._model = "Tibber Pulse"
self._device_name = f"{self._model} {self._home_name}"
self._attr_device_class = device_class self._attr_device_class = device_class
self._attr_name = f"{self._sensor_name} {self._home_name}" self._attr_name = f"{self._sensor_name} {self._home_name}"
@ -330,7 +334,7 @@ class TibberSensorRT(TibberSensor):
self.async_on_remove( self.async_on_remove(
async_dispatcher_connect( async_dispatcher_connect(
self.hass, self.hass,
SIGNAL_UPDATE_ENTITY.format(self._sensor_name), SIGNAL_UPDATE_ENTITY.format(self.unique_id),
self._set_state, self._set_state,
) )
) )
@ -370,7 +374,7 @@ class TibberRtDataHandler:
self._async_add_entities = async_add_entities self._async_add_entities = async_add_entities
self._tibber_home = tibber_home self._tibber_home = tibber_home
self.hass = hass self.hass = hass
self._entities = set() self._entities = {}
async def async_callback(self, payload): async def async_callback(self, payload):
"""Handle received data.""" """Handle received data."""
@ -393,7 +397,7 @@ class TibberRtDataHandler:
if sensor_type in self._entities: if sensor_type in self._entities:
async_dispatcher_send( async_dispatcher_send(
self.hass, self.hass,
SIGNAL_UPDATE_ENTITY.format(RT_SENSOR_MAP[sensor_type][0]), SIGNAL_UPDATE_ENTITY.format(self._entities[sensor_type]),
state, state,
timestamp, timestamp,
) )
@ -412,6 +416,6 @@ class TibberRtDataHandler:
state_class, state_class,
) )
new_entities.append(entity) new_entities.append(entity)
self._entities.add(sensor_type) self._entities[sensor_type] = entity.unique_id
if new_entities: if new_entities:
self._async_add_entities(new_entities) self._async_add_entities(new_entities)

View File

@ -100,7 +100,7 @@ class DynamicCurrentTempClimateDataTemplate(BaseDiscoverySchemaDataTemplate):
lookup_table: dict[str | int, ZwaveValue | None] = resolved_data["lookup_table"] lookup_table: dict[str | int, ZwaveValue | None] = resolved_data["lookup_table"]
dependent_value: ZwaveValue | None = resolved_data["dependent_value"] dependent_value: ZwaveValue | None = resolved_data["dependent_value"]
if dependent_value: if dependent_value and dependent_value.value is not None:
lookup_key = dependent_value.metadata.states[ lookup_key = dependent_value.metadata.states[
str(dependent_value.value) str(dependent_value.value)
].split("-")[0] ].split("-")[0]

View File

@ -3,7 +3,7 @@
"name": "Z-Wave JS", "name": "Z-Wave JS",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/zwave_js", "documentation": "https://www.home-assistant.io/integrations/zwave_js",
"requirements": ["zwave-js-server-python==0.26.0"], "requirements": ["zwave-js-server-python==0.26.1"],
"codeowners": ["@home-assistant/z-wave"], "codeowners": ["@home-assistant/z-wave"],
"dependencies": ["http", "websocket_api"], "dependencies": ["http", "websocket_api"],
"iot_class": "local_push" "iot_class": "local_push"

View File

@ -5,7 +5,7 @@ from typing import Final
MAJOR_VERSION: Final = 2021 MAJOR_VERSION: Final = 2021
MINOR_VERSION: Final = 6 MINOR_VERSION: Final = 6
PATCH_VERSION: Final = "0" PATCH_VERSION: Final = "1"
__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, 8, 0) REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 8, 0)

View File

@ -17,7 +17,7 @@ defusedxml==0.7.1
distro==1.5.0 distro==1.5.0
emoji==1.2.0 emoji==1.2.0
hass-nabucasa==0.43.0 hass-nabucasa==0.43.0
home-assistant-frontend==20210601.1 home-assistant-frontend==20210603.0
httpx==0.18.0 httpx==0.18.0
ifaddr==0.1.7 ifaddr==0.1.7
jinja2>=3.0.1 jinja2>=3.0.1

View File

@ -175,7 +175,7 @@ aioguardian==1.0.4
aioharmony==0.2.7 aioharmony==0.2.7
# homeassistant.components.homekit_controller # homeassistant.components.homekit_controller
aiohomekit==0.2.66 aiohomekit==0.2.67
# homeassistant.components.emulated_hue # homeassistant.components.emulated_hue
# homeassistant.components.http # homeassistant.components.http
@ -765,7 +765,7 @@ hole==0.5.1
holidays==0.11.1 holidays==0.11.1
# homeassistant.components.frontend # homeassistant.components.frontend
home-assistant-frontend==20210601.1 home-assistant-frontend==20210603.0
# homeassistant.components.zwave # homeassistant.components.zwave
homeassistant-pyozw==0.1.10 homeassistant-pyozw==0.1.10
@ -2442,4 +2442,4 @@ zigpy==0.33.0
zm-py==0.5.2 zm-py==0.5.2
# homeassistant.components.zwave_js # homeassistant.components.zwave_js
zwave-js-server-python==0.26.0 zwave-js-server-python==0.26.1

View File

@ -112,7 +112,7 @@ aioguardian==1.0.4
aioharmony==0.2.7 aioharmony==0.2.7
# homeassistant.components.homekit_controller # homeassistant.components.homekit_controller
aiohomekit==0.2.66 aiohomekit==0.2.67
# homeassistant.components.emulated_hue # homeassistant.components.emulated_hue
# homeassistant.components.http # homeassistant.components.http
@ -429,7 +429,7 @@ hole==0.5.1
holidays==0.11.1 holidays==0.11.1
# homeassistant.components.frontend # homeassistant.components.frontend
home-assistant-frontend==20210601.1 home-assistant-frontend==20210603.0
# homeassistant.components.zwave # homeassistant.components.zwave
homeassistant-pyozw==0.1.10 homeassistant-pyozw==0.1.10
@ -1324,4 +1324,4 @@ zigpy-znp==0.5.1
zigpy==0.33.0 zigpy==0.33.0
# homeassistant.components.zwave_js # homeassistant.components.zwave_js
zwave-js-server-python==0.26.0 zwave-js-server-python==0.26.1

View File

@ -261,6 +261,14 @@ def climate_heatit_z_trm2fx_state_fixture():
return json.loads(load_fixture("zwave_js/climate_heatit_z_trm2fx_state.json")) return json.loads(load_fixture("zwave_js/climate_heatit_z_trm2fx_state.json"))
@pytest.fixture(name="climate_heatit_z_trm3_no_value_state", scope="session")
def climate_heatit_z_trm3_no_value_state_fixture():
"""Load the climate HEATIT Z-TRM3 thermostat node w/no value state fixture data."""
return json.loads(
load_fixture("zwave_js/climate_heatit_z_trm3_no_value_state.json")
)
@pytest.fixture(name="nortek_thermostat_state", scope="session") @pytest.fixture(name="nortek_thermostat_state", scope="session")
def nortek_thermostat_state_fixture(): def nortek_thermostat_state_fixture():
"""Load the nortek thermostat node state fixture data.""" """Load the nortek thermostat node state fixture data."""
@ -517,6 +525,16 @@ def climate_eurotronic_spirit_z_fixture(client, climate_eurotronic_spirit_z_stat
return node return node
@pytest.fixture(name="climate_heatit_z_trm3_no_value")
def climate_heatit_z_trm3_no_value_fixture(
client, climate_heatit_z_trm3_no_value_state
):
"""Mock a climate radio HEATIT Z-TRM3 node."""
node = Node(client, copy.deepcopy(climate_heatit_z_trm3_no_value_state))
client.driver.controller.nodes[node.node_id] = node
return node
@pytest.fixture(name="climate_heatit_z_trm3") @pytest.fixture(name="climate_heatit_z_trm3")
def climate_heatit_z_trm3_fixture(client, climate_heatit_z_trm3_state): def climate_heatit_z_trm3_fixture(client, climate_heatit_z_trm3_state):
"""Mock a climate radio HEATIT Z-TRM3 node.""" """Mock a climate radio HEATIT Z-TRM3 node."""

View File

@ -437,6 +437,16 @@ async def test_setpoint_thermostat(hass, client, climate_danfoss_lc_13, integrat
client.async_send_command_no_wait.reset_mock() client.async_send_command_no_wait.reset_mock()
async def test_thermostat_heatit_z_trm3_no_value(
hass, client, climate_heatit_z_trm3_no_value, integration
):
"""Test a heatit Z-TRM3 entity that is missing a value."""
# When the config parameter that specifies what sensor to use has no value, we fall
# back to the first temperature sensor found on the device
state = hass.states.get(CLIMATE_FLOOR_THERMOSTAT_ENTITY)
assert state.attributes[ATTR_CURRENT_TEMPERATURE] == 22.5
async def test_thermostat_heatit_z_trm3( async def test_thermostat_heatit_z_trm3(
hass, client, climate_heatit_z_trm3, integration hass, client, climate_heatit_z_trm3, integration
): ):

File diff suppressed because it is too large Load Diff