mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 17:27:52 +00:00
Add tests for Sensibo (#71148)
* Initial commit * Check temperature missing * fix temp is none * Fix parallell * Commit to save * Fix tests * Fix test_init * assert 25 * Adjustments tests * Small removal * Cleanup * no hass.data * Adjustment test_coordinator * Minor change test_coordinator
This commit is contained in:
parent
d612b9e0b4
commit
5931f6598a
@ -1017,12 +1017,6 @@ omit =
|
||||
homeassistant/components/senseme/fan.py
|
||||
homeassistant/components/senseme/light.py
|
||||
homeassistant/components/senseme/switch.py
|
||||
homeassistant/components/sensibo/__init__.py
|
||||
homeassistant/components/sensibo/binary_sensor.py
|
||||
homeassistant/components/sensibo/climate.py
|
||||
homeassistant/components/sensibo/coordinator.py
|
||||
homeassistant/components/sensibo/diagnostics.py
|
||||
homeassistant/components/sensibo/entity.py
|
||||
homeassistant/components/sensibo/number.py
|
||||
homeassistant/components/sensibo/select.py
|
||||
homeassistant/components/sensibo/sensor.py
|
||||
|
@ -1 +1,6 @@
|
||||
"""Tests for the Sensibo integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from homeassistant.const import CONF_API_KEY
|
||||
|
||||
ENTRY_CONFIG = {CONF_API_KEY: "1234567890"}
|
||||
|
45
tests/components/sensibo/conftest.py
Normal file
45
tests/components/sensibo/conftest.py
Normal file
@ -0,0 +1,45 @@
|
||||
"""Fixtures for the Sensibo integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.sensibo.const import DOMAIN
|
||||
from homeassistant.config_entries import SOURCE_USER
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import ENTRY_CONFIG
|
||||
from .response import DATA_FROM_API
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def load_int(hass: HomeAssistant) -> MockConfigEntry:
|
||||
"""Set up the Sensibo integration in Home Assistant."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
source=SOURCE_USER,
|
||||
data=ENTRY_CONFIG,
|
||||
entry_id="1",
|
||||
unique_id="username",
|
||||
version=2,
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
), patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
|
||||
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
|
||||
), patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
|
||||
return_value={"result": {"username": "username"}},
|
||||
):
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
return config_entry
|
400
tests/components/sensibo/response.py
Normal file
400
tests/components/sensibo/response.py
Normal file
@ -0,0 +1,400 @@
|
||||
"""Test api response for the Sensibo integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from pysensibo.model import MotionSensor, SensiboData, SensiboDevice
|
||||
|
||||
DATA_FROM_API = SensiboData(
|
||||
raw={
|
||||
"status": "success",
|
||||
"result": [
|
||||
{
|
||||
"id": "ABC999111",
|
||||
"qrId": "AAAAAAAAAA",
|
||||
"room": {"uid": "99TT99TT", "name": "Hallway", "icon": "Lounge"},
|
||||
"acState": {
|
||||
"timestamp": {
|
||||
"time": "2022-04-30T19:58:15.544787Z",
|
||||
"secondsAgo": 0,
|
||||
},
|
||||
"on": False,
|
||||
"mode": "fan",
|
||||
"fanLevel": "high",
|
||||
"swing": "stopped",
|
||||
"horizontalSwing": "stopped",
|
||||
"light": "on",
|
||||
},
|
||||
"location": {
|
||||
"id": "ZZZZZZZZZZZZ",
|
||||
"name": "Home",
|
||||
"latLon": [58.9806976, 20.5864297],
|
||||
"address": ["Sealand 99", "Some county"],
|
||||
"country": "United Country",
|
||||
"createTime": {
|
||||
"time": "2020-03-21T15:44:15Z",
|
||||
"secondsAgo": 66543240,
|
||||
},
|
||||
"updateTime": None,
|
||||
"features": [],
|
||||
"geofenceTriggerRadius": 200,
|
||||
"subscription": None,
|
||||
"technician": None,
|
||||
"shareAnalytics": False,
|
||||
"occupancy": "n/a",
|
||||
},
|
||||
"accessPoint": {"ssid": "SENSIBO-I-99999", "password": None},
|
||||
"macAddress": "00:02:00:B6:00:00",
|
||||
"autoOffMinutes": None,
|
||||
"autoOffEnabled": False,
|
||||
"antiMoldTimer": None,
|
||||
"antiMoldConfig": None,
|
||||
}
|
||||
],
|
||||
},
|
||||
parsed={
|
||||
"ABC999111": SensiboDevice(
|
||||
id="ABC999111",
|
||||
mac="00:02:00:B6:00:00",
|
||||
name="Hallway",
|
||||
ac_states={
|
||||
"timestamp": {"time": "2022-04-30T19:58:15.544787Z", "secondsAgo": 0},
|
||||
"on": False,
|
||||
"mode": "heat",
|
||||
"fanLevel": "high",
|
||||
"swing": "stopped",
|
||||
"horizontalSwing": "stopped",
|
||||
"light": "on",
|
||||
},
|
||||
temp=22.4,
|
||||
humidity=38,
|
||||
target_temp=25,
|
||||
hvac_mode="heat",
|
||||
device_on=True,
|
||||
fan_mode="high",
|
||||
swing_mode="stopped",
|
||||
horizontal_swing_mode="stopped",
|
||||
light_mode="on",
|
||||
available=True,
|
||||
hvac_modes=["cool", "heat", "dry", "auto", "fan", "off"],
|
||||
fan_modes=["quiet", "low", "medium"],
|
||||
swing_modes=[
|
||||
"stopped",
|
||||
"fixedTop",
|
||||
"fixedMiddleTop",
|
||||
],
|
||||
horizontal_swing_modes=[
|
||||
"stopped",
|
||||
"fixedLeft",
|
||||
"fixedCenterLeft",
|
||||
],
|
||||
light_modes=["on", "off"],
|
||||
temp_unit="C",
|
||||
temp_list=[18, 19, 20],
|
||||
temp_step=1,
|
||||
active_features=[
|
||||
"timestamp",
|
||||
"on",
|
||||
"mode",
|
||||
"fanLevel",
|
||||
"swing",
|
||||
"targetTemperature",
|
||||
"horizontalSwing",
|
||||
"light",
|
||||
],
|
||||
full_features={
|
||||
"targetTemperature",
|
||||
"fanLevel",
|
||||
"swing",
|
||||
"horizontalSwing",
|
||||
"light",
|
||||
},
|
||||
state="heat",
|
||||
fw_ver="SKY30046",
|
||||
fw_ver_available="SKY30046",
|
||||
fw_type="esp8266ex",
|
||||
model="skyv2",
|
||||
calibration_temp=0.1,
|
||||
calibration_hum=0.1,
|
||||
full_capabilities={
|
||||
"modes": {
|
||||
"cool": {
|
||||
"temperatures": {
|
||||
"F": {
|
||||
"isNative": False,
|
||||
"values": [
|
||||
64,
|
||||
66,
|
||||
68,
|
||||
],
|
||||
},
|
||||
"C": {
|
||||
"isNative": True,
|
||||
"values": [
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
],
|
||||
},
|
||||
},
|
||||
"fanLevels": [
|
||||
"quiet",
|
||||
"low",
|
||||
"medium",
|
||||
],
|
||||
"swing": [
|
||||
"stopped",
|
||||
"fixedTop",
|
||||
"fixedMiddleTop",
|
||||
],
|
||||
"horizontalSwing": [
|
||||
"stopped",
|
||||
"fixedLeft",
|
||||
"fixedCenterLeft",
|
||||
],
|
||||
"light": ["on", "off"],
|
||||
},
|
||||
"heat": {
|
||||
"temperatures": {
|
||||
"F": {
|
||||
"isNative": False,
|
||||
"values": [
|
||||
63,
|
||||
64,
|
||||
66,
|
||||
],
|
||||
},
|
||||
"C": {
|
||||
"isNative": True,
|
||||
"values": [
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
],
|
||||
},
|
||||
},
|
||||
"fanLevels": ["quiet", "low", "medium"],
|
||||
"swing": [
|
||||
"stopped",
|
||||
"fixedTop",
|
||||
"fixedMiddleTop",
|
||||
],
|
||||
"horizontalSwing": [
|
||||
"stopped",
|
||||
"fixedLeft",
|
||||
"fixedCenterLeft",
|
||||
],
|
||||
"light": ["on", "off"],
|
||||
},
|
||||
"dry": {
|
||||
"temperatures": {
|
||||
"F": {
|
||||
"isNative": False,
|
||||
"values": [
|
||||
64,
|
||||
66,
|
||||
68,
|
||||
],
|
||||
},
|
||||
"C": {
|
||||
"isNative": True,
|
||||
"values": [
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
],
|
||||
},
|
||||
},
|
||||
"swing": [
|
||||
"stopped",
|
||||
"fixedTop",
|
||||
"fixedMiddleTop",
|
||||
],
|
||||
"horizontalSwing": [
|
||||
"stopped",
|
||||
"fixedLeft",
|
||||
"fixedCenterLeft",
|
||||
],
|
||||
"light": ["on", "off"],
|
||||
},
|
||||
"auto": {
|
||||
"temperatures": {
|
||||
"F": {
|
||||
"isNative": False,
|
||||
"values": [
|
||||
64,
|
||||
66,
|
||||
68,
|
||||
],
|
||||
},
|
||||
"C": {
|
||||
"isNative": True,
|
||||
"values": [
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
],
|
||||
},
|
||||
},
|
||||
"fanLevels": [
|
||||
"quiet",
|
||||
"low",
|
||||
"medium",
|
||||
],
|
||||
"swing": [
|
||||
"stopped",
|
||||
"fixedTop",
|
||||
"fixedMiddleTop",
|
||||
],
|
||||
"horizontalSwing": [
|
||||
"stopped",
|
||||
"fixedLeft",
|
||||
"fixedCenterLeft",
|
||||
],
|
||||
"light": ["on", "off"],
|
||||
},
|
||||
"fan": {
|
||||
"temperatures": {},
|
||||
"fanLevels": [
|
||||
"quiet",
|
||||
"low",
|
||||
],
|
||||
"swing": [
|
||||
"stopped",
|
||||
"fixedTop",
|
||||
"fixedMiddleTop",
|
||||
],
|
||||
"horizontalSwing": [
|
||||
"stopped",
|
||||
"fixedLeft",
|
||||
"fixedCenterLeft",
|
||||
],
|
||||
"light": ["on", "off"],
|
||||
},
|
||||
}
|
||||
},
|
||||
motion_sensors={
|
||||
"AABBCC": MotionSensor(
|
||||
id="AABBCC",
|
||||
alive=True,
|
||||
motion=True,
|
||||
fw_ver="V17",
|
||||
fw_type="nrf52",
|
||||
is_main_sensor=True,
|
||||
battery_voltage=3000,
|
||||
humidity=57,
|
||||
temperature=23.9,
|
||||
model="motion_sensor",
|
||||
rssi=-72,
|
||||
)
|
||||
},
|
||||
pm25=None,
|
||||
room_occupied=True,
|
||||
update_available=False,
|
||||
schedules={},
|
||||
pure_boost_enabled=None,
|
||||
pure_sensitivity=None,
|
||||
pure_ac_integration=None,
|
||||
pure_geo_integration=None,
|
||||
pure_measure_integration=None,
|
||||
timer_on=False,
|
||||
timer_id=None,
|
||||
timer_state_on=None,
|
||||
timer_time=None,
|
||||
smart_on=False,
|
||||
smart_type="temperature",
|
||||
smart_low_temp_threshold=0.0,
|
||||
smart_high_temp_threshold=27.5,
|
||||
smart_low_state={
|
||||
"on": True,
|
||||
"targetTemperature": 21,
|
||||
"temperatureUnit": "C",
|
||||
"mode": "heat",
|
||||
"fanLevel": "low",
|
||||
"swing": "stopped",
|
||||
"horizontalSwing": "stopped",
|
||||
"light": "on",
|
||||
},
|
||||
smart_high_state={
|
||||
"on": True,
|
||||
"targetTemperature": 21,
|
||||
"temperatureUnit": "C",
|
||||
"mode": "cool",
|
||||
"fanLevel": "high",
|
||||
"swing": "stopped",
|
||||
"horizontalSwing": "stopped",
|
||||
"light": "on",
|
||||
},
|
||||
filter_clean=False,
|
||||
filter_last_reset="2022-03-12T15:24:26Z",
|
||||
),
|
||||
"AAZZAAZZ": SensiboDevice(
|
||||
id="AAZZAAZZ",
|
||||
mac="00:01:00:01:00:01",
|
||||
name="Kitchen",
|
||||
ac_states={
|
||||
"timestamp": {"time": "2022-04-30T19:58:15.568753Z", "secondsAgo": 0},
|
||||
"on": False,
|
||||
"mode": "fan",
|
||||
"fanLevel": "low",
|
||||
"light": "on",
|
||||
},
|
||||
temp=None,
|
||||
humidity=None,
|
||||
target_temp=None,
|
||||
hvac_mode="off",
|
||||
device_on=False,
|
||||
fan_mode="low",
|
||||
swing_mode=None,
|
||||
horizontal_swing_mode=None,
|
||||
light_mode="on",
|
||||
available=True,
|
||||
hvac_modes=["fan", "off"],
|
||||
fan_modes=["low", "high"],
|
||||
swing_modes=None,
|
||||
horizontal_swing_modes=None,
|
||||
light_modes=["on", "dim", "off"],
|
||||
temp_unit="C",
|
||||
temp_list=[0, 1],
|
||||
temp_step=1,
|
||||
active_features=["timestamp", "on", "mode", "fanLevel", "light"],
|
||||
full_features={"light", "targetTemperature", "fanLevel"},
|
||||
state="off",
|
||||
fw_ver="PUR00111",
|
||||
fw_ver_available="PUR00111",
|
||||
fw_type="pure-esp32",
|
||||
model="pure",
|
||||
calibration_temp=0.0,
|
||||
calibration_hum=0.0,
|
||||
full_capabilities={
|
||||
"modes": {
|
||||
"fan": {
|
||||
"temperatures": {},
|
||||
"fanLevels": ["low", "high"],
|
||||
"light": ["on", "dim", "off"],
|
||||
}
|
||||
}
|
||||
},
|
||||
motion_sensors={},
|
||||
pm25=1,
|
||||
room_occupied=None,
|
||||
update_available=False,
|
||||
schedules={},
|
||||
pure_boost_enabled=False,
|
||||
pure_sensitivity="N",
|
||||
pure_ac_integration=False,
|
||||
pure_geo_integration=False,
|
||||
pure_measure_integration=True,
|
||||
timer_on=None,
|
||||
timer_id=None,
|
||||
timer_state_on=None,
|
||||
timer_time=None,
|
||||
smart_on=None,
|
||||
smart_type=None,
|
||||
smart_low_temp_threshold=None,
|
||||
smart_high_temp_threshold=None,
|
||||
smart_low_state=None,
|
||||
smart_high_state=None,
|
||||
filter_clean=False,
|
||||
filter_last_reset="2022-04-23T15:58:45Z",
|
||||
),
|
||||
},
|
||||
)
|
52
tests/components/sensibo/test_binary_sensor.py
Normal file
52
tests/components/sensibo/test_binary_sensor.py
Normal file
@ -0,0 +1,52 @@
|
||||
"""The test for the sensibo binary sensor platform."""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import timedelta
|
||||
from unittest.mock import patch
|
||||
|
||||
from pytest import MonkeyPatch
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.util import dt
|
||||
|
||||
from .response import DATA_FROM_API
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
|
||||
|
||||
async def test_binary_sensor(
|
||||
hass: HomeAssistant, load_int: ConfigEntry, monkeypatch: MonkeyPatch
|
||||
) -> None:
|
||||
"""Test the Sensibo binary sensor."""
|
||||
|
||||
state1 = hass.states.get("binary_sensor.hallway_motion_sensor_alive")
|
||||
state2 = hass.states.get("binary_sensor.hallway_motion_sensor_main_sensor")
|
||||
state3 = hass.states.get("binary_sensor.hallway_motion_sensor_motion")
|
||||
state4 = hass.states.get("binary_sensor.hallway_room_occupied")
|
||||
assert state1.state == "on"
|
||||
assert state2.state == "on"
|
||||
assert state3.state == "on"
|
||||
assert state4.state == "on"
|
||||
|
||||
monkeypatch.setattr(
|
||||
DATA_FROM_API.parsed["ABC999111"].motion_sensors["AABBCC"], "alive", False
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
DATA_FROM_API.parsed["ABC999111"].motion_sensors["AABBCC"], "motion", False
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
):
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
dt.utcnow() + timedelta(minutes=5),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state1 = hass.states.get("binary_sensor.hallway_motion_sensor_alive")
|
||||
state3 = hass.states.get("binary_sensor.hallway_motion_sensor_motion")
|
||||
assert state1.state == "off"
|
||||
assert state3.state == "off"
|
601
tests/components/sensibo/test_climate.py
Normal file
601
tests/components/sensibo/test_climate.py
Normal file
@ -0,0 +1,601 @@
|
||||
"""The test for the sensibo binary sensor platform."""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import timedelta
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from voluptuous import MultipleInvalid
|
||||
|
||||
from homeassistant.components.climate.const import (
|
||||
ATTR_FAN_MODE,
|
||||
ATTR_HVAC_MODE,
|
||||
ATTR_SWING_MODE,
|
||||
ATTR_TARGET_TEMP_HIGH,
|
||||
ATTR_TARGET_TEMP_LOW,
|
||||
DOMAIN as CLIMATE_DOMAIN,
|
||||
SERVICE_SET_FAN_MODE,
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
SERVICE_SET_SWING_MODE,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
)
|
||||
from homeassistant.components.sensibo.climate import SERVICE_ASSUME_STATE
|
||||
from homeassistant.components.sensibo.const import DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
ATTR_STATE,
|
||||
ATTR_TEMPERATURE,
|
||||
SERVICE_TURN_OFF,
|
||||
SERVICE_TURN_ON,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.util import dt
|
||||
|
||||
from .response import DATA_FROM_API
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
|
||||
|
||||
async def test_climate(hass: HomeAssistant, load_int: ConfigEntry) -> None:
|
||||
"""Test the Sensibo climate."""
|
||||
|
||||
state1 = hass.states.get("climate.hallway")
|
||||
state2 = hass.states.get("climate.kitchen")
|
||||
|
||||
assert state1.state == "heat"
|
||||
assert state1.attributes == {
|
||||
"hvac_modes": [
|
||||
"cool",
|
||||
"heat",
|
||||
"dry",
|
||||
"heat_cool",
|
||||
"fan_only",
|
||||
"off",
|
||||
],
|
||||
"min_temp": 18,
|
||||
"max_temp": 20,
|
||||
"target_temp_step": 1,
|
||||
"fan_modes": ["quiet", "low", "medium"],
|
||||
"swing_modes": [
|
||||
"stopped",
|
||||
"fixedTop",
|
||||
"fixedMiddleTop",
|
||||
],
|
||||
"current_temperature": 22.4,
|
||||
"temperature": 25,
|
||||
"current_humidity": 38,
|
||||
"fan_mode": "high",
|
||||
"swing_mode": "stopped",
|
||||
"friendly_name": "Hallway",
|
||||
"supported_features": 41,
|
||||
}
|
||||
|
||||
assert state2.state == "off"
|
||||
|
||||
|
||||
async def test_climate_fan(
|
||||
hass: HomeAssistant, load_int: ConfigEntry, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
"""Test the Sensibo climate fan service."""
|
||||
|
||||
state1 = hass.states.get("climate.hallway")
|
||||
assert state1.attributes["fan_mode"] == "high"
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
return_value={"result": {"status": "Success"}},
|
||||
):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_FAN_MODE,
|
||||
{ATTR_ENTITY_ID: state1.entity_id, ATTR_FAN_MODE: "low"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state2 = hass.states.get("climate.hallway")
|
||||
assert state2.attributes["fan_mode"] == "low"
|
||||
|
||||
monkeypatch.setattr(
|
||||
DATA_FROM_API.parsed["ABC999111"],
|
||||
"active_features",
|
||||
[
|
||||
"timestamp",
|
||||
"on",
|
||||
"mode",
|
||||
"swing",
|
||||
"targetTemperature",
|
||||
"horizontalSwing",
|
||||
"light",
|
||||
],
|
||||
)
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
):
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
dt.utcnow() + timedelta(minutes=5),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
):
|
||||
with pytest.raises(HomeAssistantError):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_FAN_MODE,
|
||||
{ATTR_ENTITY_ID: state1.entity_id, ATTR_FAN_MODE: "low"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state3 = hass.states.get("climate.hallway")
|
||||
assert state3.attributes["fan_mode"] == "low"
|
||||
|
||||
|
||||
async def test_climate_swing(
|
||||
hass: HomeAssistant, load_int: ConfigEntry, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
"""Test the Sensibo climate swing service."""
|
||||
|
||||
state1 = hass.states.get("climate.hallway")
|
||||
assert state1.attributes["swing_mode"] == "stopped"
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
return_value={"result": {"status": "Success"}},
|
||||
):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_SWING_MODE,
|
||||
{ATTR_ENTITY_ID: state1.entity_id, ATTR_SWING_MODE: "fixedTop"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state2 = hass.states.get("climate.hallway")
|
||||
assert state2.attributes["swing_mode"] == "fixedTop"
|
||||
|
||||
monkeypatch.setattr(
|
||||
DATA_FROM_API.parsed["ABC999111"],
|
||||
"active_features",
|
||||
[
|
||||
"timestamp",
|
||||
"on",
|
||||
"mode",
|
||||
"targetTemperature",
|
||||
"horizontalSwing",
|
||||
"light",
|
||||
],
|
||||
)
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
):
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
dt.utcnow() + timedelta(minutes=5),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
):
|
||||
with pytest.raises(HomeAssistantError):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_SWING_MODE,
|
||||
{ATTR_ENTITY_ID: state1.entity_id, ATTR_SWING_MODE: "fixedTop"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state3 = hass.states.get("climate.hallway")
|
||||
assert state3.attributes["swing_mode"] == "fixedTop"
|
||||
|
||||
|
||||
async def test_climate_temperatures(
|
||||
hass: HomeAssistant, load_int: ConfigEntry, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
"""Test the Sensibo climate temperature service."""
|
||||
|
||||
state1 = hass.states.get("climate.hallway")
|
||||
assert state1.attributes["temperature"] == 25
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
return_value={"result": {"status": "Success"}},
|
||||
):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
{ATTR_ENTITY_ID: state1.entity_id, ATTR_TEMPERATURE: 20},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state2 = hass.states.get("climate.hallway")
|
||||
assert state2.attributes["temperature"] == 20
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
return_value={"result": {"status": "Success"}},
|
||||
):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
{ATTR_ENTITY_ID: state1.entity_id, ATTR_TEMPERATURE: 15},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state2 = hass.states.get("climate.hallway")
|
||||
assert state2.attributes["temperature"] == 18
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
return_value={"result": {"status": "Success"}},
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
{ATTR_ENTITY_ID: state1.entity_id, ATTR_TEMPERATURE: 18.5},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state2 = hass.states.get("climate.hallway")
|
||||
assert state2.attributes["temperature"] == 18
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
return_value={"result": {"status": "Success"}},
|
||||
):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
{ATTR_ENTITY_ID: state1.entity_id, ATTR_TEMPERATURE: 24},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state2 = hass.states.get("climate.hallway")
|
||||
assert state2.attributes["temperature"] == 20
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
return_value={"result": {"status": "Success"}},
|
||||
):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
{ATTR_ENTITY_ID: state1.entity_id, ATTR_TEMPERATURE: 20},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state2 = hass.states.get("climate.hallway")
|
||||
assert state2.attributes["temperature"] == 20
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
return_value={"result": {"status": "Success"}},
|
||||
):
|
||||
with pytest.raises(MultipleInvalid):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
{ATTR_ENTITY_ID: state1.entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state2 = hass.states.get("climate.hallway")
|
||||
assert state2.attributes["temperature"] == 20
|
||||
|
||||
monkeypatch.setattr(
|
||||
DATA_FROM_API.parsed["ABC999111"],
|
||||
"active_features",
|
||||
[
|
||||
"timestamp",
|
||||
"on",
|
||||
"mode",
|
||||
"swing",
|
||||
"horizontalSwing",
|
||||
"light",
|
||||
],
|
||||
)
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
):
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
dt.utcnow() + timedelta(minutes=5),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
return_value={"result": {"status": "Success"}},
|
||||
):
|
||||
with pytest.raises(HomeAssistantError):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
{ATTR_ENTITY_ID: state1.entity_id, ATTR_TEMPERATURE: 20},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state2 = hass.states.get("climate.hallway")
|
||||
assert state2.attributes["temperature"] == 20
|
||||
|
||||
|
||||
async def test_climate_temperature_is_none(
|
||||
hass: HomeAssistant, load_int: ConfigEntry, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
"""Test the Sensibo climate temperature service no temperature provided."""
|
||||
|
||||
monkeypatch.setattr(
|
||||
DATA_FROM_API.parsed["ABC999111"],
|
||||
"active_features",
|
||||
[
|
||||
"timestamp",
|
||||
"on",
|
||||
"mode",
|
||||
"fanLevel",
|
||||
"targetTemperature",
|
||||
"swing",
|
||||
"horizontalSwing",
|
||||
"light",
|
||||
],
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
DATA_FROM_API.parsed["ABC999111"],
|
||||
"target_temp",
|
||||
25,
|
||||
)
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
):
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
dt.utcnow() + timedelta(minutes=5),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state1 = hass.states.get("climate.hallway")
|
||||
assert state1.attributes["temperature"] == 25
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
{
|
||||
ATTR_ENTITY_ID: state1.entity_id,
|
||||
ATTR_TARGET_TEMP_HIGH: 30,
|
||||
ATTR_TARGET_TEMP_LOW: 20,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state2 = hass.states.get("climate.hallway")
|
||||
assert state2.attributes["temperature"] == 25
|
||||
|
||||
|
||||
async def test_climate_hvac_mode(
|
||||
hass: HomeAssistant, load_int: ConfigEntry, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
"""Test the Sensibo climate hvac mode service."""
|
||||
|
||||
monkeypatch.setattr(
|
||||
DATA_FROM_API.parsed["ABC999111"],
|
||||
"active_features",
|
||||
[
|
||||
"timestamp",
|
||||
"on",
|
||||
"mode",
|
||||
"fanLevel",
|
||||
"targetTemperature",
|
||||
"swing",
|
||||
"horizontalSwing",
|
||||
"light",
|
||||
],
|
||||
)
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
):
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
dt.utcnow() + timedelta(minutes=5),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state1 = hass.states.get("climate.hallway")
|
||||
assert state1.state == "heat"
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
), patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
return_value={"result": {"status": "Success"}},
|
||||
):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_ENTITY_ID: state1.entity_id, ATTR_HVAC_MODE: "off"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state2 = hass.states.get("climate.hallway")
|
||||
assert state2.state == "off"
|
||||
|
||||
monkeypatch.setattr(DATA_FROM_API.parsed["ABC999111"], "device_on", False)
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
):
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
dt.utcnow() + timedelta(minutes=5),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
), patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
return_value={"result": {"status": "Success"}},
|
||||
):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_ENTITY_ID: state1.entity_id, ATTR_HVAC_MODE: "heat"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state2 = hass.states.get("climate.hallway")
|
||||
assert state2.state == "heat"
|
||||
|
||||
|
||||
async def test_climate_on_off(
|
||||
hass: HomeAssistant, load_int: ConfigEntry, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
"""Test the Sensibo climate on/off service."""
|
||||
|
||||
monkeypatch.setattr(DATA_FROM_API.parsed["ABC999111"], "hvac_mode", "heat")
|
||||
monkeypatch.setattr(DATA_FROM_API.parsed["ABC999111"], "device_on", True)
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
):
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
dt.utcnow() + timedelta(minutes=5),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state1 = hass.states.get("climate.hallway")
|
||||
assert state1.state == "heat"
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
return_value={"result": {"status": "Success"}},
|
||||
):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: state1.entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state2 = hass.states.get("climate.hallway")
|
||||
assert state2.state == "off"
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
return_value={"result": {"status": "Success"}},
|
||||
):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: state1.entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state2 = hass.states.get("climate.hallway")
|
||||
assert state2.state == "heat"
|
||||
|
||||
|
||||
async def test_climate_service_failed(
|
||||
hass: HomeAssistant, load_int: ConfigEntry, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
"""Test the Sensibo climate service failed."""
|
||||
|
||||
monkeypatch.setattr(DATA_FROM_API.parsed["ABC999111"], "hvac_mode", "heat")
|
||||
monkeypatch.setattr(DATA_FROM_API.parsed["ABC999111"], "device_on", True)
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
):
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
dt.utcnow() + timedelta(minutes=5),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state1 = hass.states.get("climate.hallway")
|
||||
assert state1.state == "heat"
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
return_value={"result": {"status": "Error", "failureReason": "Did not work"}},
|
||||
):
|
||||
with pytest.raises(HomeAssistantError):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: state1.entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state2 = hass.states.get("climate.hallway")
|
||||
assert state2.state == "heat"
|
||||
|
||||
|
||||
async def test_climate_assumed_state(
|
||||
hass: HomeAssistant, load_int: ConfigEntry, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
"""Test the Sensibo climate assumed state service."""
|
||||
|
||||
monkeypatch.setattr(DATA_FROM_API.parsed["ABC999111"], "hvac_mode", "heat")
|
||||
monkeypatch.setattr(DATA_FROM_API.parsed["ABC999111"], "device_on", True)
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
):
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
dt.utcnow() + timedelta(minutes=5),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state1 = hass.states.get("climate.hallway")
|
||||
assert state1.state == "heat"
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
), patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
return_value={"result": {"status": "Success"}},
|
||||
):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_ASSUME_STATE,
|
||||
{ATTR_ENTITY_ID: state1.entity_id, ATTR_STATE: "off"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state2 = hass.states.get("climate.hallway")
|
||||
assert state2.state == "off"
|
91
tests/components/sensibo/test_coordinator.py
Normal file
91
tests/components/sensibo/test_coordinator.py
Normal file
@ -0,0 +1,91 @@
|
||||
"""The test for the sensibo coordinator."""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import timedelta
|
||||
from unittest.mock import patch
|
||||
|
||||
from pysensibo.exceptions import AuthenticationError, SensiboError
|
||||
from pysensibo.model import SensiboData
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.sensibo.const import DOMAIN
|
||||
from homeassistant.config_entries import SOURCE_USER
|
||||
from homeassistant.const import STATE_UNAVAILABLE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.util import dt
|
||||
|
||||
from . import ENTRY_CONFIG
|
||||
from .response import DATA_FROM_API
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
|
||||
|
||||
async def test_coordinator(
|
||||
hass: HomeAssistant, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
"""Test the Sensibo coordinator with errors."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
source=SOURCE_USER,
|
||||
data=ENTRY_CONFIG,
|
||||
entry_id="1",
|
||||
unique_id="username",
|
||||
version=2,
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
) as mock_data, patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
|
||||
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
|
||||
), patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
|
||||
return_value={"result": {"username": "username"}},
|
||||
):
|
||||
monkeypatch.setattr(DATA_FROM_API.parsed["ABC999111"], "hvac_mode", "heat")
|
||||
monkeypatch.setattr(DATA_FROM_API.parsed["ABC999111"], "device_on", True)
|
||||
mock_data.return_value = DATA_FROM_API
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
mock_data.assert_called_once()
|
||||
state = hass.states.get("climate.hallway")
|
||||
assert state.state == "heat"
|
||||
mock_data.reset_mock()
|
||||
|
||||
mock_data.side_effect = SensiboError("info")
|
||||
async_fire_time_changed(hass, dt.utcnow() + timedelta(minutes=1))
|
||||
await hass.async_block_till_done()
|
||||
mock_data.assert_called_once()
|
||||
state = hass.states.get("climate.hallway")
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
mock_data.reset_mock()
|
||||
|
||||
mock_data.return_value = SensiboData(raw={}, parsed={})
|
||||
mock_data.side_effect = None
|
||||
async_fire_time_changed(hass, dt.utcnow() + timedelta(minutes=3))
|
||||
await hass.async_block_till_done()
|
||||
mock_data.assert_called_once()
|
||||
state = hass.states.get("climate.hallway")
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
mock_data.reset_mock()
|
||||
|
||||
monkeypatch.setattr(DATA_FROM_API.parsed["ABC999111"], "hvac_mode", "heat")
|
||||
monkeypatch.setattr(DATA_FROM_API.parsed["ABC999111"], "device_on", True)
|
||||
|
||||
mock_data.return_value = DATA_FROM_API
|
||||
mock_data.side_effect = None
|
||||
async_fire_time_changed(hass, dt.utcnow() + timedelta(minutes=5))
|
||||
await hass.async_block_till_done()
|
||||
mock_data.assert_called_once()
|
||||
state = hass.states.get("climate.hallway")
|
||||
assert state.state == "heat"
|
||||
mock_data.reset_mock()
|
||||
|
||||
mock_data.side_effect = AuthenticationError("info")
|
||||
async_fire_time_changed(hass, dt.utcnow() + timedelta(minutes=7))
|
||||
await hass.async_block_till_done()
|
||||
mock_data.assert_called_once()
|
||||
state = hass.states.get("climate.hallway")
|
||||
assert state.state == STATE_UNAVAILABLE
|
48
tests/components/sensibo/test_diagnostics.py
Normal file
48
tests/components/sensibo/test_diagnostics.py
Normal file
@ -0,0 +1,48 @@
|
||||
"""Test Sensibo diagnostics."""
|
||||
from __future__ import annotations
|
||||
|
||||
import aiohttp
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.components.diagnostics import get_diagnostics_for_config_entry
|
||||
|
||||
|
||||
async def test_diagnostics(
|
||||
hass: HomeAssistant, hass_client: aiohttp.client, load_int: ConfigEntry
|
||||
):
|
||||
"""Test generating diagnostics for a config entry."""
|
||||
entry = load_int
|
||||
|
||||
diag = await get_diagnostics_for_config_entry(hass, hass_client, entry)
|
||||
|
||||
assert diag == {
|
||||
"status": "success",
|
||||
"result": [
|
||||
{
|
||||
"id": "**REDACTED**",
|
||||
"qrId": "**REDACTED**",
|
||||
"room": {"uid": "**REDACTED**", "name": "Hallway", "icon": "Lounge"},
|
||||
"acState": {
|
||||
"timestamp": {
|
||||
"time": "2022-04-30T19:58:15.544787Z",
|
||||
"secondsAgo": 0,
|
||||
},
|
||||
"on": False,
|
||||
"mode": "fan",
|
||||
"fanLevel": "high",
|
||||
"swing": "stopped",
|
||||
"horizontalSwing": "stopped",
|
||||
"light": "on",
|
||||
},
|
||||
"location": "**REDACTED**",
|
||||
"accessPoint": {"ssid": "**REDACTED**", "password": None},
|
||||
"macAddress": "**REDACTED**",
|
||||
"autoOffMinutes": None,
|
||||
"autoOffEnabled": False,
|
||||
"antiMoldTimer": None,
|
||||
"antiMoldConfig": None,
|
||||
}
|
||||
],
|
||||
}
|
132
tests/components/sensibo/test_entity.py
Normal file
132
tests/components/sensibo/test_entity.py
Normal file
@ -0,0 +1,132 @@
|
||||
"""The test for the sensibo entity."""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import timedelta
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.climate.const import (
|
||||
ATTR_FAN_MODE,
|
||||
DOMAIN as CLIMATE_DOMAIN,
|
||||
SERVICE_SET_FAN_MODE,
|
||||
)
|
||||
from homeassistant.components.number.const import (
|
||||
ATTR_VALUE,
|
||||
DOMAIN as NUMBER_DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
)
|
||||
from homeassistant.components.sensibo.const import SENSIBO_ERRORS
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import ATTR_ENTITY_ID
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.util import dt
|
||||
|
||||
from .response import DATA_FROM_API
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
|
||||
|
||||
async def test_entity(hass: HomeAssistant, load_int: ConfigEntry) -> None:
|
||||
"""Test the Sensibo climate."""
|
||||
|
||||
state1 = hass.states.get("climate.hallway")
|
||||
assert state1
|
||||
|
||||
dr_reg = dr.async_get(hass)
|
||||
dr_entries = dr.async_entries_for_config_entry(dr_reg, load_int.entry_id)
|
||||
dr_entry: dr.DeviceEntry
|
||||
for dr_entry in dr_entries:
|
||||
if dr_entry.name == "Hallway":
|
||||
assert dr_entry.identifiers == {("sensibo", "ABC999111")}
|
||||
device_id = dr_entry.id
|
||||
|
||||
er_reg = er.async_get(hass)
|
||||
er_entries = er.async_entries_for_device(
|
||||
er_reg, device_id, include_disabled_entities=True
|
||||
)
|
||||
er_entry: er.RegistryEntry
|
||||
for er_entry in er_entries:
|
||||
if er_entry.name == "Hallway":
|
||||
assert er_entry.unique_id == "Hallway"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("p_error", SENSIBO_ERRORS)
|
||||
async def test_entity_send_command(
|
||||
hass: HomeAssistant, p_error: Exception, load_int: ConfigEntry
|
||||
) -> None:
|
||||
"""Test the Sensibo send command with error."""
|
||||
|
||||
state = hass.states.get("climate.hallway")
|
||||
assert state
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
return_value={"result": {"status": "Success"}},
|
||||
):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_FAN_MODE,
|
||||
{ATTR_ENTITY_ID: state.entity_id, ATTR_FAN_MODE: "low"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("climate.hallway")
|
||||
assert state.attributes["fan_mode"] == "low"
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
|
||||
side_effect=p_error,
|
||||
):
|
||||
with pytest.raises(HomeAssistantError):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_FAN_MODE,
|
||||
{ATTR_ENTITY_ID: state.entity_id, ATTR_FAN_MODE: "low"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
state = hass.states.get("climate.hallway")
|
||||
assert state.attributes["fan_mode"] == "low"
|
||||
|
||||
|
||||
async def test_entity_send_command_calibration(
|
||||
hass: HomeAssistant, load_int: ConfigEntry
|
||||
) -> None:
|
||||
"""Test the Sensibo send command for calibration."""
|
||||
|
||||
registry = er.async_get(hass)
|
||||
registry.async_update_entity(
|
||||
"number.hallway_temperature_calibration", disabled_by=None
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
):
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
dt.utcnow() + timedelta(minutes=5),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("number.hallway_temperature_calibration")
|
||||
assert state.state == "0.1"
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_calibration",
|
||||
return_value={"status": "success"},
|
||||
):
|
||||
await hass.services.async_call(
|
||||
NUMBER_DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
{ATTR_ENTITY_ID: state.entity_id, ATTR_VALUE: 0.2},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
state = hass.states.get("number.hallway_temperature_calibration")
|
||||
assert state.state == "0.2"
|
132
tests/components/sensibo/test_init.py
Normal file
132
tests/components/sensibo/test_init.py
Normal file
@ -0,0 +1,132 @@
|
||||
"""Test for Sensibo component Init."""
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.sensibo.const import DOMAIN
|
||||
from homeassistant.components.sensibo.util import NoUsernameError
|
||||
from homeassistant.config_entries import SOURCE_USER
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import ENTRY_CONFIG
|
||||
from .response import DATA_FROM_API
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_setup_entry(hass: HomeAssistant) -> None:
|
||||
"""Test setup entry."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
source=SOURCE_USER,
|
||||
data=ENTRY_CONFIG,
|
||||
entry_id="1",
|
||||
unique_id="12",
|
||||
version=2,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
), patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
|
||||
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
|
||||
), patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
|
||||
return_value={"result": {"username": "username"}},
|
||||
):
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state == config_entries.ConfigEntryState.LOADED
|
||||
|
||||
|
||||
async def test_migrate_entry(hass: HomeAssistant) -> None:
|
||||
"""Test migrate entry unique id."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
source=SOURCE_USER,
|
||||
data=ENTRY_CONFIG,
|
||||
entry_id="1",
|
||||
unique_id="12",
|
||||
version=1,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
), patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
|
||||
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
|
||||
), patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
|
||||
return_value={"result": {"username": "username"}},
|
||||
):
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state == config_entries.ConfigEntryState.LOADED
|
||||
assert entry.version == 2
|
||||
assert entry.unique_id == "username"
|
||||
|
||||
|
||||
async def test_migrate_entry_fails(hass: HomeAssistant) -> None:
|
||||
"""Test migrate entry unique id."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
source=SOURCE_USER,
|
||||
data=ENTRY_CONFIG,
|
||||
entry_id="1",
|
||||
unique_id="12",
|
||||
version=1,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
), patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
|
||||
), patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
|
||||
side_effect=NoUsernameError("No username returned"),
|
||||
):
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state == config_entries.ConfigEntryState.MIGRATION_ERROR
|
||||
assert entry.version == 1
|
||||
assert entry.unique_id == "12"
|
||||
|
||||
|
||||
async def test_unload_entry(hass: HomeAssistant) -> None:
|
||||
"""Test unload an entry."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
source=SOURCE_USER,
|
||||
data=ENTRY_CONFIG,
|
||||
entry_id="1",
|
||||
unique_id="12",
|
||||
version="2",
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
|
||||
return_value=DATA_FROM_API,
|
||||
), patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
|
||||
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
|
||||
), patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
|
||||
return_value={"result": {"username": "username"}},
|
||||
):
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state == config_entries.ConfigEntryState.LOADED
|
||||
assert await hass.config_entries.async_unload(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
assert entry.state is config_entries.ConfigEntryState.NOT_LOADED
|
Loading…
x
Reference in New Issue
Block a user