mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Update whirlpool-sixth-sense to 0.19.1 (#139987)
This commit is contained in:
parent
2401d8900a
commit
82d5304b45
@ -1,6 +1,5 @@
|
|||||||
"""The Whirlpool Appliances integration."""
|
"""The Whirlpool Appliances integration."""
|
||||||
|
|
||||||
from dataclasses import dataclass
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from aiohttp import ClientError
|
from aiohttp import ClientError
|
||||||
@ -20,7 +19,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
|
|
||||||
PLATFORMS = [Platform.CLIMATE, Platform.SENSOR]
|
PLATFORMS = [Platform.CLIMATE, Platform.SENSOR]
|
||||||
|
|
||||||
type WhirlpoolConfigEntry = ConfigEntry[WhirlpoolData]
|
type WhirlpoolConfigEntry = ConfigEntry[AppliancesManager]
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: WhirlpoolConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: WhirlpoolConfigEntry) -> bool:
|
||||||
@ -52,8 +51,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: WhirlpoolConfigEntry) ->
|
|||||||
if not await appliances_manager.fetch_appliances():
|
if not await appliances_manager.fetch_appliances():
|
||||||
_LOGGER.error("Cannot fetch appliances")
|
_LOGGER.error("Cannot fetch appliances")
|
||||||
return False
|
return False
|
||||||
|
await appliances_manager.connect()
|
||||||
|
|
||||||
entry.runtime_data = WhirlpoolData(appliances_manager, auth, backend_selector)
|
entry.runtime_data = appliances_manager
|
||||||
|
|
||||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||||
return True
|
return True
|
||||||
@ -61,13 +61,5 @@ async def async_setup_entry(hass: HomeAssistant, entry: WhirlpoolConfigEntry) ->
|
|||||||
|
|
||||||
async def async_unload_entry(hass: HomeAssistant, entry: WhirlpoolConfigEntry) -> bool:
|
async def async_unload_entry(hass: HomeAssistant, entry: WhirlpoolConfigEntry) -> bool:
|
||||||
"""Unload a config entry."""
|
"""Unload a config entry."""
|
||||||
|
await entry.runtime_data.disconnect()
|
||||||
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class WhirlpoolData:
|
|
||||||
"""Whirlpool integaration shared data."""
|
|
||||||
|
|
||||||
appliances_manager: AppliancesManager
|
|
||||||
auth: Auth
|
|
||||||
backend_selector: BackendSelector
|
|
||||||
|
@ -5,10 +5,7 @@ from __future__ import annotations
|
|||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from aiohttp import ClientSession
|
|
||||||
from whirlpool.aircon import Aircon, FanSpeed as AirconFanSpeed, Mode as AirconMode
|
from whirlpool.aircon import Aircon, FanSpeed as AirconFanSpeed, Mode as AirconMode
|
||||||
from whirlpool.auth import Auth
|
|
||||||
from whirlpool.backendselector import BackendSelector
|
|
||||||
|
|
||||||
from homeassistant.components.climate import (
|
from homeassistant.components.climate import (
|
||||||
ENTITY_ID_FORMAT,
|
ENTITY_ID_FORMAT,
|
||||||
@ -25,7 +22,6 @@ from homeassistant.components.climate import (
|
|||||||
)
|
)
|
||||||
from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
|
from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
|
||||||
from homeassistant.helpers.device_registry import DeviceInfo
|
from homeassistant.helpers.device_registry import DeviceInfo
|
||||||
from homeassistant.helpers.entity import generate_entity_id
|
from homeassistant.helpers.entity import generate_entity_id
|
||||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
@ -73,19 +69,8 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up entry."""
|
"""Set up entry."""
|
||||||
whirlpool_data = config_entry.runtime_data
|
appliances_manager = config_entry.runtime_data
|
||||||
|
aircons = [AirConEntity(hass, aircon) for aircon in appliances_manager.aircons]
|
||||||
aircons = [
|
|
||||||
AirConEntity(
|
|
||||||
hass,
|
|
||||||
ac_data["SAID"],
|
|
||||||
ac_data["NAME"],
|
|
||||||
whirlpool_data.backend_selector,
|
|
||||||
whirlpool_data.auth,
|
|
||||||
async_get_clientsession(hass),
|
|
||||||
)
|
|
||||||
for ac_data in whirlpool_data.appliances_manager.aircons
|
|
||||||
]
|
|
||||||
async_add_entities(aircons, True)
|
async_add_entities(aircons, True)
|
||||||
|
|
||||||
|
|
||||||
@ -110,36 +95,26 @@ class AirConEntity(ClimateEntity):
|
|||||||
_attr_target_temperature_step = SUPPORTED_TARGET_TEMPERATURE_STEP
|
_attr_target_temperature_step = SUPPORTED_TARGET_TEMPERATURE_STEP
|
||||||
_attr_temperature_unit = UnitOfTemperature.CELSIUS
|
_attr_temperature_unit = UnitOfTemperature.CELSIUS
|
||||||
|
|
||||||
def __init__(
|
def __init__(self, hass: HomeAssistant, aircon: Aircon) -> None:
|
||||||
self,
|
|
||||||
hass: HomeAssistant,
|
|
||||||
said: str,
|
|
||||||
name: str | None,
|
|
||||||
backend_selector: BackendSelector,
|
|
||||||
auth: Auth,
|
|
||||||
session: ClientSession,
|
|
||||||
) -> None:
|
|
||||||
"""Initialize the entity."""
|
"""Initialize the entity."""
|
||||||
self._aircon = Aircon(backend_selector, auth, said, session)
|
self._aircon = aircon
|
||||||
self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, said, hass=hass)
|
self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, aircon.said, hass=hass)
|
||||||
self._attr_unique_id = said
|
self._attr_unique_id = aircon.said
|
||||||
|
|
||||||
self._attr_device_info = DeviceInfo(
|
self._attr_device_info = DeviceInfo(
|
||||||
identifiers={(DOMAIN, said)},
|
identifiers={(DOMAIN, aircon.said)},
|
||||||
name=name if name is not None else said,
|
name=aircon.name if aircon.name is not None else aircon.said,
|
||||||
manufacturer="Whirlpool",
|
manufacturer="Whirlpool",
|
||||||
model="Sixth Sense",
|
model="Sixth Sense",
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Connect aircon to the cloud."""
|
"""Register updates callback."""
|
||||||
self._aircon.register_attr_callback(self.async_write_ha_state)
|
self._aircon.register_attr_callback(self.async_write_ha_state)
|
||||||
await self._aircon.connect()
|
|
||||||
|
|
||||||
async def async_will_remove_from_hass(self) -> None:
|
async def async_will_remove_from_hass(self) -> None:
|
||||||
"""Close Whrilpool Appliance sockets before removing."""
|
"""Unregister updates callback."""
|
||||||
self._aircon.unregister_attr_callback(self.async_write_ha_state)
|
self._aircon.unregister_attr_callback(self.async_write_ha_state)
|
||||||
await self._aircon.disconnect()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def available(self) -> bool:
|
def available(self) -> bool:
|
||||||
|
@ -4,6 +4,8 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from whirlpool.appliance import Appliance
|
||||||
|
|
||||||
from homeassistant.components.diagnostics import async_redact_data
|
from homeassistant.components.diagnostics import async_redact_data
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
@ -26,18 +28,25 @@ async def async_get_config_entry_diagnostics(
|
|||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
"""Return diagnostics for a config entry."""
|
"""Return diagnostics for a config entry."""
|
||||||
|
|
||||||
whirlpool = config_entry.runtime_data
|
def get_appliance_diagnostics(appliance: Appliance) -> dict[str, Any]:
|
||||||
|
return {
|
||||||
|
"data_model": appliance.appliance_info.data_model,
|
||||||
|
"category": appliance.appliance_info.category,
|
||||||
|
"model_number": appliance.appliance_info.model_number,
|
||||||
|
}
|
||||||
|
|
||||||
|
appliances_manager = config_entry.runtime_data
|
||||||
diagnostics_data = {
|
diagnostics_data = {
|
||||||
"Washer_dryers": {
|
"washer_dryers": {
|
||||||
wd["NAME"]: dict(wd.items())
|
wd.name: get_appliance_diagnostics(wd)
|
||||||
for wd in whirlpool.appliances_manager.washer_dryers
|
for wd in appliances_manager.washer_dryers
|
||||||
},
|
},
|
||||||
"aircons": {
|
"aircons": {
|
||||||
ac["NAME"]: dict(ac.items()) for ac in whirlpool.appliances_manager.aircons
|
ac.name: get_appliance_diagnostics(ac) for ac in appliances_manager.aircons
|
||||||
},
|
},
|
||||||
"ovens": {
|
"ovens": {
|
||||||
oven["NAME"]: dict(oven.items())
|
oven.name: get_appliance_diagnostics(oven)
|
||||||
for oven in whirlpool.appliances_manager.ovens
|
for oven in appliances_manager.ovens
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,5 +7,5 @@
|
|||||||
"integration_type": "hub",
|
"integration_type": "hub",
|
||||||
"iot_class": "cloud_push",
|
"iot_class": "cloud_push",
|
||||||
"loggers": ["whirlpool"],
|
"loggers": ["whirlpool"],
|
||||||
"requirements": ["whirlpool-sixth-sense==0.18.12"]
|
"requirements": ["whirlpool-sixth-sense==0.19.1"]
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ from homeassistant.components.sensor import (
|
|||||||
SensorEntityDescription,
|
SensorEntityDescription,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
|
||||||
from homeassistant.helpers.device_registry import DeviceInfo
|
from homeassistant.helpers.device_registry import DeviceInfo
|
||||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
from homeassistant.helpers.typing import StateType
|
from homeassistant.helpers.typing import StateType
|
||||||
@ -134,37 +133,16 @@ async def async_setup_entry(
|
|||||||
config_entry: WhirlpoolConfigEntry,
|
config_entry: WhirlpoolConfigEntry,
|
||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Config flow entry for Whrilpool Laundry."""
|
"""Config flow entry for Whirlpool sensors."""
|
||||||
entities: list = []
|
entities: list = []
|
||||||
whirlpool_data = config_entry.runtime_data
|
appliances_manager = config_entry.runtime_data
|
||||||
for appliance in whirlpool_data.appliances_manager.washer_dryers:
|
for washer_dryer in appliances_manager.washer_dryers:
|
||||||
_wd = WasherDryer(
|
|
||||||
whirlpool_data.backend_selector,
|
|
||||||
whirlpool_data.auth,
|
|
||||||
appliance["SAID"],
|
|
||||||
async_get_clientsession(hass),
|
|
||||||
)
|
|
||||||
await _wd.connect()
|
|
||||||
|
|
||||||
entities.extend(
|
entities.extend(
|
||||||
[
|
[WasherDryerClass(washer_dryer, description) for description in SENSORS]
|
||||||
WasherDryerClass(
|
|
||||||
appliance["SAID"],
|
|
||||||
appliance["NAME"],
|
|
||||||
description,
|
|
||||||
_wd,
|
|
||||||
)
|
|
||||||
for description in SENSORS
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
entities.extend(
|
entities.extend(
|
||||||
[
|
[
|
||||||
WasherDryerTimeClass(
|
WasherDryerTimeClass(washer_dryer, description)
|
||||||
appliance["SAID"],
|
|
||||||
appliance["NAME"],
|
|
||||||
description,
|
|
||||||
_wd,
|
|
||||||
)
|
|
||||||
for description in SENSOR_TIMER
|
for description in SENSOR_TIMER
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@ -178,34 +156,30 @@ class WasherDryerClass(SensorEntity):
|
|||||||
_attr_has_entity_name = True
|
_attr_has_entity_name = True
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self, washer_dryer: WasherDryer, description: WhirlpoolSensorEntityDescription
|
||||||
said: str,
|
|
||||||
name: str,
|
|
||||||
description: WhirlpoolSensorEntityDescription,
|
|
||||||
washdry: WasherDryer,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the washer sensor."""
|
"""Initialize the washer sensor."""
|
||||||
self._wd: WasherDryer = washdry
|
self._wd: WasherDryer = washer_dryer
|
||||||
|
|
||||||
if name == "dryer":
|
if washer_dryer.name == "dryer":
|
||||||
self._attr_icon = ICON_D
|
self._attr_icon = ICON_D
|
||||||
else:
|
else:
|
||||||
self._attr_icon = ICON_W
|
self._attr_icon = ICON_W
|
||||||
|
|
||||||
self.entity_description: WhirlpoolSensorEntityDescription = description
|
self.entity_description: WhirlpoolSensorEntityDescription = description
|
||||||
self._attr_device_info = DeviceInfo(
|
self._attr_device_info = DeviceInfo(
|
||||||
identifiers={(DOMAIN, said)},
|
identifiers={(DOMAIN, washer_dryer.said)},
|
||||||
name=name.capitalize(),
|
name=washer_dryer.name.capitalize(),
|
||||||
manufacturer="Whirlpool",
|
manufacturer="Whirlpool",
|
||||||
)
|
)
|
||||||
self._attr_unique_id = f"{said}-{description.key}"
|
self._attr_unique_id = f"{washer_dryer.said}-{description.key}"
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Connect washer/dryer to the cloud."""
|
"""Register updates callback."""
|
||||||
self._wd.register_attr_callback(self.async_write_ha_state)
|
self._wd.register_attr_callback(self.async_write_ha_state)
|
||||||
|
|
||||||
async def async_will_remove_from_hass(self) -> None:
|
async def async_will_remove_from_hass(self) -> None:
|
||||||
"""Close Whirlpool Appliance sockets before removing."""
|
"""Unregister updates callback."""
|
||||||
self._wd.unregister_attr_callback(self.async_write_ha_state)
|
self._wd.unregister_attr_callback(self.async_write_ha_state)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -226,16 +200,12 @@ class WasherDryerTimeClass(RestoreSensor):
|
|||||||
_attr_has_entity_name = True
|
_attr_has_entity_name = True
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self, washer_dryer: WasherDryer, description: SensorEntityDescription
|
||||||
said: str,
|
|
||||||
name: str,
|
|
||||||
description: SensorEntityDescription,
|
|
||||||
washdry: WasherDryer,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the washer sensor."""
|
"""Initialize the washer sensor."""
|
||||||
self._wd: WasherDryer = washdry
|
self._wd: WasherDryer = washer_dryer
|
||||||
|
|
||||||
if name == "dryer":
|
if washer_dryer.name == "dryer":
|
||||||
self._attr_icon = ICON_D
|
self._attr_icon = ICON_D
|
||||||
else:
|
else:
|
||||||
self._attr_icon = ICON_W
|
self._attr_icon = ICON_W
|
||||||
@ -243,11 +213,11 @@ class WasherDryerTimeClass(RestoreSensor):
|
|||||||
self.entity_description: SensorEntityDescription = description
|
self.entity_description: SensorEntityDescription = description
|
||||||
self._running: bool | None = None
|
self._running: bool | None = None
|
||||||
self._attr_device_info = DeviceInfo(
|
self._attr_device_info = DeviceInfo(
|
||||||
identifiers={(DOMAIN, said)},
|
identifiers={(DOMAIN, washer_dryer.said)},
|
||||||
name=name.capitalize(),
|
name=washer_dryer.name.capitalize(),
|
||||||
manufacturer="Whirlpool",
|
manufacturer="Whirlpool",
|
||||||
)
|
)
|
||||||
self._attr_unique_id = f"{said}-{description.key}"
|
self._attr_unique_id = f"{washer_dryer.said}-{description.key}"
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Connect washer/dryer to the cloud."""
|
"""Connect washer/dryer to the cloud."""
|
||||||
@ -259,7 +229,6 @@ class WasherDryerTimeClass(RestoreSensor):
|
|||||||
async def async_will_remove_from_hass(self) -> None:
|
async def async_will_remove_from_hass(self) -> None:
|
||||||
"""Close Whrilpool Appliance sockets before removing."""
|
"""Close Whrilpool Appliance sockets before removing."""
|
||||||
self._wd.unregister_attr_callback(self.update_from_latest_data)
|
self._wd.unregister_attr_callback(self.update_from_latest_data)
|
||||||
await self._wd.disconnect()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def available(self) -> bool:
|
def available(self) -> bool:
|
||||||
|
2
requirements_all.txt
generated
2
requirements_all.txt
generated
@ -3061,7 +3061,7 @@ webmin-xmlrpc==0.0.2
|
|||||||
weheat==2025.2.26
|
weheat==2025.2.26
|
||||||
|
|
||||||
# homeassistant.components.whirlpool
|
# homeassistant.components.whirlpool
|
||||||
whirlpool-sixth-sense==0.18.12
|
whirlpool-sixth-sense==0.19.1
|
||||||
|
|
||||||
# homeassistant.components.whois
|
# homeassistant.components.whois
|
||||||
whois==0.9.27
|
whois==0.9.27
|
||||||
|
2
requirements_test_all.txt
generated
2
requirements_test_all.txt
generated
@ -2465,7 +2465,7 @@ webmin-xmlrpc==0.0.2
|
|||||||
weheat==2025.2.26
|
weheat==2025.2.26
|
||||||
|
|
||||||
# homeassistant.components.whirlpool
|
# homeassistant.components.whirlpool
|
||||||
whirlpool-sixth-sense==0.18.12
|
whirlpool-sixth-sense==0.19.1
|
||||||
|
|
||||||
# homeassistant.components.whois
|
# homeassistant.components.whois
|
||||||
whois==0.9.27
|
whois==0.9.27
|
||||||
|
@ -31,5 +31,4 @@ async def init_integration_with_entry(
|
|||||||
entry.add_to_hass(hass)
|
entry.add_to_hass(hass)
|
||||||
await hass.config_entries.async_setup(entry.entry_id)
|
await hass.config_entries.async_setup(entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
return entry
|
return entry
|
||||||
|
@ -8,10 +8,7 @@ import whirlpool
|
|||||||
import whirlpool.aircon
|
import whirlpool.aircon
|
||||||
from whirlpool.backendselector import Brand, Region
|
from whirlpool.backendselector import Brand, Region
|
||||||
|
|
||||||
MOCK_SAID1 = "said1"
|
from .const import MOCK_SAID1, MOCK_SAID2, MOCK_SAID3, MOCK_SAID4
|
||||||
MOCK_SAID2 = "said2"
|
|
||||||
MOCK_SAID3 = "said3"
|
|
||||||
MOCK_SAID4 = "said4"
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(
|
@pytest.fixture(
|
||||||
@ -36,7 +33,7 @@ def fixture_brand(request: pytest.FixtureRequest) -> tuple[str, Brand]:
|
|||||||
return request.param
|
return request.param
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="mock_auth_api")
|
@pytest.fixture(name="mock_auth_api", autouse=True)
|
||||||
def fixture_mock_auth_api():
|
def fixture_mock_auth_api():
|
||||||
"""Set up Auth fixture."""
|
"""Set up Auth fixture."""
|
||||||
with (
|
with (
|
||||||
@ -50,8 +47,10 @@ def fixture_mock_auth_api():
|
|||||||
yield mock_auth
|
yield mock_auth
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="mock_appliances_manager_api")
|
@pytest.fixture(name="mock_appliances_manager_api", autouse=True)
|
||||||
def fixture_mock_appliances_manager_api():
|
def fixture_mock_appliances_manager_api(
|
||||||
|
mock_aircon1_api, mock_aircon2_api, mock_sensor1_api, mock_sensor2_api
|
||||||
|
):
|
||||||
"""Set up AppliancesManager fixture."""
|
"""Set up AppliancesManager fixture."""
|
||||||
with (
|
with (
|
||||||
mock.patch(
|
mock.patch(
|
||||||
@ -63,28 +62,15 @@ def fixture_mock_appliances_manager_api():
|
|||||||
),
|
),
|
||||||
):
|
):
|
||||||
mock_appliances_manager.return_value.fetch_appliances = AsyncMock()
|
mock_appliances_manager.return_value.fetch_appliances = AsyncMock()
|
||||||
|
mock_appliances_manager.return_value.connect = AsyncMock()
|
||||||
|
mock_appliances_manager.return_value.disconnect = AsyncMock()
|
||||||
mock_appliances_manager.return_value.aircons = [
|
mock_appliances_manager.return_value.aircons = [
|
||||||
{"SAID": MOCK_SAID1, "NAME": "TestZone"},
|
mock_aircon1_api,
|
||||||
{"SAID": MOCK_SAID2, "NAME": "TestZone"},
|
mock_aircon2_api,
|
||||||
]
|
]
|
||||||
mock_appliances_manager.return_value.washer_dryers = [
|
mock_appliances_manager.return_value.washer_dryers = [
|
||||||
{"SAID": MOCK_SAID3, "NAME": "washer"},
|
mock_sensor1_api,
|
||||||
{"SAID": MOCK_SAID4, "NAME": "dryer"},
|
mock_sensor2_api,
|
||||||
]
|
|
||||||
yield mock_appliances_manager
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="mock_appliances_manager_laundry_api")
|
|
||||||
def fixture_mock_appliances_manager_laundry_api():
|
|
||||||
"""Set up AppliancesManager fixture."""
|
|
||||||
with mock.patch(
|
|
||||||
"homeassistant.components.whirlpool.AppliancesManager"
|
|
||||||
) as mock_appliances_manager:
|
|
||||||
mock_appliances_manager.return_value.fetch_appliances = AsyncMock()
|
|
||||||
mock_appliances_manager.return_value.aircons = None
|
|
||||||
mock_appliances_manager.return_value.washer_dryers = [
|
|
||||||
{"SAID": MOCK_SAID3, "NAME": "washer"},
|
|
||||||
{"SAID": MOCK_SAID4, "NAME": "dryer"},
|
|
||||||
]
|
]
|
||||||
yield mock_appliances_manager
|
yield mock_appliances_manager
|
||||||
|
|
||||||
@ -107,9 +93,11 @@ def fixture_mock_backend_selector_api():
|
|||||||
def get_aircon_mock(said):
|
def get_aircon_mock(said):
|
||||||
"""Get a mock of an air conditioner."""
|
"""Get a mock of an air conditioner."""
|
||||||
mock_aircon = mock.Mock(said=said)
|
mock_aircon = mock.Mock(said=said)
|
||||||
mock_aircon.connect = AsyncMock()
|
mock_aircon.name = f"Aircon {said}"
|
||||||
mock_aircon.disconnect = AsyncMock()
|
|
||||||
mock_aircon.register_attr_callback = MagicMock()
|
mock_aircon.register_attr_callback = MagicMock()
|
||||||
|
mock_aircon.appliance_info.data_model = "aircon_model"
|
||||||
|
mock_aircon.appliance_info.category = "aircon"
|
||||||
|
mock_aircon.appliance_info.model_number = "12345"
|
||||||
mock_aircon.get_online.return_value = True
|
mock_aircon.get_online.return_value = True
|
||||||
mock_aircon.get_power_on.return_value = True
|
mock_aircon.get_power_on.return_value = True
|
||||||
mock_aircon.get_mode.return_value = whirlpool.aircon.Mode.Cool
|
mock_aircon.get_mode.return_value = whirlpool.aircon.Mode.Cool
|
||||||
@ -132,13 +120,13 @@ def get_aircon_mock(said):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="mock_aircon1_api", autouse=False)
|
@pytest.fixture(name="mock_aircon1_api", autouse=False)
|
||||||
def fixture_mock_aircon1_api(mock_auth_api, mock_appliances_manager_api):
|
def fixture_mock_aircon1_api():
|
||||||
"""Set up air conditioner API fixture."""
|
"""Set up air conditioner API fixture."""
|
||||||
return get_aircon_mock(MOCK_SAID1)
|
return get_aircon_mock(MOCK_SAID1)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="mock_aircon2_api", autouse=False)
|
@pytest.fixture(name="mock_aircon2_api", autouse=False)
|
||||||
def fixture_mock_aircon2_api(mock_auth_api, mock_appliances_manager_api):
|
def fixture_mock_aircon2_api():
|
||||||
"""Set up air conditioner API fixture."""
|
"""Set up air conditioner API fixture."""
|
||||||
return get_aircon_mock(MOCK_SAID2)
|
return get_aircon_mock(MOCK_SAID2)
|
||||||
|
|
||||||
@ -168,9 +156,11 @@ def side_effect_function(*args, **kwargs):
|
|||||||
def get_sensor_mock(said):
|
def get_sensor_mock(said):
|
||||||
"""Get a mock of a sensor."""
|
"""Get a mock of a sensor."""
|
||||||
mock_sensor = mock.Mock(said=said)
|
mock_sensor = mock.Mock(said=said)
|
||||||
mock_sensor.connect = AsyncMock()
|
mock_sensor.name = f"WasherDryer {said}"
|
||||||
mock_sensor.disconnect = AsyncMock()
|
|
||||||
mock_sensor.register_attr_callback = MagicMock()
|
mock_sensor.register_attr_callback = MagicMock()
|
||||||
|
mock_sensor.appliance_info.data_model = "washer_dryer_model"
|
||||||
|
mock_sensor.appliance_info.category = "washer_dryer"
|
||||||
|
mock_sensor.appliance_info.model_number = "12345"
|
||||||
mock_sensor.get_online.return_value = True
|
mock_sensor.get_online.return_value = True
|
||||||
mock_sensor.get_machine_state.return_value = (
|
mock_sensor.get_machine_state.return_value = (
|
||||||
whirlpool.washerdryer.MachineState.Standby
|
whirlpool.washerdryer.MachineState.Standby
|
||||||
@ -187,13 +177,13 @@ def get_sensor_mock(said):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="mock_sensor1_api", autouse=False)
|
@pytest.fixture(name="mock_sensor1_api", autouse=False)
|
||||||
def fixture_mock_sensor1_api(mock_auth_api, mock_appliances_manager_laundry_api):
|
def fixture_mock_sensor1_api():
|
||||||
"""Set up sensor API fixture."""
|
"""Set up sensor API fixture."""
|
||||||
return get_sensor_mock(MOCK_SAID3)
|
return get_sensor_mock(MOCK_SAID3)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="mock_sensor2_api", autouse=False)
|
@pytest.fixture(name="mock_sensor2_api", autouse=False)
|
||||||
def fixture_mock_sensor2_api(mock_auth_api, mock_appliances_manager_laundry_api):
|
def fixture_mock_sensor2_api():
|
||||||
"""Set up sensor API fixture."""
|
"""Set up sensor API fixture."""
|
||||||
return get_sensor_mock(MOCK_SAID4)
|
return get_sensor_mock(MOCK_SAID4)
|
||||||
|
|
||||||
|
6
tests/components/whirlpool/const.py
Normal file
6
tests/components/whirlpool/const.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
"""Constants for the Whirlpool Sixth Sense integration tests."""
|
||||||
|
|
||||||
|
MOCK_SAID1 = "said1"
|
||||||
|
MOCK_SAID2 = "said2"
|
||||||
|
MOCK_SAID3 = "said3"
|
||||||
|
MOCK_SAID4 = "said4"
|
@ -2,24 +2,32 @@
|
|||||||
# name: test_entry_diagnostics
|
# name: test_entry_diagnostics
|
||||||
dict({
|
dict({
|
||||||
'appliances': dict({
|
'appliances': dict({
|
||||||
'Washer_dryers': dict({
|
|
||||||
'dryer': dict({
|
|
||||||
'NAME': 'dryer',
|
|
||||||
'SAID': '**REDACTED**',
|
|
||||||
}),
|
|
||||||
'washer': dict({
|
|
||||||
'NAME': 'washer',
|
|
||||||
'SAID': '**REDACTED**',
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
'aircons': dict({
|
'aircons': dict({
|
||||||
'TestZone': dict({
|
'Aircon said1': dict({
|
||||||
'NAME': 'TestZone',
|
'category': 'aircon',
|
||||||
'SAID': '**REDACTED**',
|
'data_model': 'aircon_model',
|
||||||
|
'model_number': '12345',
|
||||||
|
}),
|
||||||
|
'Aircon said2': dict({
|
||||||
|
'category': 'aircon',
|
||||||
|
'data_model': 'aircon_model',
|
||||||
|
'model_number': '12345',
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
'ovens': dict({
|
'ovens': dict({
|
||||||
}),
|
}),
|
||||||
|
'washer_dryers': dict({
|
||||||
|
'WasherDryer said3': dict({
|
||||||
|
'category': 'washer_dryer',
|
||||||
|
'data_model': 'washer_dryer_model',
|
||||||
|
'model_number': '12345',
|
||||||
|
}),
|
||||||
|
'WasherDryer said4': dict({
|
||||||
|
'category': 'washer_dryer',
|
||||||
|
'data_model': 'washer_dryer_model',
|
||||||
|
'model_number': '12345',
|
||||||
|
}),
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
'config_entry': dict({
|
'config_entry': dict({
|
||||||
'data': dict({
|
'data': dict({
|
||||||
|
@ -68,6 +68,7 @@ async def test_no_appliances(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Test the setup of the climate entities when there are no appliances available."""
|
"""Test the setup of the climate entities when there are no appliances available."""
|
||||||
mock_appliances_manager_api.return_value.aircons = []
|
mock_appliances_manager_api.return_value.aircons = []
|
||||||
|
mock_appliances_manager_api.return_value.washer_dryers = []
|
||||||
await init_integration(hass)
|
await init_integration(hass)
|
||||||
assert len(hass.states.async_all()) == 0
|
assert len(hass.states.async_all()) == 0
|
||||||
|
|
||||||
@ -75,16 +76,15 @@ async def test_no_appliances(
|
|||||||
async def test_static_attributes(
|
async def test_static_attributes(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
entity_registry: er.EntityRegistry,
|
entity_registry: er.EntityRegistry,
|
||||||
mock_aircon1_api: MagicMock,
|
|
||||||
mock_aircon_api_instances: MagicMock,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test static climate attributes."""
|
"""Test static climate attributes."""
|
||||||
await init_integration(hass)
|
await init_integration(hass)
|
||||||
|
|
||||||
for entity_id in ("climate.said1", "climate.said2"):
|
for said in ("said1", "said2"):
|
||||||
|
entity_id = f"climate.{said}"
|
||||||
entry = entity_registry.async_get(entity_id)
|
entry = entity_registry.async_get(entity_id)
|
||||||
assert entry
|
assert entry
|
||||||
assert entry.unique_id == entity_id.split(".")[1]
|
assert entry.unique_id == said
|
||||||
|
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state is not None
|
assert state is not None
|
||||||
@ -92,7 +92,7 @@ async def test_static_attributes(
|
|||||||
assert state.state == HVACMode.COOL
|
assert state.state == HVACMode.COOL
|
||||||
|
|
||||||
attributes = state.attributes
|
attributes = state.attributes
|
||||||
assert attributes[ATTR_FRIENDLY_NAME] == "TestZone"
|
assert attributes[ATTR_FRIENDLY_NAME] == f"Aircon {said}"
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
attributes[ATTR_SUPPORTED_FEATURES]
|
attributes[ATTR_SUPPORTED_FEATURES]
|
||||||
@ -123,7 +123,6 @@ async def test_static_attributes(
|
|||||||
|
|
||||||
async def test_dynamic_attributes(
|
async def test_dynamic_attributes(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_aircon_api_instances: MagicMock,
|
|
||||||
mock_aircon1_api: MagicMock,
|
mock_aircon1_api: MagicMock,
|
||||||
mock_aircon2_api: MagicMock,
|
mock_aircon2_api: MagicMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -212,7 +211,6 @@ async def test_dynamic_attributes(
|
|||||||
|
|
||||||
async def test_service_calls(
|
async def test_service_calls(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_aircon_api_instances: MagicMock,
|
|
||||||
mock_aircon1_api: MagicMock,
|
mock_aircon1_api: MagicMock,
|
||||||
mock_aircon2_api: MagicMock,
|
mock_aircon2_api: MagicMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
"""Test Blink diagnostics."""
|
"""Test Blink diagnostics."""
|
||||||
|
|
||||||
from unittest.mock import MagicMock
|
|
||||||
|
|
||||||
from syrupy import SnapshotAssertion
|
from syrupy import SnapshotAssertion
|
||||||
from syrupy.filters import props
|
from syrupy.filters import props
|
||||||
|
|
||||||
@ -19,9 +17,6 @@ async def test_entry_diagnostics(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
hass_client: ClientSessionGenerator,
|
hass_client: ClientSessionGenerator,
|
||||||
snapshot: SnapshotAssertion,
|
snapshot: SnapshotAssertion,
|
||||||
mock_appliances_manager_api: MagicMock,
|
|
||||||
mock_aircon1_api: MagicMock,
|
|
||||||
mock_aircon_api_instances: MagicMock,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test config entry diagnostics."""
|
"""Test config entry diagnostics."""
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ async def test_setup(
|
|||||||
mock_backend_selector_api: MagicMock,
|
mock_backend_selector_api: MagicMock,
|
||||||
region,
|
region,
|
||||||
brand,
|
brand,
|
||||||
mock_aircon_api_instances: MagicMock,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test setup."""
|
"""Test setup."""
|
||||||
entry = await init_integration(hass, region[0], brand[0])
|
entry = await init_integration(hass, region[0], brand[0])
|
||||||
@ -33,7 +32,6 @@ async def test_setup(
|
|||||||
async def test_setup_region_fallback(
|
async def test_setup_region_fallback(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_backend_selector_api: MagicMock,
|
mock_backend_selector_api: MagicMock,
|
||||||
mock_aircon_api_instances: MagicMock,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test setup when no region is available on the ConfigEntry.
|
"""Test setup when no region is available on the ConfigEntry.
|
||||||
|
|
||||||
@ -57,7 +55,6 @@ async def test_setup_brand_fallback(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
region,
|
region,
|
||||||
mock_backend_selector_api: MagicMock,
|
mock_backend_selector_api: MagicMock,
|
||||||
mock_aircon_api_instances: MagicMock,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test setup when no brand is available on the ConfigEntry.
|
"""Test setup when no brand is available on the ConfigEntry.
|
||||||
|
|
||||||
@ -81,7 +78,6 @@ async def test_setup_brand_fallback(
|
|||||||
async def test_setup_http_exception(
|
async def test_setup_http_exception(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_auth_api: MagicMock,
|
mock_auth_api: MagicMock,
|
||||||
mock_aircon_api_instances: MagicMock,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test setup with an http exception."""
|
"""Test setup with an http exception."""
|
||||||
mock_auth_api.return_value.do_auth = AsyncMock(
|
mock_auth_api.return_value.do_auth = AsyncMock(
|
||||||
@ -95,7 +91,6 @@ async def test_setup_http_exception(
|
|||||||
async def test_setup_auth_failed(
|
async def test_setup_auth_failed(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_auth_api: MagicMock,
|
mock_auth_api: MagicMock,
|
||||||
mock_aircon_api_instances: MagicMock,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test setup with failed auth."""
|
"""Test setup with failed auth."""
|
||||||
mock_auth_api.return_value.do_auth = AsyncMock()
|
mock_auth_api.return_value.do_auth = AsyncMock()
|
||||||
@ -108,7 +103,6 @@ async def test_setup_auth_failed(
|
|||||||
async def test_setup_auth_account_locked(
|
async def test_setup_auth_account_locked(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_auth_api: MagicMock,
|
mock_auth_api: MagicMock,
|
||||||
mock_aircon_api_instances: MagicMock,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test setup with failed auth due to account being locked."""
|
"""Test setup with failed auth due to account being locked."""
|
||||||
mock_auth_api.return_value.do_auth.side_effect = AccountLockedError
|
mock_auth_api.return_value.do_auth.side_effect = AccountLockedError
|
||||||
@ -120,7 +114,6 @@ async def test_setup_auth_account_locked(
|
|||||||
async def test_setup_fetch_appliances_failed(
|
async def test_setup_fetch_appliances_failed(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_appliances_manager_api: MagicMock,
|
mock_appliances_manager_api: MagicMock,
|
||||||
mock_aircon_api_instances: MagicMock,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test setup with failed fetch_appliances."""
|
"""Test setup with failed fetch_appliances."""
|
||||||
mock_appliances_manager_api.return_value.fetch_appliances.return_value = False
|
mock_appliances_manager_api.return_value.fetch_appliances.return_value = False
|
||||||
@ -129,11 +122,7 @@ async def test_setup_fetch_appliances_failed(
|
|||||||
assert entry.state is ConfigEntryState.SETUP_ERROR
|
assert entry.state is ConfigEntryState.SETUP_ERROR
|
||||||
|
|
||||||
|
|
||||||
async def test_unload_entry(
|
async def test_unload_entry(hass: HomeAssistant) -> None:
|
||||||
hass: HomeAssistant,
|
|
||||||
mock_aircon_api_instances: MagicMock,
|
|
||||||
mock_sensor_api_instances: MagicMock,
|
|
||||||
) -> None:
|
|
||||||
"""Test successful unload of entry."""
|
"""Test successful unload of entry."""
|
||||||
entry = await init_integration(hass)
|
entry = await init_integration(hass)
|
||||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
||||||
|
@ -12,14 +12,13 @@ from homeassistant.helpers import entity_registry as er
|
|||||||
from homeassistant.util.dt import as_timestamp, utc_from_timestamp, utcnow
|
from homeassistant.util.dt import as_timestamp, utc_from_timestamp, utcnow
|
||||||
|
|
||||||
from . import init_integration
|
from . import init_integration
|
||||||
|
from .const import MOCK_SAID3, MOCK_SAID4
|
||||||
|
|
||||||
from tests.common import async_fire_time_changed, mock_restore_cache_with_extra_data
|
from tests.common import async_fire_time_changed, mock_restore_cache_with_extra_data
|
||||||
|
|
||||||
|
|
||||||
async def update_sensor_state(
|
async def update_sensor_state(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant, entity_id: str, mock_sensor_api_instance: MagicMock
|
||||||
entity_id: str,
|
|
||||||
mock_sensor_api_instance: MagicMock,
|
|
||||||
) -> State:
|
) -> State:
|
||||||
"""Simulate an update trigger from the API."""
|
"""Simulate an update trigger from the API."""
|
||||||
|
|
||||||
@ -46,10 +45,7 @@ def side_effect_function_open_door(*args, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
async def test_dryer_sensor_values(
|
async def test_dryer_sensor_values(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant, mock_sensor2_api: MagicMock, entity_registry: er.EntityRegistry
|
||||||
mock_sensor_api_instances: MagicMock,
|
|
||||||
mock_sensor2_api: MagicMock,
|
|
||||||
entity_registry: er.EntityRegistry,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the sensor value callbacks."""
|
"""Test the sensor value callbacks."""
|
||||||
hass.set_state(CoreState.not_running)
|
hass.set_state(CoreState.not_running)
|
||||||
@ -58,14 +54,11 @@ async def test_dryer_sensor_values(
|
|||||||
hass,
|
hass,
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
State(
|
State(f"sensor.washerdryer_{MOCK_SAID3}_end_time", "1"),
|
||||||
"sensor.washer_end_time",
|
|
||||||
"1",
|
|
||||||
),
|
|
||||||
{"native_value": thetimestamp, "native_unit_of_measurement": None},
|
{"native_value": thetimestamp, "native_unit_of_measurement": None},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
State("sensor.dryer_end_time", "1"),
|
State(f"sensor.washerdryer_{MOCK_SAID4}_end_time", "1"),
|
||||||
{"native_value": thetimestamp, "native_unit_of_measurement": None},
|
{"native_value": thetimestamp, "native_unit_of_measurement": None},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -73,7 +66,7 @@ async def test_dryer_sensor_values(
|
|||||||
|
|
||||||
await init_integration(hass)
|
await init_integration(hass)
|
||||||
|
|
||||||
entity_id = "sensor.dryer_state"
|
entity_id = f"sensor.washerdryer_{MOCK_SAID4}_state"
|
||||||
mock_instance = mock_sensor2_api
|
mock_instance = mock_sensor2_api
|
||||||
entry = entity_registry.async_get(entity_id)
|
entry = entity_registry.async_get(entity_id)
|
||||||
assert entry
|
assert entry
|
||||||
@ -83,7 +76,7 @@ async def test_dryer_sensor_values(
|
|||||||
|
|
||||||
state = await update_sensor_state(hass, entity_id, mock_instance)
|
state = await update_sensor_state(hass, entity_id, mock_instance)
|
||||||
assert state is not None
|
assert state is not None
|
||||||
state_id = f"{entity_id.split('_', maxsplit=1)[0]}_end_time"
|
state_id = f"sensor.washerdryer_{MOCK_SAID3}_end_time"
|
||||||
state = hass.states.get(state_id)
|
state = hass.states.get(state_id)
|
||||||
assert state.state == thetimestamp.isoformat()
|
assert state.state == thetimestamp.isoformat()
|
||||||
|
|
||||||
@ -110,10 +103,7 @@ async def test_dryer_sensor_values(
|
|||||||
|
|
||||||
|
|
||||||
async def test_washer_sensor_values(
|
async def test_washer_sensor_values(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant, mock_sensor1_api: MagicMock, entity_registry: er.EntityRegistry
|
||||||
mock_sensor_api_instances: MagicMock,
|
|
||||||
mock_sensor1_api: MagicMock,
|
|
||||||
entity_registry: er.EntityRegistry,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the sensor value callbacks."""
|
"""Test the sensor value callbacks."""
|
||||||
hass.set_state(CoreState.not_running)
|
hass.set_state(CoreState.not_running)
|
||||||
@ -122,14 +112,11 @@ async def test_washer_sensor_values(
|
|||||||
hass,
|
hass,
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
State(
|
State(f"sensor.washerdryer_{MOCK_SAID3}_end_time", "1"),
|
||||||
"sensor.washer_end_time",
|
|
||||||
"1",
|
|
||||||
),
|
|
||||||
{"native_value": thetimestamp, "native_unit_of_measurement": None},
|
{"native_value": thetimestamp, "native_unit_of_measurement": None},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
State("sensor.dryer_end_time", "1"),
|
State(f"sensor.washerdryer_{MOCK_SAID4}_end_time", "1"),
|
||||||
{"native_value": thetimestamp, "native_unit_of_measurement": None},
|
{"native_value": thetimestamp, "native_unit_of_measurement": None},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -143,7 +130,7 @@ async def test_washer_sensor_values(
|
|||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
entity_id = "sensor.washer_state"
|
entity_id = f"sensor.washerdryer_{MOCK_SAID3}_state"
|
||||||
mock_instance = mock_sensor1_api
|
mock_instance = mock_sensor1_api
|
||||||
entry = entity_registry.async_get(entity_id)
|
entry = entity_registry.async_get(entity_id)
|
||||||
assert entry
|
assert entry
|
||||||
@ -153,11 +140,11 @@ async def test_washer_sensor_values(
|
|||||||
|
|
||||||
state = await update_sensor_state(hass, entity_id, mock_instance)
|
state = await update_sensor_state(hass, entity_id, mock_instance)
|
||||||
assert state is not None
|
assert state is not None
|
||||||
state_id = f"{entity_id.split('_', maxsplit=1)[0]}_end_time"
|
state_id = f"sensor.washerdryer_{MOCK_SAID3}_end_time"
|
||||||
state = hass.states.get(state_id)
|
state = hass.states.get(state_id)
|
||||||
assert state.state == thetimestamp.isoformat()
|
assert state.state == thetimestamp.isoformat()
|
||||||
|
|
||||||
state_id = f"{entity_id.split('_', maxsplit=1)[0]}_detergent_level"
|
state_id = f"sensor.washerdryer_{MOCK_SAID3}_detergent_level"
|
||||||
entry = entity_registry.async_get(state_id)
|
entry = entity_registry.async_get(state_id)
|
||||||
assert entry
|
assert entry
|
||||||
assert entry.disabled
|
assert entry.disabled
|
||||||
@ -277,10 +264,7 @@ async def test_washer_sensor_values(
|
|||||||
assert state.state == "door_open"
|
assert state.state == "door_open"
|
||||||
|
|
||||||
|
|
||||||
async def test_restore_state(
|
async def test_restore_state(hass: HomeAssistant) -> None:
|
||||||
hass: HomeAssistant,
|
|
||||||
mock_sensor_api_instances: MagicMock,
|
|
||||||
) -> None:
|
|
||||||
"""Test sensor restore state."""
|
"""Test sensor restore state."""
|
||||||
# Home assistant is not running yet
|
# Home assistant is not running yet
|
||||||
hass.set_state(CoreState.not_running)
|
hass.set_state(CoreState.not_running)
|
||||||
@ -289,14 +273,11 @@ async def test_restore_state(
|
|||||||
hass,
|
hass,
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
State(
|
State(f"sensor.washerdryer_{MOCK_SAID3}_end_time", "1"),
|
||||||
"sensor.washer_end_time",
|
|
||||||
"1",
|
|
||||||
),
|
|
||||||
{"native_value": thetimestamp, "native_unit_of_measurement": None},
|
{"native_value": thetimestamp, "native_unit_of_measurement": None},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
State("sensor.dryer_end_time", "1"),
|
State(f"sensor.washerdryer_{MOCK_SAID4}_end_time", "1"),
|
||||||
{"native_value": thetimestamp, "native_unit_of_measurement": None},
|
{"native_value": thetimestamp, "native_unit_of_measurement": None},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -305,20 +286,18 @@ async def test_restore_state(
|
|||||||
# create and add entry
|
# create and add entry
|
||||||
await init_integration(hass)
|
await init_integration(hass)
|
||||||
# restore from cache
|
# restore from cache
|
||||||
state = hass.states.get("sensor.washer_end_time")
|
state = hass.states.get(f"sensor.washerdryer_{MOCK_SAID3}_end_time")
|
||||||
assert state.state == thetimestamp.isoformat()
|
assert state.state == thetimestamp.isoformat()
|
||||||
state = hass.states.get("sensor.dryer_end_time")
|
state = hass.states.get(f"sensor.washerdryer_{MOCK_SAID4}_end_time")
|
||||||
assert state.state == thetimestamp.isoformat()
|
assert state.state == thetimestamp.isoformat()
|
||||||
|
|
||||||
|
|
||||||
async def test_no_restore_state(
|
async def test_no_restore_state(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant, mock_sensor1_api: MagicMock
|
||||||
mock_sensor_api_instances: MagicMock,
|
|
||||||
mock_sensor1_api: MagicMock,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test sensor restore state with no restore."""
|
"""Test sensor restore state with no restore."""
|
||||||
# create and add entry
|
# create and add entry
|
||||||
entity_id = "sensor.washer_end_time"
|
entity_id = f"sensor.washerdryer_{MOCK_SAID3}_end_time"
|
||||||
await init_integration(hass)
|
await init_integration(hass)
|
||||||
# restore from cache
|
# restore from cache
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
@ -330,11 +309,7 @@ async def test_no_restore_state(
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.freeze_time("2022-11-30 00:00:00")
|
@pytest.mark.freeze_time("2022-11-30 00:00:00")
|
||||||
async def test_callback(
|
async def test_callback(hass: HomeAssistant, mock_sensor1_api: MagicMock) -> None:
|
||||||
hass: HomeAssistant,
|
|
||||||
mock_sensor_api_instances: MagicMock,
|
|
||||||
mock_sensor1_api: MagicMock,
|
|
||||||
) -> None:
|
|
||||||
"""Test callback timestamp callback function."""
|
"""Test callback timestamp callback function."""
|
||||||
hass.set_state(CoreState.not_running)
|
hass.set_state(CoreState.not_running)
|
||||||
thetimestamp: datetime = datetime(2022, 11, 29, 00, 00, 00, 00, UTC)
|
thetimestamp: datetime = datetime(2022, 11, 29, 00, 00, 00, 00, UTC)
|
||||||
@ -342,14 +317,11 @@ async def test_callback(
|
|||||||
hass,
|
hass,
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
State(
|
State(f"sensor.washerdryer_{MOCK_SAID3}_end_time", "1"),
|
||||||
"sensor.washer_end_time",
|
|
||||||
"1",
|
|
||||||
),
|
|
||||||
{"native_value": thetimestamp, "native_unit_of_measurement": None},
|
{"native_value": thetimestamp, "native_unit_of_measurement": None},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
State("sensor.dryer_end_time", "1"),
|
State(f"sensor.washerdryer_{MOCK_SAID4}_end_time", "1"),
|
||||||
{"native_value": thetimestamp, "native_unit_of_measurement": None},
|
{"native_value": thetimestamp, "native_unit_of_measurement": None},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -358,12 +330,12 @@ async def test_callback(
|
|||||||
# create and add entry
|
# create and add entry
|
||||||
await init_integration(hass)
|
await init_integration(hass)
|
||||||
# restore from cache
|
# restore from cache
|
||||||
state = hass.states.get("sensor.washer_end_time")
|
state = hass.states.get(f"sensor.washerdryer_{MOCK_SAID3}_end_time")
|
||||||
assert state.state == thetimestamp.isoformat()
|
assert state.state == thetimestamp.isoformat()
|
||||||
callback = mock_sensor1_api.register_attr_callback.call_args_list[1][0][0]
|
callback = mock_sensor1_api.register_attr_callback.call_args_list[1][0][0]
|
||||||
callback()
|
callback()
|
||||||
|
|
||||||
state = hass.states.get("sensor.washer_end_time")
|
state = hass.states.get(f"sensor.washerdryer_{MOCK_SAID3}_end_time")
|
||||||
assert state.state == thetimestamp.isoformat()
|
assert state.state == thetimestamp.isoformat()
|
||||||
mock_sensor1_api.get_machine_state.return_value = MachineState.RunningMainCycle
|
mock_sensor1_api.get_machine_state.return_value = MachineState.RunningMainCycle
|
||||||
mock_sensor1_api.get_attribute.side_effect = None
|
mock_sensor1_api.get_attribute.side_effect = None
|
||||||
@ -371,19 +343,19 @@ async def test_callback(
|
|||||||
callback()
|
callback()
|
||||||
|
|
||||||
# Test new timestamp when machine starts a cycle.
|
# Test new timestamp when machine starts a cycle.
|
||||||
state = hass.states.get("sensor.washer_end_time")
|
state = hass.states.get(f"sensor.washerdryer_{MOCK_SAID3}_end_time")
|
||||||
time = state.state
|
time = state.state
|
||||||
assert state.state != thetimestamp.isoformat()
|
assert state.state != thetimestamp.isoformat()
|
||||||
|
|
||||||
# Test no timestamp change for < 60 seconds time change.
|
# Test no timestamp change for < 60 seconds time change.
|
||||||
mock_sensor1_api.get_attribute.return_value = "65"
|
mock_sensor1_api.get_attribute.return_value = "65"
|
||||||
callback()
|
callback()
|
||||||
state = hass.states.get("sensor.washer_end_time")
|
state = hass.states.get(f"sensor.washerdryer_{MOCK_SAID3}_end_time")
|
||||||
assert state.state == time
|
assert state.state == time
|
||||||
|
|
||||||
# Test timestamp change for > 60 seconds.
|
# Test timestamp change for > 60 seconds.
|
||||||
mock_sensor1_api.get_attribute.return_value = "125"
|
mock_sensor1_api.get_attribute.return_value = "125"
|
||||||
callback()
|
callback()
|
||||||
state = hass.states.get("sensor.washer_end_time")
|
state = hass.states.get(f"sensor.washerdryer_{MOCK_SAID3}_end_time")
|
||||||
newtime = utc_from_timestamp(as_timestamp(time) + 65)
|
newtime = utc_from_timestamp(as_timestamp(time) + 65)
|
||||||
assert state.state == newtime.isoformat()
|
assert state.state == newtime.isoformat()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user