Blebox add thermoBox to climate (#81090)

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
Michał Huryn 2022-12-06 14:43:35 +01:00 committed by GitHub
parent 9f36412076
commit 923fa473e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 223 additions and 125 deletions

View File

@ -21,6 +21,19 @@ from .const import DOMAIN, PRODUCT
SCAN_INTERVAL = timedelta(seconds=5)
BLEBOX_TO_HVACMODE = {
0: HVACMode.OFF,
1: HVACMode.HEAT,
2: HVACMode.COOL,
}
BLEBOX_TO_HVACACTION = {
0: HVACAction.IDLE,
1: HVACAction.HEATING,
2: HVACAction.COOLING,
3: HVACAction.IDLE,
}
async def async_setup_entry(
hass: HomeAssistant,
@ -40,20 +53,29 @@ class BleBoxClimateEntity(BleBoxEntity[blebox_uniapi.climate.Climate], ClimateEn
"""Representation of a BleBox climate feature (saunaBox)."""
_attr_supported_features = ClimateEntityFeature.TARGET_TEMPERATURE
_attr_hvac_modes = [HVACMode.OFF, HVACMode.HEAT]
_attr_temperature_unit = UnitOfTemperature.CELSIUS
@property
def hvac_modes(self):
"""Return list of supported HVAC modes."""
return [HVACMode.OFF, self.hvac_mode]
@property
def hvac_mode(self):
"""Return the desired HVAC mode."""
if self._feature.is_on is None:
return None
if self._feature.mode is not None:
return BLEBOX_TO_HVACMODE[self._feature.mode]
return HVACMode.HEAT if self._feature.is_on else HVACMode.OFF
@property
def hvac_action(self):
"""Return the actual current HVAC action."""
if self._feature.hvac_action is not None:
if not self._feature.is_on:
return HVACAction.OFF
return BLEBOX_TO_HVACACTION[self._feature.hvac_action]
if not (is_on := self._feature.is_on):
return None if is_on is None else HVACAction.OFF
@ -82,7 +104,7 @@ class BleBoxClimateEntity(BleBoxEntity[blebox_uniapi.climate.Climate], ClimateEn
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set the climate entity mode."""
if hvac_mode == HVACMode.HEAT:
if hvac_mode in [HVACMode.HEAT, HVACMode.COOL]:
await self._feature.async_on()
return

View File

@ -8,7 +8,6 @@ import pytest
from homeassistant.components.blebox.const import DOMAIN
from homeassistant.const import CONF_HOST, CONF_PORT
from homeassistant.helpers import entity_registry as er
from homeassistant.setup import async_setup_component
from tests.common import MockConfigEntry
from tests.components.light.conftest import mock_light_profiles # noqa: F401
@ -76,18 +75,20 @@ def feature_fixture(request):
return request.getfixturevalue(request.param)
async def async_setup_entities(hass, config, entity_ids):
async def async_setup_entities(hass, entity_ids):
"""Return configured entries with the given entity ids."""
config_entry = mock_config()
config_entry.add_to_hass(hass)
assert await async_setup_component(hass, DOMAIN, config)
assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
return [entity_registry.async_get(entity_id) for entity_id in entity_ids]
async def async_setup_entity(hass, config, entity_id):
async def async_setup_entity(hass, entity_id):
"""Return a configured entry with the given entity_id."""
return (await async_setup_entities(hass, config, [entity_id]))[0]
return (await async_setup_entities(hass, [entity_id]))[0]

View File

@ -28,10 +28,10 @@ def airsensor_fixture() -> tuple[AsyncMock, str]:
return feature, "binary_sensor.windrainsensor_0_rain"
async def test_init(rainsensor: AsyncMock, hass: HomeAssistant, config: dict):
async def test_init(rainsensor: AsyncMock, hass: HomeAssistant):
"""Test binary_sensor initialisation."""
_, entity_id = rainsensor
entry = await async_setup_entity(hass, config, entity_id)
entry = await async_setup_entity(hass, entity_id)
assert entry.unique_id == "BleBox-windRainSensor-ea68e74f4f49-0.rain"
state = hass.states.get(entity_id)

View File

@ -39,12 +39,12 @@ def tv_lift_box_fixture(caplog):
return (feature, "button.tvliftbox_open_or_stop")
async def test_tvliftbox_init(tvliftbox, hass, config, caplog):
async def test_tvliftbox_init(tvliftbox, hass, caplog):
"""Test tvLiftBox initialisation."""
caplog.set_level(logging.ERROR)
_, entity_id = tvliftbox
entry = await async_setup_entity(hass, config, entity_id)
entry = await async_setup_entity(hass, entity_id)
state = hass.states.get(entity_id)
assert entry.unique_id == "BleBox-tvLiftBox-4a3fdaad90aa-open_or_stop"
@ -53,13 +53,13 @@ async def test_tvliftbox_init(tvliftbox, hass, config, caplog):
@pytest.mark.parametrize("input", query_icon_matching)
async def test_get_icon(input, tvliftbox, hass, config, caplog):
async def test_get_icon(input, tvliftbox, hass, caplog):
"""Test if proper icon is returned."""
caplog.set_level(logging.ERROR)
feature_mock, entity_id = tvliftbox
feature_mock.query_string = input[0]
_ = await async_setup_entity(hass, config, entity_id)
_ = await async_setup_entity(hass, entity_id)
state = hass.states.get(entity_id)
assert state.attributes[ATTR_ICON] == input[1]

View File

@ -43,6 +43,8 @@ def saunabox_fixture():
current=None,
min_temp=-54.3,
max_temp=124.3,
mode=None,
hvac_action=None,
)
product = feature.product
type(product).name = PropertyMock(return_value="My sauna")
@ -50,11 +52,34 @@ def saunabox_fixture():
return (feature, "climate.saunabox_thermostat")
async def test_init(saunabox, hass, config):
@pytest.fixture(name="thermobox")
def thermobox_fixture():
"""Return a default climate entity mock."""
feature = mock_feature(
"climates",
blebox_uniapi.climate.Climate,
unique_id="BleBox-thermoBox-1afe34db9437-thermostat",
full_name="thermoBox-thermostat",
device_class=None,
is_on=None,
desired=None,
current=None,
min_temp=-54.3,
max_temp=124.3,
mode=2,
hvac_action=1,
)
product = feature.product
type(product).name = PropertyMock(return_value="My thermo")
type(product).model = PropertyMock(return_value="thermoBox")
return (feature, "climate.thermobox_thermostat")
async def test_init(saunabox, hass):
"""Test default state."""
_, entity_id = saunabox
entry = await async_setup_entity(hass, config, entity_id)
entry = await async_setup_entity(hass, entity_id)
assert entry.unique_id == "BleBox-saunaBox-1afe34db9437-thermostat"
state = hass.states.get(entity_id)
@ -63,7 +88,7 @@ async def test_init(saunabox, hass, config):
supported_features = state.attributes[ATTR_SUPPORTED_FEATURES]
assert supported_features & ClimateEntityFeature.TARGET_TEMPERATURE
assert state.attributes[ATTR_HVAC_MODES] == [HVACMode.OFF, HVACMode.HEAT]
assert state.attributes[ATTR_HVAC_MODES] == [HVACMode.OFF, None]
assert ATTR_DEVICE_CLASS not in state.attributes
assert ATTR_HVAC_MODE not in state.attributes
@ -97,7 +122,7 @@ async def test_update(saunabox, hass, config):
feature_mock.current = 40.9
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.OFF
@ -106,7 +131,7 @@ async def test_update(saunabox, hass, config):
assert state.state == HVACMode.OFF
async def test_on_when_below_desired(saunabox, hass, config):
async def test_on_when_below_desired(saunabox, hass):
"""Test when temperature is below desired."""
feature_mock, entity_id = saunabox
@ -115,7 +140,7 @@ async def test_on_when_below_desired(saunabox, hass, config):
feature_mock.is_on = False
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
feature_mock.async_update = AsyncMock()
def turn_on():
@ -140,7 +165,7 @@ async def test_on_when_below_desired(saunabox, hass, config):
assert state.state == HVACMode.HEAT
async def test_on_when_above_desired(saunabox, hass, config):
async def test_on_when_above_desired(saunabox, hass):
"""Test when temperature is below desired."""
feature_mock, entity_id = saunabox
@ -149,7 +174,7 @@ async def test_on_when_above_desired(saunabox, hass, config):
feature_mock.is_on = False
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
feature_mock.async_update = AsyncMock()
def turn_on():
@ -175,7 +200,7 @@ async def test_on_when_above_desired(saunabox, hass, config):
assert state.state == HVACMode.HEAT
async def test_off(saunabox, hass, config):
async def test_off(saunabox, hass):
"""Test turning off."""
feature_mock, entity_id = saunabox
@ -185,7 +210,7 @@ async def test_off(saunabox, hass, config):
feature_mock.is_heating = False
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
feature_mock.async_update = AsyncMock()
def turn_off():
@ -210,7 +235,7 @@ async def test_off(saunabox, hass, config):
assert state.state == HVACMode.OFF
async def test_set_thermo(saunabox, hass, config):
async def test_set_thermo(saunabox, hass):
"""Test setting thermostat."""
feature_mock, entity_id = saunabox
@ -220,7 +245,7 @@ async def test_set_thermo(saunabox, hass, config):
feature_mock.is_heating = False
feature_mock.async_update = AsyncMock(side_effect=update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
feature_mock.async_update = AsyncMock()
def set_temp(temp):
@ -244,13 +269,63 @@ async def test_set_thermo(saunabox, hass, config):
assert state.state == HVACMode.HEAT
async def test_update_failure(saunabox, hass, config, caplog):
async def test_update_failure(saunabox, hass, caplog):
"""Test that update failures are logged."""
caplog.set_level(logging.ERROR)
feature_mock, entity_id = saunabox
feature_mock.async_update = AsyncMock(side_effect=blebox_uniapi.error.ClientError)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
assert f"Updating '{feature_mock.full_name}' failed: " in caplog.text
async def test_reding_hvac_actions(saunabox, hass, caplog):
"""Test hvac action for given device(mock) state."""
caplog.set_level(logging.ERROR)
feature_mock, entity_id = saunabox
await async_setup_entity(hass, entity_id)
def set_heating():
feature_mock.is_on = True
feature_mock.hvac_action = 1
feature_mock.mode = 1
feature_mock.async_update = AsyncMock(side_effect=set_heating)
await hass.services.async_call(
"climate",
SERVICE_SET_TEMPERATURE,
{"entity_id": entity_id, ATTR_TEMPERATURE: 43.21},
blocking=True,
)
state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.HEATING
assert state.attributes[ATTR_HVAC_MODES] == [HVACMode.OFF, HVACMode.HEAT]
async def test_thermo_off(thermobox, hass, caplog):
"""Test hvac action off fir given device state."""
caplog.set_level(logging.ERROR)
feature_mock, entity_id = thermobox
await async_setup_entity(hass, entity_id)
def set_off():
feature_mock.is_on = False
feature_mock.hvac_action = 0
feature_mock.async_update = AsyncMock(side_effect=set_off)
await hass.services.async_call(
"climate",
SERVICE_SET_HVAC_MODE,
{"entity_id": entity_id, ATTR_HVAC_MODE: HVACMode.OFF},
blocking=True,
)
state = hass.states.get(entity_id)
assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.OFF
assert state.attributes[ATTR_HVAC_MODES] == [HVACMode.OFF, HVACMode.COOL]

View File

@ -92,11 +92,11 @@ def gate_fixture():
return (feature, "cover.gatecontroller_position")
async def test_init_gatecontroller(gatecontroller, hass, config):
async def test_init_gatecontroller(gatecontroller, hass):
"""Test gateController default state."""
_, entity_id = gatecontroller
entry = await async_setup_entity(hass, config, entity_id)
entry = await async_setup_entity(hass, entity_id)
assert entry.unique_id == "BleBox-gateController-2bee34e750b8-position"
state = hass.states.get(entity_id)
@ -122,11 +122,11 @@ async def test_init_gatecontroller(gatecontroller, hass, config):
assert device.sw_version == "1.23"
async def test_init_shutterbox(shutterbox, hass, config):
async def test_init_shutterbox(shutterbox, hass):
"""Test gateBox default state."""
_, entity_id = shutterbox
entry = await async_setup_entity(hass, config, entity_id)
entry = await async_setup_entity(hass, entity_id)
assert entry.unique_id == "BleBox-shutterBox-2bee34e750b8-position"
state = hass.states.get(entity_id)
@ -152,11 +152,11 @@ async def test_init_shutterbox(shutterbox, hass, config):
assert device.sw_version == "1.23"
async def test_init_gatebox(gatebox, hass, config):
async def test_init_gatebox(gatebox, hass):
"""Test cover default state."""
_, entity_id = gatebox
entry = await async_setup_entity(hass, config, entity_id)
entry = await async_setup_entity(hass, entity_id)
assert entry.unique_id == "BleBox-gateBox-1afe34db9437-position"
state = hass.states.get(entity_id)
@ -185,7 +185,7 @@ async def test_init_gatebox(gatebox, hass, config):
@pytest.mark.parametrize("feature", ALL_COVER_FIXTURES, indirect=["feature"])
async def test_open(feature, hass, config):
async def test_open(feature, hass):
"""Test cover opening."""
feature_mock, entity_id = feature
@ -199,7 +199,7 @@ async def test_open(feature, hass, config):
feature_mock.async_update = AsyncMock(side_effect=initial_update)
feature_mock.async_open = AsyncMock(side_effect=open_gate)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
assert hass.states.get(entity_id).state == STATE_CLOSED
feature_mock.async_update = AsyncMock()
@ -213,7 +213,7 @@ async def test_open(feature, hass, config):
@pytest.mark.parametrize("feature", ALL_COVER_FIXTURES, indirect=["feature"])
async def test_close(feature, hass, config):
async def test_close(feature, hass):
"""Test cover closing."""
feature_mock, entity_id = feature
@ -227,7 +227,7 @@ async def test_close(feature, hass, config):
feature_mock.async_update = AsyncMock(side_effect=initial_update)
feature_mock.async_close = AsyncMock(side_effect=close)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
assert hass.states.get(entity_id).state == STATE_OPEN
feature_mock.async_update = AsyncMock()
@ -251,13 +251,13 @@ def opening_to_stop_feature_mock(feature_mock):
@pytest.mark.parametrize("feature", FIXTURES_SUPPORTING_STOP, indirect=["feature"])
async def test_stop(feature, hass, config):
async def test_stop(feature, hass):
"""Test cover stopping."""
feature_mock, entity_id = feature
opening_to_stop_feature_mock(feature_mock)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
assert hass.states.get(entity_id).state == STATE_OPENING
feature_mock.async_update = AsyncMock()
@ -268,7 +268,7 @@ async def test_stop(feature, hass, config):
@pytest.mark.parametrize("feature", ALL_COVER_FIXTURES, indirect=["feature"])
async def test_update(feature, hass, config):
async def test_update(feature, hass):
"""Test cover updating."""
feature_mock, entity_id = feature
@ -279,7 +279,7 @@ async def test_update(feature, hass, config):
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
state = hass.states.get(entity_id)
assert state.attributes[ATTR_CURRENT_POSITION] == 71 # 100 - 29
@ -289,7 +289,7 @@ async def test_update(feature, hass, config):
@pytest.mark.parametrize(
"feature", ["gatecontroller", "shutterbox"], indirect=["feature"]
)
async def test_set_position(feature, hass, config):
async def test_set_position(feature, hass):
"""Test cover position setting."""
feature_mock, entity_id = feature
@ -305,7 +305,7 @@ async def test_set_position(feature, hass, config):
feature_mock.async_update = AsyncMock(side_effect=initial_update)
feature_mock.async_set_position = AsyncMock(side_effect=set_position)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
assert hass.states.get(entity_id).state == STATE_CLOSED
feature_mock.async_update = AsyncMock()
@ -318,7 +318,7 @@ async def test_set_position(feature, hass, config):
assert hass.states.get(entity_id).state == STATE_OPENING
async def test_unknown_position(shutterbox, hass, config):
async def test_unknown_position(shutterbox, hass):
"""Test cover position setting."""
feature_mock, entity_id = shutterbox
@ -329,35 +329,35 @@ async def test_unknown_position(shutterbox, hass, config):
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
state = hass.states.get(entity_id)
assert state.state == STATE_OPEN
assert ATTR_CURRENT_POSITION not in state.attributes
async def test_with_stop(gatebox, hass, config):
async def test_with_stop(gatebox, hass):
"""Test stop capability is available."""
feature_mock, entity_id = gatebox
opening_to_stop_feature_mock(feature_mock)
feature_mock.has_stop = True
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
state = hass.states.get(entity_id)
supported_features = state.attributes[ATTR_SUPPORTED_FEATURES]
assert supported_features & CoverEntityFeature.STOP
async def test_with_no_stop(gatebox, hass, config):
async def test_with_no_stop(gatebox, hass):
"""Test stop capability is not available."""
feature_mock, entity_id = gatebox
opening_to_stop_feature_mock(feature_mock)
feature_mock.has_stop = False
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
state = hass.states.get(entity_id)
supported_features = state.attributes[ATTR_SUPPORTED_FEATURES]
@ -365,20 +365,20 @@ async def test_with_no_stop(gatebox, hass, config):
@pytest.mark.parametrize("feature", ALL_COVER_FIXTURES, indirect=["feature"])
async def test_update_failure(feature, hass, config, caplog):
async def test_update_failure(feature, hass, caplog):
"""Test that update failures are logged."""
caplog.set_level(logging.ERROR)
feature_mock, entity_id = feature
feature_mock.async_update = AsyncMock(side_effect=blebox_uniapi.error.ClientError)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
assert f"Updating '{feature_mock.full_name}' failed: " in caplog.text
@pytest.mark.parametrize("feature", ALL_COVER_FIXTURES, indirect=["feature"])
async def test_opening_state(feature, hass, config):
async def test_opening_state(feature, hass):
"""Test that entity properties work."""
feature_mock, entity_id = feature
@ -387,12 +387,12 @@ async def test_opening_state(feature, hass, config):
feature_mock.state = 1 # opening
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
assert hass.states.get(entity_id).state == STATE_OPENING
@pytest.mark.parametrize("feature", ALL_COVER_FIXTURES, indirect=["feature"])
async def test_closing_state(feature, hass, config):
async def test_closing_state(feature, hass):
"""Test that entity properties work."""
feature_mock, entity_id = feature
@ -401,12 +401,12 @@ async def test_closing_state(feature, hass, config):
feature_mock.state = 0 # closing
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
assert hass.states.get(entity_id).state == STATE_CLOSING
@pytest.mark.parametrize("feature", ALL_COVER_FIXTURES, indirect=["feature"])
async def test_closed_state(feature, hass, config):
async def test_closed_state(feature, hass):
"""Test that entity properties work."""
feature_mock, entity_id = feature
@ -415,5 +415,5 @@ async def test_closed_state(feature, hass, config):
feature_mock.state = 3 # closed
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
assert hass.states.get(entity_id).state == STATE_CLOSED

View File

@ -49,11 +49,11 @@ def dimmer_fixture():
return (feature, "light.dimmerbox_brightness")
async def test_dimmer_init(dimmer, hass, config):
async def test_dimmer_init(dimmer, hass):
"""Test cover default state."""
_, entity_id = dimmer
entry = await async_setup_entity(hass, config, entity_id)
entry = await async_setup_entity(hass, entity_id)
assert entry.unique_id == "BleBox-dimmerBox-1afe34e750b8-brightness"
state = hass.states.get(entity_id)
@ -75,7 +75,7 @@ async def test_dimmer_init(dimmer, hass, config):
assert device.sw_version == "1.23"
async def test_dimmer_update(dimmer, hass, config):
async def test_dimmer_update(dimmer, hass):
"""Test light updating."""
feature_mock, entity_id = dimmer
@ -84,14 +84,14 @@ async def test_dimmer_update(dimmer, hass, config):
feature_mock.brightness = 53
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
state = hass.states.get(entity_id)
assert state.attributes[ATTR_BRIGHTNESS] == 53
assert state.state == STATE_ON
async def test_dimmer_on(dimmer, hass, config):
async def test_dimmer_on(dimmer, hass):
"""Test light on."""
feature_mock, entity_id = dimmer
@ -102,7 +102,7 @@ async def test_dimmer_on(dimmer, hass, config):
feature_mock.sensible_on_value = 254
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)
@ -126,7 +126,7 @@ async def test_dimmer_on(dimmer, hass, config):
assert state.attributes[ATTR_BRIGHTNESS] == 254
async def test_dimmer_on_with_brightness(dimmer, hass, config):
async def test_dimmer_on_with_brightness(dimmer, hass):
"""Test light on with a brightness value."""
feature_mock, entity_id = dimmer
@ -137,7 +137,7 @@ async def test_dimmer_on_with_brightness(dimmer, hass, config):
feature_mock.sensible_on_value = 254
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)
@ -167,7 +167,7 @@ async def test_dimmer_on_with_brightness(dimmer, hass, config):
assert state.state == STATE_ON
async def test_dimmer_off(dimmer, hass, config):
async def test_dimmer_off(dimmer, hass):
"""Test light off."""
feature_mock, entity_id = dimmer
@ -176,7 +176,7 @@ async def test_dimmer_off(dimmer, hass, config):
feature_mock.is_on = True
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)
@ -222,11 +222,11 @@ def wlightboxs_fixture():
return (feature, "light.wlightboxs_color")
async def test_wlightbox_s_init(wlightbox_s, hass, config):
async def test_wlightbox_s_init(wlightbox_s, hass):
"""Test cover default state."""
_, entity_id = wlightbox_s
entry = await async_setup_entity(hass, config, entity_id)
entry = await async_setup_entity(hass, entity_id)
assert entry.unique_id == "BleBox-wLightBoxS-1afe34e750b8-color"
state = hass.states.get(entity_id)
@ -248,7 +248,7 @@ async def test_wlightbox_s_init(wlightbox_s, hass, config):
assert device.sw_version == "1.23"
async def test_wlightbox_s_update(wlightbox_s, hass, config):
async def test_wlightbox_s_update(wlightbox_s, hass):
"""Test light updating."""
feature_mock, entity_id = wlightbox_s
@ -259,14 +259,14 @@ async def test_wlightbox_s_update(wlightbox_s, hass, config):
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
state = hass.states.get(entity_id)
assert state.state == STATE_ON
assert state.attributes[ATTR_BRIGHTNESS] == 0xAB
async def test_wlightbox_s_on(wlightbox_s, hass, config):
async def test_wlightbox_s_on(wlightbox_s, hass):
"""Test light on."""
feature_mock, entity_id = wlightbox_s
@ -276,7 +276,7 @@ async def test_wlightbox_s_on(wlightbox_s, hass, config):
feature_mock.sensible_on_value = 254
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)
@ -325,11 +325,11 @@ def wlightbox_fixture():
return (feature, "light.wlightbox_color")
async def test_wlightbox_init(wlightbox, hass, config):
async def test_wlightbox_init(wlightbox, hass):
"""Test cover default state."""
_, entity_id = wlightbox
entry = await async_setup_entity(hass, config, entity_id)
entry = await async_setup_entity(hass, entity_id)
assert entry.unique_id == "BleBox-wLightBox-1afe34e750b8-color"
state = hass.states.get(entity_id)
@ -352,7 +352,7 @@ async def test_wlightbox_init(wlightbox, hass, config):
assert device.sw_version == "1.23"
async def test_wlightbox_update(wlightbox, hass, config):
async def test_wlightbox_update(wlightbox, hass):
"""Test light updating."""
feature_mock, entity_id = wlightbox
@ -363,14 +363,14 @@ async def test_wlightbox_update(wlightbox, hass, config):
feature_mock.white_value = 0x3A
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
state = hass.states.get(entity_id)
assert state.attributes[ATTR_RGBW_COLOR] == (0xFA, 0x00, 0x20, 0x3A)
assert state.state == STATE_ON
async def test_wlightbox_on_rgbw(wlightbox, hass, config):
async def test_wlightbox_on_rgbw(wlightbox, hass):
"""Test light on."""
feature_mock, entity_id = wlightbox
@ -379,7 +379,7 @@ async def test_wlightbox_on_rgbw(wlightbox, hass, config):
feature_mock.is_on = False
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)
@ -420,7 +420,7 @@ async def test_wlightbox_on_rgbw(wlightbox, hass, config):
assert state.attributes[ATTR_RGBW_COLOR] == (0xC1, 0xD2, 0xF3, 0xC7)
async def test_wlightbox_on_to_last_color(wlightbox, hass, config):
async def test_wlightbox_on_to_last_color(wlightbox, hass):
"""Test light on."""
feature_mock, entity_id = wlightbox
@ -429,7 +429,7 @@ async def test_wlightbox_on_to_last_color(wlightbox, hass, config):
feature_mock.is_on = False
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)
@ -456,7 +456,7 @@ async def test_wlightbox_on_to_last_color(wlightbox, hass, config):
assert state.state == STATE_ON
async def test_wlightbox_off(wlightbox, hass, config):
async def test_wlightbox_off(wlightbox, hass):
"""Test light off."""
feature_mock, entity_id = wlightbox
@ -465,7 +465,7 @@ async def test_wlightbox_off(wlightbox, hass, config):
feature_mock.is_on = True
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)
@ -491,27 +491,27 @@ async def test_wlightbox_off(wlightbox, hass, config):
@pytest.mark.parametrize("feature", ALL_LIGHT_FIXTURES, indirect=["feature"])
async def test_update_failure(feature, hass, config, caplog):
async def test_update_failure(feature, hass, caplog):
"""Test that update failures are logged."""
caplog.set_level(logging.ERROR)
feature_mock, entity_id = feature
feature_mock.async_update = AsyncMock(side_effect=blebox_uniapi.error.ClientError)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
assert f"Updating '{feature_mock.full_name}' failed: " in caplog.text
@pytest.mark.parametrize("feature", ALL_LIGHT_FIXTURES, indirect=["feature"])
async def test_turn_on_failure(feature, hass, config, caplog):
async def test_turn_on_failure(feature, hass, caplog):
"""Test that turn_on failures are logged."""
caplog.set_level(logging.ERROR)
feature_mock, entity_id = feature
feature_mock.async_on = AsyncMock(side_effect=ValueError)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
feature_mock.sensible_on_value = 123
with pytest.raises(ValueError) as info:
@ -527,7 +527,7 @@ async def test_turn_on_failure(feature, hass, config, caplog):
)
async def test_wlightbox_on_effect(wlightbox, hass, config):
async def test_wlightbox_on_effect(wlightbox, hass):
"""Test light on."""
feature_mock, entity_id = wlightbox
@ -536,7 +536,7 @@ async def test_wlightbox_on_effect(wlightbox, hass, config):
feature_mock.is_on = False
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)

View File

@ -55,11 +55,11 @@ def tempsensor_fixture():
return (feature, "sensor.tempsensor_0_temperature")
async def test_init(tempsensor, hass, config):
async def test_init(tempsensor, hass):
"""Test sensor default state."""
_, entity_id = tempsensor
entry = await async_setup_entity(hass, config, entity_id)
entry = await async_setup_entity(hass, entity_id)
assert entry.unique_id == "BleBox-tempSensor-1afe34db9437-0.temperature"
state = hass.states.get(entity_id)
@ -79,7 +79,7 @@ async def test_init(tempsensor, hass, config):
assert device.sw_version == "1.23"
async def test_update(tempsensor, hass, config):
async def test_update(tempsensor, hass):
"""Test sensor update."""
feature_mock, entity_id = tempsensor
@ -88,30 +88,30 @@ async def test_update(tempsensor, hass, config):
feature_mock.native_value = 25.18
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
state = hass.states.get(entity_id)
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == TEMP_CELSIUS
assert state.state == "25.18"
async def test_update_failure(tempsensor, hass, config, caplog):
async def test_update_failure(tempsensor, hass, caplog):
"""Test that update failures are logged."""
caplog.set_level(logging.ERROR)
feature_mock, entity_id = tempsensor
feature_mock.async_update = AsyncMock(side_effect=blebox_uniapi.error.ClientError)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
assert f"Updating '{feature_mock.full_name}' failed: " in caplog.text
async def test_airsensor_init(airsensor, hass, config):
async def test_airsensor_init(airsensor, hass):
"""Test airSensor default state."""
_, entity_id = airsensor
entry = await async_setup_entity(hass, config, entity_id)
entry = await async_setup_entity(hass, entity_id)
assert entry.unique_id == "BleBox-airSensor-1afe34db9437-0.air"
state = hass.states.get(entity_id)
@ -130,7 +130,7 @@ async def test_airsensor_init(airsensor, hass, config):
assert device.sw_version == "1.23"
async def test_airsensor_update(airsensor, hass, config):
async def test_airsensor_update(airsensor, hass):
"""Test air quality sensor state after update."""
feature_mock, entity_id = airsensor
@ -139,7 +139,7 @@ async def test_airsensor_update(airsensor, hass, config):
feature_mock.native_value = 49
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
state = hass.states.get(entity_id)
assert (

View File

@ -49,7 +49,7 @@ async def test_switchbox_init(switchbox, hass, config):
feature_mock, entity_id = switchbox
feature_mock.async_update = AsyncMock()
entry = await async_setup_entity(hass, config, entity_id)
entry = await async_setup_entity(hass, entity_id)
assert entry.unique_id == "BleBox-switchBox-1afe34e750b8-0.relay"
state = hass.states.get(entity_id)
@ -69,7 +69,7 @@ async def test_switchbox_init(switchbox, hass, config):
assert device.sw_version == "1.23"
async def test_switchbox_update_when_off(switchbox, hass, config):
async def test_switchbox_update_when_off(switchbox, hass):
"""Test switch updating when off."""
feature_mock, entity_id = switchbox
@ -78,13 +78,13 @@ async def test_switchbox_update_when_off(switchbox, hass, config):
feature_mock.is_on = False
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
async def test_switchbox_update_when_on(switchbox, hass, config):
async def test_switchbox_update_when_on(switchbox, hass):
"""Test switch updating when on."""
feature_mock, entity_id = switchbox
@ -93,13 +93,13 @@ async def test_switchbox_update_when_on(switchbox, hass, config):
feature_mock.is_on = True
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
state = hass.states.get(entity_id)
assert state.state == STATE_ON
async def test_switchbox_on(switchbox, hass, config):
async def test_switchbox_on(switchbox, hass):
"""Test turning switch on."""
feature_mock, entity_id = switchbox
@ -108,7 +108,7 @@ async def test_switchbox_on(switchbox, hass, config):
feature_mock.is_on = False
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
feature_mock.async_update = AsyncMock()
def turn_on():
@ -127,7 +127,7 @@ async def test_switchbox_on(switchbox, hass, config):
assert state.state == STATE_ON
async def test_switchbox_off(switchbox, hass, config):
async def test_switchbox_off(switchbox, hass):
"""Test turning switch off."""
feature_mock, entity_id = switchbox
@ -136,7 +136,7 @@ async def test_switchbox_off(switchbox, hass, config):
feature_mock.is_on = True
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
feature_mock.async_update = AsyncMock()
def turn_off():
@ -188,14 +188,14 @@ def switchbox_d_fixture():
return (features, ["switch.switchboxd_0_relay", "switch.switchboxd_1_relay"])
async def test_switchbox_d_init(switchbox_d, hass, config):
async def test_switchbox_d_init(switchbox_d, hass):
"""Test switch default state."""
feature_mocks, entity_ids = switchbox_d
feature_mocks[0].async_update = AsyncMock()
feature_mocks[1].async_update = AsyncMock()
entries = await async_setup_entities(hass, config, entity_ids)
entries = await async_setup_entities(hass, entity_ids)
entry = entries[0]
assert entry.unique_id == "BleBox-switchBoxD-1afe34e750b8-0.relay"
@ -232,7 +232,7 @@ async def test_switchbox_d_init(switchbox_d, hass, config):
assert device.sw_version == "1.23"
async def test_switchbox_d_update_when_off(switchbox_d, hass, config):
async def test_switchbox_d_update_when_off(switchbox_d, hass):
"""Test switch updating when off."""
feature_mocks, entity_ids = switchbox_d
@ -243,13 +243,13 @@ async def test_switchbox_d_update_when_off(switchbox_d, hass, config):
feature_mocks[0].async_update = AsyncMock(side_effect=initial_update0)
feature_mocks[1].async_update = AsyncMock()
await async_setup_entities(hass, config, entity_ids)
await async_setup_entities(hass, entity_ids)
assert hass.states.get(entity_ids[0]).state == STATE_OFF
assert hass.states.get(entity_ids[1]).state == STATE_OFF
async def test_switchbox_d_update_when_second_off(switchbox_d, hass, config):
async def test_switchbox_d_update_when_second_off(switchbox_d, hass):
"""Test switch updating when off."""
feature_mocks, entity_ids = switchbox_d
@ -260,13 +260,13 @@ async def test_switchbox_d_update_when_second_off(switchbox_d, hass, config):
feature_mocks[0].async_update = AsyncMock(side_effect=initial_update0)
feature_mocks[1].async_update = AsyncMock()
await async_setup_entities(hass, config, entity_ids)
await async_setup_entities(hass, entity_ids)
assert hass.states.get(entity_ids[0]).state == STATE_ON
assert hass.states.get(entity_ids[1]).state == STATE_OFF
async def test_switchbox_d_turn_first_on(switchbox_d, hass, config):
async def test_switchbox_d_turn_first_on(switchbox_d, hass):
"""Test turning switch on."""
feature_mocks, entity_ids = switchbox_d
@ -277,7 +277,7 @@ async def test_switchbox_d_turn_first_on(switchbox_d, hass, config):
feature_mocks[0].async_update = AsyncMock(side_effect=initial_update0)
feature_mocks[1].async_update = AsyncMock()
await async_setup_entities(hass, config, entity_ids)
await async_setup_entities(hass, entity_ids)
feature_mocks[0].async_update = AsyncMock()
def turn_on0():
@ -295,7 +295,7 @@ async def test_switchbox_d_turn_first_on(switchbox_d, hass, config):
assert hass.states.get(entity_ids[1]).state == STATE_OFF
async def test_switchbox_d_second_on(switchbox_d, hass, config):
async def test_switchbox_d_second_on(switchbox_d, hass):
"""Test turning switch on."""
feature_mocks, entity_ids = switchbox_d
@ -306,7 +306,7 @@ async def test_switchbox_d_second_on(switchbox_d, hass, config):
feature_mocks[0].async_update = AsyncMock(side_effect=initial_update0)
feature_mocks[1].async_update = AsyncMock()
await async_setup_entities(hass, config, entity_ids)
await async_setup_entities(hass, entity_ids)
feature_mocks[0].async_update = AsyncMock()
def turn_on1():
@ -324,7 +324,7 @@ async def test_switchbox_d_second_on(switchbox_d, hass, config):
assert hass.states.get(entity_ids[1]).state == STATE_ON
async def test_switchbox_d_first_off(switchbox_d, hass, config):
async def test_switchbox_d_first_off(switchbox_d, hass):
"""Test turning switch on."""
feature_mocks, entity_ids = switchbox_d
@ -335,7 +335,7 @@ async def test_switchbox_d_first_off(switchbox_d, hass, config):
feature_mocks[0].async_update = AsyncMock(side_effect=initial_update_any)
feature_mocks[1].async_update = AsyncMock()
await async_setup_entities(hass, config, entity_ids)
await async_setup_entities(hass, entity_ids)
feature_mocks[0].async_update = AsyncMock()
def turn_off0():
@ -353,7 +353,7 @@ async def test_switchbox_d_first_off(switchbox_d, hass, config):
assert hass.states.get(entity_ids[1]).state == STATE_ON
async def test_switchbox_d_second_off(switchbox_d, hass, config):
async def test_switchbox_d_second_off(switchbox_d, hass):
"""Test turning switch on."""
feature_mocks, entity_ids = switchbox_d
@ -364,7 +364,7 @@ async def test_switchbox_d_second_off(switchbox_d, hass, config):
feature_mocks[0].async_update = AsyncMock(side_effect=initial_update_any)
feature_mocks[1].async_update = AsyncMock()
await async_setup_entities(hass, config, entity_ids)
await async_setup_entities(hass, entity_ids)
feature_mocks[0].async_update = AsyncMock()
def turn_off1():
@ -385,7 +385,7 @@ ALL_SWITCH_FIXTURES = ["switchbox", "switchbox_d"]
@pytest.mark.parametrize("feature", ALL_SWITCH_FIXTURES, indirect=["feature"])
async def test_update_failure(feature, hass, config, caplog):
async def test_update_failure(feature, hass, caplog):
"""Test that update failures are logged."""
caplog.set_level(logging.ERROR)
@ -399,6 +399,6 @@ async def test_update_failure(feature, hass, config, caplog):
entity_id = entity_id[0]
feature_mock.async_update = AsyncMock(side_effect=blebox_uniapi.error.ClientError)
await async_setup_entity(hass, config, entity_id)
await async_setup_entity(hass, entity_id)
assert f"Updating '{feature_mock.full_name}' failed: " in caplog.text