mirror of
https://github.com/home-assistant/core.git
synced 2025-07-26 06:37:52 +00:00
Merge pull request #57793 from home-assistant/rc
This commit is contained in:
commit
eb30fb1f3b
@ -404,8 +404,8 @@ class DlnaDmrEntity(MediaPlayerEntity):
|
|||||||
try:
|
try:
|
||||||
do_ping = self.poll_availability or self.check_available
|
do_ping = self.poll_availability or self.check_available
|
||||||
await self._device.async_update(do_ping=do_ping)
|
await self._device.async_update(do_ping=do_ping)
|
||||||
except UpnpError:
|
except UpnpError as err:
|
||||||
_LOGGER.debug("Device unavailable")
|
_LOGGER.debug("Device unavailable: %r", err)
|
||||||
await self._device_disconnect()
|
await self._device_disconnect()
|
||||||
return
|
return
|
||||||
finally:
|
finally:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Support for testing internet speed via Fast.com."""
|
"""Support for testing internet speed via Fast.com."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from datetime import timedelta
|
from datetime import datetime, timedelta
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ class SpeedtestData:
|
|||||||
self.data: dict[str, Any] | None = None
|
self.data: dict[str, Any] | None = None
|
||||||
self._hass = hass
|
self._hass = hass
|
||||||
|
|
||||||
def update(self) -> None:
|
def update(self, now: datetime | None = None) -> None:
|
||||||
"""Get the latest data from fast.com."""
|
"""Get the latest data from fast.com."""
|
||||||
|
|
||||||
_LOGGER.debug("Executing fast.com speedtest")
|
_LOGGER.debug("Executing fast.com speedtest")
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"domain": "mill",
|
"domain": "mill",
|
||||||
"name": "Mill",
|
"name": "Mill",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/mill",
|
"documentation": "https://www.home-assistant.io/integrations/mill",
|
||||||
"requirements": ["millheater==0.6.1"],
|
"requirements": ["millheater==0.6.2"],
|
||||||
"codeowners": ["@danielhiversen"],
|
"codeowners": ["@danielhiversen"],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"iot_class": "cloud_polling"
|
"iot_class": "cloud_polling"
|
||||||
|
@ -151,7 +151,7 @@ class NotionEntity(CoordinatorEntity):
|
|||||||
"identifiers": {(DOMAIN, sensor["hardware_id"])},
|
"identifiers": {(DOMAIN, sensor["hardware_id"])},
|
||||||
"manufacturer": "Silicon Labs",
|
"manufacturer": "Silicon Labs",
|
||||||
"model": sensor["hardware_revision"],
|
"model": sensor["hardware_revision"],
|
||||||
"name": sensor["name"],
|
"name": str(sensor["name"]),
|
||||||
"sw_version": sensor["firmware_version"],
|
"sw_version": sensor["firmware_version"],
|
||||||
"via_device": (DOMAIN, bridge.get("hardware_id")),
|
"via_device": (DOMAIN, bridge.get("hardware_id")),
|
||||||
}
|
}
|
||||||
|
@ -311,7 +311,9 @@ def setup_connection_for_dialect(
|
|||||||
result = query_on_connection(dbapi_connection, "SELECT VERSION()")
|
result = query_on_connection(dbapi_connection, "SELECT VERSION()")
|
||||||
version = result[0][0]
|
version = result[0][0]
|
||||||
major, minor, _patch = version.split(".", 2)
|
major, minor, _patch = version.split(".", 2)
|
||||||
if int(major) == 5 and int(minor) < 8:
|
if (int(major) == 5 and int(minor) < 8) or (
|
||||||
|
int(major) == 10 and int(minor) < 2
|
||||||
|
):
|
||||||
instance._db_supports_row_number = ( # pylint: disable=[protected-access]
|
instance._db_supports_row_number = ( # pylint: disable=[protected-access]
|
||||||
False
|
False
|
||||||
)
|
)
|
||||||
|
@ -182,7 +182,7 @@ SENSORS: Final = {
|
|||||||
value=lambda value: round(value, 1),
|
value=lambda value: round(value, 1),
|
||||||
device_class=sensor.DEVICE_CLASS_HUMIDITY,
|
device_class=sensor.DEVICE_CLASS_HUMIDITY,
|
||||||
state_class=sensor.STATE_CLASS_MEASUREMENT,
|
state_class=sensor.STATE_CLASS_MEASUREMENT,
|
||||||
available=lambda block: cast(int, block.extTemp) != 999,
|
available=lambda block: cast(int, block.humidity) != 999,
|
||||||
),
|
),
|
||||||
("sensor", "luminosity"): BlockAttributeDescription(
|
("sensor", "luminosity"): BlockAttributeDescription(
|
||||||
name="Luminosity",
|
name="Luminosity",
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "SimpliSafe",
|
"name": "SimpliSafe",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/simplisafe",
|
"documentation": "https://www.home-assistant.io/integrations/simplisafe",
|
||||||
"requirements": ["simplisafe-python==11.0.6"],
|
"requirements": ["simplisafe-python==11.0.7"],
|
||||||
"codeowners": ["@bachya"],
|
"codeowners": ["@bachya"],
|
||||||
"iot_class": "cloud_polling"
|
"iot_class": "cloud_polling"
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"domain": "spider",
|
"domain": "spider",
|
||||||
"name": "Itho Daalderop Spider",
|
"name": "Itho Daalderop Spider",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/spider",
|
"documentation": "https://www.home-assistant.io/integrations/spider",
|
||||||
"requirements": ["spiderpy==1.4.2"],
|
"requirements": ["spiderpy==1.4.3"],
|
||||||
"codeowners": ["@peternijssen"],
|
"codeowners": ["@peternijssen"],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"iot_class": "cloud_polling"
|
"iot_class": "cloud_polling"
|
||||||
|
@ -264,5 +264,5 @@ class UpnpEntity(CoordinatorEntity):
|
|||||||
def available(self) -> bool:
|
def available(self) -> bool:
|
||||||
"""Return if entity is available."""
|
"""Return if entity is available."""
|
||||||
return super().available and (
|
return super().available and (
|
||||||
self.coordinator.data.get(self.entity_description.key) or False
|
self.coordinator.data.get(self.entity_description.key) is not None
|
||||||
)
|
)
|
||||||
|
@ -190,7 +190,10 @@ class DerivedUpnpSensor(UpnpSensor):
|
|||||||
|
|
||||||
# Calculate derivative.
|
# Calculate derivative.
|
||||||
delta_value = current_value - self._last_value
|
delta_value = current_value - self._last_value
|
||||||
if self.entity_description.native_unit_of_measurement == DATA_BYTES:
|
if (
|
||||||
|
self.entity_description.native_unit_of_measurement
|
||||||
|
== DATA_RATE_KIBIBYTES_PER_SECOND
|
||||||
|
):
|
||||||
delta_value /= KIBIBYTE
|
delta_value /= KIBIBYTE
|
||||||
delta_time = current_timestamp - self._last_timestamp
|
delta_time = current_timestamp - self._last_timestamp
|
||||||
if delta_time.total_seconds() == 0:
|
if delta_time.total_seconds() == 0:
|
||||||
|
@ -6,7 +6,6 @@ import contextlib
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from ipaddress import IPv4Address, IPv6Address
|
from ipaddress import IPv4Address, IPv6Address
|
||||||
import logging
|
import logging
|
||||||
import socket
|
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
from async_upnp_client.search import SsdpSearchListener
|
from async_upnp_client.search import SsdpSearchListener
|
||||||
@ -163,9 +162,6 @@ UPDATE_REQUEST_PROPERTIES = [
|
|||||||
"active_mode",
|
"active_mode",
|
||||||
]
|
]
|
||||||
|
|
||||||
BULB_NETWORK_EXCEPTIONS = (socket.error,)
|
|
||||||
BULB_EXCEPTIONS = (BulbException, asyncio.TimeoutError, *BULB_NETWORK_EXCEPTIONS)
|
|
||||||
|
|
||||||
|
|
||||||
PLATFORMS = ["binary_sensor", "light"]
|
PLATFORMS = ["binary_sensor", "light"]
|
||||||
|
|
||||||
@ -270,7 +266,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
try:
|
try:
|
||||||
device = await _async_get_device(hass, entry.data[CONF_HOST], entry)
|
device = await _async_get_device(hass, entry.data[CONF_HOST], entry)
|
||||||
await _async_initialize(hass, entry, device)
|
await _async_initialize(hass, entry, device)
|
||||||
except BULB_EXCEPTIONS as ex:
|
except (asyncio.TimeoutError, OSError, BulbException) as ex:
|
||||||
raise ConfigEntryNotReady from ex
|
raise ConfigEntryNotReady from ex
|
||||||
|
|
||||||
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
|
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
|
||||||
@ -594,13 +590,20 @@ class YeelightDevice:
|
|||||||
self._available = True
|
self._available = True
|
||||||
if not self._initialized:
|
if not self._initialized:
|
||||||
self._initialized = True
|
self._initialized = True
|
||||||
except BULB_NETWORK_EXCEPTIONS as ex:
|
except OSError as ex:
|
||||||
if self._available: # just inform once
|
if self._available: # just inform once
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
"Unable to update device %s, %s: %s", self._host, self.name, ex
|
"Unable to update device %s, %s: %s", self._host, self.name, ex
|
||||||
)
|
)
|
||||||
self._available = False
|
self._available = False
|
||||||
except BULB_EXCEPTIONS as ex:
|
except asyncio.TimeoutError as ex:
|
||||||
|
_LOGGER.debug(
|
||||||
|
"timed out while trying to update device %s, %s: %s",
|
||||||
|
self._host,
|
||||||
|
self.name,
|
||||||
|
ex,
|
||||||
|
)
|
||||||
|
except BulbException as ex:
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Unable to update device %s, %s: %s", self._host, self.name, ex
|
"Unable to update device %s, %s: %s", self._host, self.name, ex
|
||||||
)
|
)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""Light platform support for yeelight."""
|
"""Light platform support for yeelight."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
import math
|
import math
|
||||||
|
|
||||||
@ -8,6 +9,7 @@ import voluptuous as vol
|
|||||||
import yeelight
|
import yeelight
|
||||||
from yeelight import Bulb, Flow, RGBTransition, SleepTransition, flows
|
from yeelight import Bulb, Flow, RGBTransition, SleepTransition, flows
|
||||||
from yeelight.enums import BulbType, LightType, PowerMode, SceneClass
|
from yeelight.enums import BulbType, LightType, PowerMode, SceneClass
|
||||||
|
from yeelight.main import BulbException
|
||||||
|
|
||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
ATTR_BRIGHTNESS,
|
ATTR_BRIGHTNESS,
|
||||||
@ -51,8 +53,6 @@ from . import (
|
|||||||
ATTR_COUNT,
|
ATTR_COUNT,
|
||||||
ATTR_MODE_MUSIC,
|
ATTR_MODE_MUSIC,
|
||||||
ATTR_TRANSITIONS,
|
ATTR_TRANSITIONS,
|
||||||
BULB_EXCEPTIONS,
|
|
||||||
BULB_NETWORK_EXCEPTIONS,
|
|
||||||
CONF_FLOW_PARAMS,
|
CONF_FLOW_PARAMS,
|
||||||
CONF_MODE_MUSIC,
|
CONF_MODE_MUSIC,
|
||||||
CONF_NIGHTLIGHT_SWITCH,
|
CONF_NIGHTLIGHT_SWITCH,
|
||||||
@ -243,23 +243,33 @@ def _async_cmd(func):
|
|||||||
"""Define a wrapper to catch exceptions from the bulb."""
|
"""Define a wrapper to catch exceptions from the bulb."""
|
||||||
|
|
||||||
async def _async_wrap(self, *args, **kwargs):
|
async def _async_wrap(self, *args, **kwargs):
|
||||||
try:
|
for attempts in range(2):
|
||||||
_LOGGER.debug("Calling %s with %s %s", func, args, kwargs)
|
try:
|
||||||
return await func(self, *args, **kwargs)
|
_LOGGER.debug("Calling %s with %s %s", func, args, kwargs)
|
||||||
except BULB_NETWORK_EXCEPTIONS as ex:
|
return await func(self, *args, **kwargs)
|
||||||
# A network error happened, the bulb is likely offline now
|
except asyncio.TimeoutError as ex:
|
||||||
self.device.async_mark_unavailable()
|
# The wifi likely dropped, so we want to retry once since
|
||||||
self.async_state_changed()
|
# python-yeelight will auto reconnect
|
||||||
exc_message = str(ex) or type(ex)
|
exc_message = str(ex) or type(ex)
|
||||||
raise HomeAssistantError(
|
if attempts == 0:
|
||||||
f"Error when calling {func.__name__} for bulb {self.device.name} at {self.device.host}: {exc_message}"
|
continue
|
||||||
) from ex
|
raise HomeAssistantError(
|
||||||
except BULB_EXCEPTIONS as ex:
|
f"Timed out when calling {func.__name__} for bulb {self.device.name} at {self.device.host}: {exc_message}"
|
||||||
# The bulb likely responded but had an error
|
) from ex
|
||||||
exc_message = str(ex) or type(ex)
|
except OSError as ex:
|
||||||
raise HomeAssistantError(
|
# A network error happened, the bulb is likely offline now
|
||||||
f"Error when calling {func.__name__} for bulb {self.device.name} at {self.device.host}: {exc_message}"
|
self.device.async_mark_unavailable()
|
||||||
) from ex
|
self.async_state_changed()
|
||||||
|
exc_message = str(ex) or type(ex)
|
||||||
|
raise HomeAssistantError(
|
||||||
|
f"Error when calling {func.__name__} for bulb {self.device.name} at {self.device.host}: {exc_message}"
|
||||||
|
) from ex
|
||||||
|
except BulbException as ex:
|
||||||
|
# The bulb likely responded but had an error
|
||||||
|
exc_message = str(ex) or type(ex)
|
||||||
|
raise HomeAssistantError(
|
||||||
|
f"Error when calling {func.__name__} for bulb {self.device.name} at {self.device.host}: {exc_message}"
|
||||||
|
) from ex
|
||||||
|
|
||||||
return _async_wrap
|
return _async_wrap
|
||||||
|
|
||||||
@ -621,7 +631,11 @@ class YeelightGenericLight(YeelightEntity, LightEntity):
|
|||||||
"""Set bulb's color."""
|
"""Set bulb's color."""
|
||||||
if not hs_color or COLOR_MODE_HS not in self.supported_color_modes:
|
if not hs_color or COLOR_MODE_HS not in self.supported_color_modes:
|
||||||
return
|
return
|
||||||
if self.color_mode == COLOR_MODE_HS and self.hs_color == hs_color:
|
if (
|
||||||
|
not self.device.is_color_flow_enabled
|
||||||
|
and self.color_mode == COLOR_MODE_HS
|
||||||
|
and self.hs_color == hs_color
|
||||||
|
):
|
||||||
_LOGGER.debug("HS already set to: %s", hs_color)
|
_LOGGER.debug("HS already set to: %s", hs_color)
|
||||||
# Already set, and since we get pushed updates
|
# Already set, and since we get pushed updates
|
||||||
# we avoid setting it again to ensure we do not
|
# we avoid setting it again to ensure we do not
|
||||||
@ -638,7 +652,11 @@ class YeelightGenericLight(YeelightEntity, LightEntity):
|
|||||||
"""Set bulb's color."""
|
"""Set bulb's color."""
|
||||||
if not rgb or COLOR_MODE_RGB not in self.supported_color_modes:
|
if not rgb or COLOR_MODE_RGB not in self.supported_color_modes:
|
||||||
return
|
return
|
||||||
if self.color_mode == COLOR_MODE_RGB and self.rgb_color == rgb:
|
if (
|
||||||
|
not self.device.is_color_flow_enabled
|
||||||
|
and self.color_mode == COLOR_MODE_RGB
|
||||||
|
and self.rgb_color == rgb
|
||||||
|
):
|
||||||
_LOGGER.debug("RGB already set to: %s", rgb)
|
_LOGGER.debug("RGB already set to: %s", rgb)
|
||||||
# Already set, and since we get pushed updates
|
# Already set, and since we get pushed updates
|
||||||
# we avoid setting it again to ensure we do not
|
# we avoid setting it again to ensure we do not
|
||||||
@ -657,7 +675,11 @@ class YeelightGenericLight(YeelightEntity, LightEntity):
|
|||||||
return
|
return
|
||||||
temp_in_k = mired_to_kelvin(colortemp)
|
temp_in_k = mired_to_kelvin(colortemp)
|
||||||
|
|
||||||
if self.color_mode == COLOR_MODE_COLOR_TEMP and self.color_temp == colortemp:
|
if (
|
||||||
|
not self.device.is_color_flow_enabled
|
||||||
|
and self.color_mode == COLOR_MODE_COLOR_TEMP
|
||||||
|
and self.color_temp == colortemp
|
||||||
|
):
|
||||||
_LOGGER.debug("Color temp already set to: %s", temp_in_k)
|
_LOGGER.debug("Color temp already set to: %s", temp_in_k)
|
||||||
# Already set, and since we get pushed updates
|
# Already set, and since we get pushed updates
|
||||||
# we avoid setting it again to ensure we do not
|
# we avoid setting it again to ensure we do not
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"domain": "yeelight",
|
"domain": "yeelight",
|
||||||
"name": "Yeelight",
|
"name": "Yeelight",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/yeelight",
|
"documentation": "https://www.home-assistant.io/integrations/yeelight",
|
||||||
"requirements": ["yeelight==0.7.7", "async-upnp-client==0.22.8"],
|
"requirements": ["yeelight==0.7.8", "async-upnp-client==0.22.8"],
|
||||||
"codeowners": ["@rytilahti", "@zewelor", "@shenxn", "@starkillerOG"],
|
"codeowners": ["@rytilahti", "@zewelor", "@shenxn", "@starkillerOG"],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"dependencies": ["network"],
|
"dependencies": ["network"],
|
||||||
|
@ -5,6 +5,7 @@ from youless_api.youless_sensor import YoulessSensor
|
|||||||
|
|
||||||
from homeassistant.components.sensor import (
|
from homeassistant.components.sensor import (
|
||||||
STATE_CLASS_MEASUREMENT,
|
STATE_CLASS_MEASUREMENT,
|
||||||
|
STATE_CLASS_TOTAL,
|
||||||
STATE_CLASS_TOTAL_INCREASING,
|
STATE_CLASS_TOTAL_INCREASING,
|
||||||
SensorEntity,
|
SensorEntity,
|
||||||
)
|
)
|
||||||
@ -40,9 +41,9 @@ async def async_setup_entry(
|
|||||||
async_add_entities(
|
async_add_entities(
|
||||||
[
|
[
|
||||||
GasSensor(coordinator, device),
|
GasSensor(coordinator, device),
|
||||||
PowerMeterSensor(coordinator, device, "low"),
|
PowerMeterSensor(coordinator, device, "low", STATE_CLASS_TOTAL_INCREASING),
|
||||||
PowerMeterSensor(coordinator, device, "high"),
|
PowerMeterSensor(coordinator, device, "high", STATE_CLASS_TOTAL_INCREASING),
|
||||||
PowerMeterSensor(coordinator, device, "total"),
|
PowerMeterSensor(coordinator, device, "total", STATE_CLASS_TOTAL),
|
||||||
CurrentPowerSensor(coordinator, device),
|
CurrentPowerSensor(coordinator, device),
|
||||||
DeliveryMeterSensor(coordinator, device, "low"),
|
DeliveryMeterSensor(coordinator, device, "low"),
|
||||||
DeliveryMeterSensor(coordinator, device, "high"),
|
DeliveryMeterSensor(coordinator, device, "high"),
|
||||||
@ -168,7 +169,11 @@ class PowerMeterSensor(YoulessBaseSensor):
|
|||||||
_attr_state_class = STATE_CLASS_TOTAL_INCREASING
|
_attr_state_class = STATE_CLASS_TOTAL_INCREASING
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, coordinator: DataUpdateCoordinator, device: str, dev_type: str
|
self,
|
||||||
|
coordinator: DataUpdateCoordinator,
|
||||||
|
device: str,
|
||||||
|
dev_type: str,
|
||||||
|
state_class: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Instantiate a power meter sensor."""
|
"""Instantiate a power meter sensor."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
@ -177,6 +182,7 @@ class PowerMeterSensor(YoulessBaseSensor):
|
|||||||
self._device = device
|
self._device = device
|
||||||
self._type = dev_type
|
self._type = dev_type
|
||||||
self._attr_name = f"Power {dev_type}"
|
self._attr_name = f"Power {dev_type}"
|
||||||
|
self._attr_state_class = state_class
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def get_sensor(self) -> YoulessSensor | None:
|
def get_sensor(self) -> YoulessSensor | None:
|
||||||
|
@ -5,7 +5,7 @@ from typing import Final
|
|||||||
|
|
||||||
MAJOR_VERSION: Final = 2021
|
MAJOR_VERSION: Final = 2021
|
||||||
MINOR_VERSION: Final = 10
|
MINOR_VERSION: Final = 10
|
||||||
PATCH_VERSION: Final = "4"
|
PATCH_VERSION: Final = "5"
|
||||||
__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)
|
||||||
|
@ -1005,7 +1005,7 @@ micloud==0.3
|
|||||||
miflora==0.7.0
|
miflora==0.7.0
|
||||||
|
|
||||||
# homeassistant.components.mill
|
# homeassistant.components.mill
|
||||||
millheater==0.6.1
|
millheater==0.6.2
|
||||||
|
|
||||||
# homeassistant.components.minio
|
# homeassistant.components.minio
|
||||||
minio==4.0.9
|
minio==4.0.9
|
||||||
@ -2149,7 +2149,7 @@ simplehound==0.3
|
|||||||
simplepush==1.1.4
|
simplepush==1.1.4
|
||||||
|
|
||||||
# homeassistant.components.simplisafe
|
# homeassistant.components.simplisafe
|
||||||
simplisafe-python==11.0.6
|
simplisafe-python==11.0.7
|
||||||
|
|
||||||
# homeassistant.components.sisyphus
|
# homeassistant.components.sisyphus
|
||||||
sisyphus-control==3.0
|
sisyphus-control==3.0
|
||||||
@ -2214,7 +2214,7 @@ speak2mary==1.4.0
|
|||||||
speedtest-cli==2.1.3
|
speedtest-cli==2.1.3
|
||||||
|
|
||||||
# homeassistant.components.spider
|
# homeassistant.components.spider
|
||||||
spiderpy==1.4.2
|
spiderpy==1.4.3
|
||||||
|
|
||||||
# homeassistant.components.spotify
|
# homeassistant.components.spotify
|
||||||
spotipy==2.18.0
|
spotipy==2.18.0
|
||||||
@ -2459,7 +2459,7 @@ yalesmartalarmclient==0.3.4
|
|||||||
yalexs==1.1.13
|
yalexs==1.1.13
|
||||||
|
|
||||||
# homeassistant.components.yeelight
|
# homeassistant.components.yeelight
|
||||||
yeelight==0.7.7
|
yeelight==0.7.8
|
||||||
|
|
||||||
# homeassistant.components.yeelightsunflower
|
# homeassistant.components.yeelightsunflower
|
||||||
yeelightsunflower==0.0.10
|
yeelightsunflower==0.0.10
|
||||||
|
@ -585,7 +585,7 @@ mficlient==0.3.0
|
|||||||
micloud==0.3
|
micloud==0.3
|
||||||
|
|
||||||
# homeassistant.components.mill
|
# homeassistant.components.mill
|
||||||
millheater==0.6.1
|
millheater==0.6.2
|
||||||
|
|
||||||
# homeassistant.components.minio
|
# homeassistant.components.minio
|
||||||
minio==4.0.9
|
minio==4.0.9
|
||||||
@ -1224,7 +1224,7 @@ sharkiqpy==0.1.8
|
|||||||
simplehound==0.3
|
simplehound==0.3
|
||||||
|
|
||||||
# homeassistant.components.simplisafe
|
# homeassistant.components.simplisafe
|
||||||
simplisafe-python==11.0.6
|
simplisafe-python==11.0.7
|
||||||
|
|
||||||
# homeassistant.components.slack
|
# homeassistant.components.slack
|
||||||
slackclient==2.5.0
|
slackclient==2.5.0
|
||||||
@ -1263,7 +1263,7 @@ speak2mary==1.4.0
|
|||||||
speedtest-cli==2.1.3
|
speedtest-cli==2.1.3
|
||||||
|
|
||||||
# homeassistant.components.spider
|
# homeassistant.components.spider
|
||||||
spiderpy==1.4.2
|
spiderpy==1.4.3
|
||||||
|
|
||||||
# homeassistant.components.spotify
|
# homeassistant.components.spotify
|
||||||
spotipy==2.18.0
|
spotipy==2.18.0
|
||||||
@ -1403,7 +1403,7 @@ yalesmartalarmclient==0.3.4
|
|||||||
yalexs==1.1.13
|
yalexs==1.1.13
|
||||||
|
|
||||||
# homeassistant.components.yeelight
|
# homeassistant.components.yeelight
|
||||||
yeelight==0.7.7
|
yeelight==0.7.8
|
||||||
|
|
||||||
# homeassistant.components.youless
|
# homeassistant.components.youless
|
||||||
youless-api==0.14
|
youless-api==0.14
|
||||||
|
@ -125,7 +125,8 @@ async def test_last_run_was_recently_clean(hass):
|
|||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"mysql_version, db_supports_row_number",
|
"mysql_version, db_supports_row_number",
|
||||||
[
|
[
|
||||||
("10.0.0", True),
|
("10.2.0", True),
|
||||||
|
("10.1.0", False),
|
||||||
("5.8.0", True),
|
("5.8.0", True),
|
||||||
("5.7.0", False),
|
("5.7.0", False),
|
||||||
],
|
],
|
||||||
|
@ -9,6 +9,9 @@ from homeassistant.components import ssdp
|
|||||||
from homeassistant.components.upnp.const import (
|
from homeassistant.components.upnp.const import (
|
||||||
BYTES_RECEIVED,
|
BYTES_RECEIVED,
|
||||||
BYTES_SENT,
|
BYTES_SENT,
|
||||||
|
CONFIG_ENTRY_ST,
|
||||||
|
CONFIG_ENTRY_UDN,
|
||||||
|
DOMAIN,
|
||||||
PACKETS_RECEIVED,
|
PACKETS_RECEIVED,
|
||||||
PACKETS_SENT,
|
PACKETS_SENT,
|
||||||
ROUTER_IP,
|
ROUTER_IP,
|
||||||
@ -19,6 +22,8 @@ from homeassistant.components.upnp.const import (
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.util import dt
|
from homeassistant.util import dt
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
TEST_UDN = "uuid:device"
|
TEST_UDN = "uuid:device"
|
||||||
TEST_ST = "urn:schemas-upnp-org:device:InternetGatewayDevice:1"
|
TEST_ST = "urn:schemas-upnp-org:device:InternetGatewayDevice:1"
|
||||||
TEST_USN = f"{TEST_UDN}::{TEST_ST}"
|
TEST_USN = f"{TEST_UDN}::{TEST_ST}"
|
||||||
@ -115,8 +120,8 @@ class MockDevice:
|
|||||||
self.status_times_polled += 1
|
self.status_times_polled += 1
|
||||||
return {
|
return {
|
||||||
WAN_STATUS: "Connected",
|
WAN_STATUS: "Connected",
|
||||||
ROUTER_UPTIME: 0,
|
ROUTER_UPTIME: 10,
|
||||||
ROUTER_IP: "192.168.0.1",
|
ROUTER_IP: "8.9.10.11",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -185,3 +190,24 @@ async def ssdp_no_discovery():
|
|||||||
return_value=[],
|
return_value=[],
|
||||||
) as mock_get_info:
|
) as mock_get_info:
|
||||||
yield (mock_register, mock_get_info)
|
yield (mock_register, mock_get_info)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
async def setup_integration(
|
||||||
|
hass: HomeAssistant, mock_get_source_ip, ssdp_instant_discovery, mock_upnp_device
|
||||||
|
):
|
||||||
|
"""Create an initialized integration."""
|
||||||
|
entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
data={
|
||||||
|
CONFIG_ENTRY_UDN: TEST_UDN,
|
||||||
|
CONFIG_ENTRY_ST: TEST_ST,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
# Load config_entry.
|
||||||
|
entry.add_to_hass(hass)
|
||||||
|
await hass.config_entries.async_setup(entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
yield entry
|
||||||
|
42
tests/components/upnp/test_binary_sensor.py
Normal file
42
tests/components/upnp/test_binary_sensor.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
"""Tests for UPnP/IGD binary_sensor."""
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
|
from unittest.mock import AsyncMock
|
||||||
|
|
||||||
|
from homeassistant.components.upnp.const import (
|
||||||
|
DOMAIN,
|
||||||
|
ROUTER_IP,
|
||||||
|
ROUTER_UPTIME,
|
||||||
|
WAN_STATUS,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
|
from .conftest import MockDevice
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||||
|
|
||||||
|
|
||||||
|
async def test_upnp_binary_sensors(
|
||||||
|
hass: HomeAssistant, setup_integration: MockConfigEntry
|
||||||
|
):
|
||||||
|
"""Test normal sensors."""
|
||||||
|
mock_device: MockDevice = hass.data[DOMAIN][setup_integration.entry_id].device
|
||||||
|
|
||||||
|
# First poll.
|
||||||
|
wan_status_state = hass.states.get("binary_sensor.mock_name_wan_status")
|
||||||
|
assert wan_status_state.state == "on"
|
||||||
|
|
||||||
|
# Second poll.
|
||||||
|
mock_device.async_get_status = AsyncMock(
|
||||||
|
return_value={
|
||||||
|
WAN_STATUS: "Disconnected",
|
||||||
|
ROUTER_UPTIME: 100,
|
||||||
|
ROUTER_IP: "",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=31))
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
wan_status_state = hass.states.get("binary_sensor.mock_name_wan_status")
|
||||||
|
assert wan_status_state.state == "off"
|
@ -25,6 +25,7 @@ from .conftest import (
|
|||||||
TEST_ST,
|
TEST_ST,
|
||||||
TEST_UDN,
|
TEST_UDN,
|
||||||
TEST_USN,
|
TEST_USN,
|
||||||
|
MockDevice,
|
||||||
)
|
)
|
||||||
|
|
||||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||||
@ -196,7 +197,7 @@ async def test_options_flow(hass: HomeAssistant):
|
|||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
assert await hass.config_entries.async_setup(config_entry.entry_id) is True
|
assert await hass.config_entries.async_setup(config_entry.entry_id) is True
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
mock_device = hass.data[DOMAIN][config_entry.entry_id].device
|
mock_device: MockDevice = hass.data[DOMAIN][config_entry.entry_id].device
|
||||||
|
|
||||||
# Reset.
|
# Reset.
|
||||||
mock_device.traffic_times_polled = 0
|
mock_device.traffic_times_polled = 0
|
||||||
|
@ -9,7 +9,6 @@ from homeassistant.components.upnp.const import (
|
|||||||
DOMAIN,
|
DOMAIN,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.setup import async_setup_component
|
|
||||||
|
|
||||||
from .conftest import TEST_ST, TEST_UDN
|
from .conftest import TEST_ST, TEST_UDN
|
||||||
|
|
||||||
@ -28,10 +27,6 @@ async def test_async_setup_entry_default(hass: HomeAssistant):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
# Initialisation of component, no device discovered.
|
|
||||||
await async_setup_component(hass, DOMAIN, {})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
# Load config_entry.
|
# Load config_entry.
|
||||||
entry.add_to_hass(hass)
|
entry.add_to_hass(hass)
|
||||||
assert await hass.config_entries.async_setup(entry.entry_id) is True
|
assert await hass.config_entries.async_setup(entry.entry_id) is True
|
||||||
|
114
tests/components/upnp/test_sensor.py
Normal file
114
tests/components/upnp/test_sensor.py
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
"""Tests for UPnP/IGD sensor."""
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
|
from unittest.mock import AsyncMock
|
||||||
|
|
||||||
|
from homeassistant.components.upnp.const import (
|
||||||
|
BYTES_RECEIVED,
|
||||||
|
BYTES_SENT,
|
||||||
|
DOMAIN,
|
||||||
|
PACKETS_RECEIVED,
|
||||||
|
PACKETS_SENT,
|
||||||
|
ROUTER_IP,
|
||||||
|
ROUTER_UPTIME,
|
||||||
|
TIMESTAMP,
|
||||||
|
UPDATE_INTERVAL,
|
||||||
|
WAN_STATUS,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
|
from .conftest import MockDevice
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||||
|
|
||||||
|
|
||||||
|
async def test_upnp_sensors(hass: HomeAssistant, setup_integration: MockConfigEntry):
|
||||||
|
"""Test normal sensors."""
|
||||||
|
mock_device: MockDevice = hass.data[DOMAIN][setup_integration.entry_id].device
|
||||||
|
|
||||||
|
# First poll.
|
||||||
|
b_received_state = hass.states.get("sensor.mock_name_b_received")
|
||||||
|
b_sent_state = hass.states.get("sensor.mock_name_b_sent")
|
||||||
|
packets_received_state = hass.states.get("sensor.mock_name_packets_received")
|
||||||
|
packets_sent_state = hass.states.get("sensor.mock_name_packets_sent")
|
||||||
|
external_ip_state = hass.states.get("sensor.mock_name_external_ip")
|
||||||
|
wan_status_state = hass.states.get("sensor.mock_name_wan_status")
|
||||||
|
assert b_received_state.state == "0"
|
||||||
|
assert b_sent_state.state == "0"
|
||||||
|
assert packets_received_state.state == "0"
|
||||||
|
assert packets_sent_state.state == "0"
|
||||||
|
assert external_ip_state.state == "8.9.10.11"
|
||||||
|
assert wan_status_state.state == "Connected"
|
||||||
|
|
||||||
|
# Second poll.
|
||||||
|
mock_device.async_get_traffic_data = AsyncMock(
|
||||||
|
return_value={
|
||||||
|
TIMESTAMP: dt_util.utcnow() + UPDATE_INTERVAL,
|
||||||
|
BYTES_RECEIVED: 10240,
|
||||||
|
BYTES_SENT: 20480,
|
||||||
|
PACKETS_RECEIVED: 30,
|
||||||
|
PACKETS_SENT: 40,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
mock_device.async_get_status = AsyncMock(
|
||||||
|
return_value={
|
||||||
|
WAN_STATUS: "Disconnected",
|
||||||
|
ROUTER_UPTIME: 100,
|
||||||
|
ROUTER_IP: "",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=31))
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
b_received_state = hass.states.get("sensor.mock_name_b_received")
|
||||||
|
b_sent_state = hass.states.get("sensor.mock_name_b_sent")
|
||||||
|
packets_received_state = hass.states.get("sensor.mock_name_packets_received")
|
||||||
|
packets_sent_state = hass.states.get("sensor.mock_name_packets_sent")
|
||||||
|
external_ip_state = hass.states.get("sensor.mock_name_external_ip")
|
||||||
|
wan_status_state = hass.states.get("sensor.mock_name_wan_status")
|
||||||
|
assert b_received_state.state == "10240"
|
||||||
|
assert b_sent_state.state == "20480"
|
||||||
|
assert packets_received_state.state == "30"
|
||||||
|
assert packets_sent_state.state == "40"
|
||||||
|
assert external_ip_state.state == ""
|
||||||
|
assert wan_status_state.state == "Disconnected"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_derived_upnp_sensors(
|
||||||
|
hass: HomeAssistant, setup_integration: MockConfigEntry
|
||||||
|
):
|
||||||
|
"""Test derived sensors."""
|
||||||
|
mock_device: MockDevice = hass.data[DOMAIN][setup_integration.entry_id].device
|
||||||
|
|
||||||
|
# First poll.
|
||||||
|
kib_s_received_state = hass.states.get("sensor.mock_name_kib_s_received")
|
||||||
|
kib_s_sent_state = hass.states.get("sensor.mock_name_kib_s_sent")
|
||||||
|
packets_s_received_state = hass.states.get("sensor.mock_name_packets_s_received")
|
||||||
|
packets_s_sent_state = hass.states.get("sensor.mock_name_packets_s_sent")
|
||||||
|
assert kib_s_received_state.state == "unknown"
|
||||||
|
assert kib_s_sent_state.state == "unknown"
|
||||||
|
assert packets_s_received_state.state == "unknown"
|
||||||
|
assert packets_s_sent_state.state == "unknown"
|
||||||
|
|
||||||
|
# Second poll.
|
||||||
|
mock_device.async_get_traffic_data = AsyncMock(
|
||||||
|
return_value={
|
||||||
|
TIMESTAMP: dt_util.utcnow() + UPDATE_INTERVAL,
|
||||||
|
BYTES_RECEIVED: int(10240 * UPDATE_INTERVAL.total_seconds()),
|
||||||
|
BYTES_SENT: int(20480 * UPDATE_INTERVAL.total_seconds()),
|
||||||
|
PACKETS_RECEIVED: int(30 * UPDATE_INTERVAL.total_seconds()),
|
||||||
|
PACKETS_SENT: int(40 * UPDATE_INTERVAL.total_seconds()),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=31))
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
kib_s_received_state = hass.states.get("sensor.mock_name_kib_s_received")
|
||||||
|
kib_s_sent_state = hass.states.get("sensor.mock_name_kib_s_sent")
|
||||||
|
packets_s_received_state = hass.states.get("sensor.mock_name_packets_s_received")
|
||||||
|
packets_s_sent_state = hass.states.get("sensor.mock_name_packets_s_sent")
|
||||||
|
assert kib_s_received_state.state == "10.0"
|
||||||
|
assert kib_s_sent_state.state == "20.0"
|
||||||
|
assert packets_s_received_state.state == "30.0"
|
||||||
|
assert packets_s_sent_state.state == "40.0"
|
@ -1,7 +1,9 @@
|
|||||||
"""Test Yeelight."""
|
"""Test Yeelight."""
|
||||||
|
import asyncio
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
from yeelight import BulbException, BulbType
|
from yeelight import BulbException, BulbType
|
||||||
from yeelight.aio import KEY_CONNECTED
|
from yeelight.aio import KEY_CONNECTED
|
||||||
|
|
||||||
@ -507,3 +509,51 @@ async def test_connection_dropped_resyncs_properties(hass: HomeAssistant):
|
|||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert len(mocked_bulb.async_get_properties.mock_calls) == 2
|
assert len(mocked_bulb.async_get_properties.mock_calls) == 2
|
||||||
|
|
||||||
|
|
||||||
|
async def test_oserror_on_first_update_results_in_unavailable(hass: HomeAssistant):
|
||||||
|
"""Test that an OSError on first update results in unavailable."""
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
unique_id=ID,
|
||||||
|
data={CONF_HOST: "127.0.0.1"},
|
||||||
|
options={CONF_NAME: "Test name"},
|
||||||
|
)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
mocked_bulb = _mocked_bulb()
|
||||||
|
mocked_bulb.async_get_properties = AsyncMock(side_effect=OSError)
|
||||||
|
|
||||||
|
with _patch_discovery(), _patch_discovery_timeout(), _patch_discovery_interval(), patch(
|
||||||
|
f"{MODULE}.AsyncBulb", return_value=mocked_bulb
|
||||||
|
):
|
||||||
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert hass.states.get("light.test_name").state == STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("exception", [BulbException, asyncio.TimeoutError])
|
||||||
|
async def test_non_oserror_exception_on_first_update(
|
||||||
|
hass: HomeAssistant, exception: Exception
|
||||||
|
):
|
||||||
|
"""Test that an exceptions other than OSError on first update do not result in unavailable.
|
||||||
|
|
||||||
|
The unavailable state will come as a push update in this case
|
||||||
|
"""
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
unique_id=ID,
|
||||||
|
data={CONF_HOST: "127.0.0.1"},
|
||||||
|
options={CONF_NAME: "Test name"},
|
||||||
|
)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
mocked_bulb = _mocked_bulb()
|
||||||
|
mocked_bulb.async_get_properties = AsyncMock(side_effect=exception)
|
||||||
|
|
||||||
|
with _patch_discovery(), _patch_discovery_timeout(), _patch_discovery_interval(), patch(
|
||||||
|
f"{MODULE}.AsyncBulb", return_value=mocked_bulb
|
||||||
|
):
|
||||||
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert hass.states.get("light.test_name").state != STATE_UNAVAILABLE
|
||||||
|
@ -625,6 +625,22 @@ async def test_state_already_set_avoid_ratelimit(hass: HomeAssistant):
|
|||||||
assert mocked_bulb.async_set_brightness.mock_calls == []
|
assert mocked_bulb.async_set_brightness.mock_calls == []
|
||||||
mocked_bulb.async_set_rgb.reset_mock()
|
mocked_bulb.async_set_rgb.reset_mock()
|
||||||
|
|
||||||
|
mocked_bulb.last_properties["flowing"] = "1"
|
||||||
|
await hass.services.async_call(
|
||||||
|
"light",
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
{ATTR_ENTITY_ID: ENTITY_LIGHT, ATTR_RGB_COLOR: (red, green, blue)},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert mocked_bulb.async_set_hsv.mock_calls == []
|
||||||
|
assert mocked_bulb.async_set_rgb.mock_calls == [
|
||||||
|
call(255, 0, 0, duration=350, light_type=ANY)
|
||||||
|
]
|
||||||
|
assert mocked_bulb.async_set_color_temp.mock_calls == []
|
||||||
|
assert mocked_bulb.async_set_brightness.mock_calls == []
|
||||||
|
mocked_bulb.async_set_rgb.reset_mock()
|
||||||
|
mocked_bulb.last_properties["flowing"] = "0"
|
||||||
|
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
"light",
|
"light",
|
||||||
SERVICE_TURN_ON,
|
SERVICE_TURN_ON,
|
||||||
@ -666,6 +682,22 @@ async def test_state_already_set_avoid_ratelimit(hass: HomeAssistant):
|
|||||||
assert mocked_bulb.async_set_color_temp.mock_calls == []
|
assert mocked_bulb.async_set_color_temp.mock_calls == []
|
||||||
assert mocked_bulb.async_set_brightness.mock_calls == []
|
assert mocked_bulb.async_set_brightness.mock_calls == []
|
||||||
|
|
||||||
|
mocked_bulb.last_properties["flowing"] = "1"
|
||||||
|
await hass.services.async_call(
|
||||||
|
"light",
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
{ATTR_ENTITY_ID: ENTITY_LIGHT, ATTR_COLOR_TEMP: 250},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert mocked_bulb.async_set_hsv.mock_calls == []
|
||||||
|
assert mocked_bulb.async_set_rgb.mock_calls == []
|
||||||
|
assert mocked_bulb.async_set_color_temp.mock_calls == [
|
||||||
|
call(4000, duration=350, light_type=ANY)
|
||||||
|
]
|
||||||
|
assert mocked_bulb.async_set_brightness.mock_calls == []
|
||||||
|
mocked_bulb.async_set_color_temp.reset_mock()
|
||||||
|
mocked_bulb.last_properties["flowing"] = "0"
|
||||||
|
|
||||||
mocked_bulb.last_properties["color_mode"] = 3
|
mocked_bulb.last_properties["color_mode"] = 3
|
||||||
# This last change should generate a call even though
|
# This last change should generate a call even though
|
||||||
# the color mode is the same since the HSV has changed
|
# the color mode is the same since the HSV has changed
|
||||||
@ -681,6 +713,33 @@ async def test_state_already_set_avoid_ratelimit(hass: HomeAssistant):
|
|||||||
assert mocked_bulb.async_set_rgb.mock_calls == []
|
assert mocked_bulb.async_set_rgb.mock_calls == []
|
||||||
assert mocked_bulb.async_set_color_temp.mock_calls == []
|
assert mocked_bulb.async_set_color_temp.mock_calls == []
|
||||||
assert mocked_bulb.async_set_brightness.mock_calls == []
|
assert mocked_bulb.async_set_brightness.mock_calls == []
|
||||||
|
mocked_bulb.async_set_hsv.reset_mock()
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
"light",
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
{ATTR_ENTITY_ID: ENTITY_LIGHT, ATTR_HS_COLOR: (100, 35)},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert mocked_bulb.async_set_hsv.mock_calls == []
|
||||||
|
assert mocked_bulb.async_set_rgb.mock_calls == []
|
||||||
|
assert mocked_bulb.async_set_color_temp.mock_calls == []
|
||||||
|
assert mocked_bulb.async_set_brightness.mock_calls == []
|
||||||
|
|
||||||
|
mocked_bulb.last_properties["flowing"] = "1"
|
||||||
|
await hass.services.async_call(
|
||||||
|
"light",
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
{ATTR_ENTITY_ID: ENTITY_LIGHT, ATTR_HS_COLOR: (100, 35)},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert mocked_bulb.async_set_hsv.mock_calls == [
|
||||||
|
call(100.0, 35.0, duration=350, light_type=ANY)
|
||||||
|
]
|
||||||
|
assert mocked_bulb.async_set_rgb.mock_calls == []
|
||||||
|
assert mocked_bulb.async_set_color_temp.mock_calls == []
|
||||||
|
assert mocked_bulb.async_set_brightness.mock_calls == []
|
||||||
|
mocked_bulb.last_properties["flowing"] = "0"
|
||||||
|
|
||||||
|
|
||||||
async def test_device_types(hass: HomeAssistant, caplog):
|
async def test_device_types(hass: HomeAssistant, caplog):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user