mirror of
https://github.com/home-assistant/core.git
synced 2025-07-30 08:47:09 +00:00
Merge pull request #51449 from home-assistant/rc
This commit is contained in:
commit
1aa6266fb4
@ -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):
|
||||||
|
@ -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",
|
||||||
|
@ -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"],
|
||||||
|
@ -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:
|
||||||
|
@ -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:
|
||||||
|
@ -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:
|
||||||
|
@ -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)
|
||||||
|
@ -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]
|
||||||
|
@ -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"
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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."""
|
||||||
|
@ -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
|
||||||
):
|
):
|
||||||
|
1250
tests/fixtures/zwave_js/climate_heatit_z_trm3_no_value_state.json
vendored
Normal file
1250
tests/fixtures/zwave_js/climate_heatit_z_trm3_no_value_state.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user