Improve eurotronic_cometblue tests (#168046)

This commit is contained in:
Richard Kroegel
2026-04-13 07:16:22 +02:00
committed by GitHub
parent e5c49b6455
commit a061e47bec
6 changed files with 568 additions and 44 deletions

View File

@@ -1 +1,67 @@
"""Tests for the Eurotronic Comet Blue integration."""
from eurotronic_cometblue_ha import const as cometblue_const
from homeassistant.const import CONF_PIN
FIXTURE_DEVICE_NAME = "Comet Blue"
FIXTURE_MAC = "aa:bb:cc:dd:ee:ff"
FIXTURE_RSSI = -60
FIXTURE_SERVICE_UUID = "47e9ee00-47e9-11e4-8939-164230d1df67"
WRITEABLE_CHARACTERISTICS = [
cometblue_const.CHARACTERISTIC_DATETIME,
cometblue_const.CHARACTERISTIC_MONDAY,
cometblue_const.CHARACTERISTIC_TUESDAY,
cometblue_const.CHARACTERISTIC_WEDNESDAY,
cometblue_const.CHARACTERISTIC_THURSDAY,
cometblue_const.CHARACTERISTIC_FRIDAY,
cometblue_const.CHARACTERISTIC_SATURDAY,
cometblue_const.CHARACTERISTIC_SUNDAY,
cometblue_const.CHARACTERISTIC_HOLIDAY_1,
cometblue_const.CHARACTERISTIC_SETTINGS,
cometblue_const.CHARACTERISTIC_TEMPERATURE,
cometblue_const.CHARACTERISTIC_PIN,
]
WRITEABLE_CHARACTERISTICS_ALLOW_UNCHANGED = [
cometblue_const.CHARACTERISTIC_SETTINGS,
cometblue_const.CHARACTERISTIC_TEMPERATURE,
]
FIXTURE_DEFAULT_CHARACTERISTICS = {
cometblue_const.CHARACTERISTIC_MODEL: b"Comet Blue",
cometblue_const.CHARACTERISTIC_VERSION: b"0.0.10",
cometblue_const.CHARACTERISTIC_MANUFACTURER: b"Eurotronic GmbH",
cometblue_const.CHARACTERISTIC_HOLIDAY_1: [
128,
27,
11,
22,
128,
27,
11,
22,
34,
],
cometblue_const.CHARACTERISTIC_TEMPERATURE: [
41,
40,
34,
42,
0,
4,
10,
],
cometblue_const.CHARACTERISTIC_BATTERY: b"48",
cometblue_const.CHARACTERISTIC_MONDAY: [37, 137, 0, 0, 0, 0, 0, 0],
cometblue_const.CHARACTERISTIC_TUESDAY: [37, 137, 0, 0, 0, 0, 0, 0],
cometblue_const.CHARACTERISTIC_WEDNESDAY: [37, 137, 0, 0, 0, 0, 0, 0],
cometblue_const.CHARACTERISTIC_THURSDAY: [37, 137, 0, 0, 0, 0, 0, 0],
cometblue_const.CHARACTERISTIC_FRIDAY: [0, 1, 10, 20, 21, 130, 140, 143],
cometblue_const.CHARACTERISTIC_SATURDAY: [37, 137, 0, 0, 0, 0, 0, 0],
cometblue_const.CHARACTERISTIC_SUNDAY: [37, 137, 0, 0, 0, 0, 0, 0],
}
FIXTURE_USER_INPUT = {
CONF_PIN: "000000",
}

View File

@@ -1,6 +1,6 @@
"""Session fixtures."""
from collections.abc import Generator
from collections.abc import Buffer, Generator
from typing import Any
from unittest.mock import AsyncMock, patch
import uuid
@@ -12,17 +12,21 @@ from eurotronic_cometblue_ha import CometBlueBleakClient
import pytest
from homeassistant.components.bluetooth import BluetoothServiceInfoBleak
from homeassistant.components.eurotronic_cometblue import PLATFORMS
from homeassistant.components.eurotronic_cometblue.const import DOMAIN
from homeassistant.const import CONF_ADDRESS
from homeassistant.const import CONF_ADDRESS, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import format_mac
from .const import (
from . import (
FIXTURE_DEFAULT_CHARACTERISTICS,
FIXTURE_DEVICE_NAME,
FIXTURE_GATT_CHARACTERISTICS,
FIXTURE_MAC,
FIXTURE_RSSI,
FIXTURE_SERVICE_UUID,
FIXTURE_USER_INPUT,
WRITEABLE_CHARACTERISTICS,
WRITEABLE_CHARACTERISTICS_ALLOW_UNCHANGED,
)
from tests.common import MockConfigEntry
@@ -58,9 +62,24 @@ FAKE_SERVICE_INFO = BluetoothServiceInfoBleak(
)
def _normalize_characteristic(
char_specifier: BleakGATTCharacteristic | int | str | uuid.UUID,
) -> uuid.UUID:
"""Normalize a characteristic specifier to UUID."""
if not isinstance(char_specifier, (BleakGATTCharacteristic, str, uuid.UUID)):
raise BleakCharacteristicNotFoundError(char_specifier)
if isinstance(char_specifier, BleakGATTCharacteristic):
char_specifier = char_specifier.uuid
if not isinstance(char_specifier, uuid.UUID):
char_specifier = uuid.UUID(char_specifier)
return char_specifier
class MockCometBlueBleakClient(CometBlueBleakClient):
"""Mock BleakClient."""
characteristics: dict[uuid.UUID, bytearray] = {}
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""Mock init."""
super().__init__(*args, **kwargs)
@@ -94,17 +113,40 @@ class MockCometBlueBleakClient(CometBlueBleakClient):
**kwargs: Any,
) -> bytearray:
"""Mock read_gatt_char."""
if not isinstance(char_specifier, (BleakGATTCharacteristic, str, uuid.UUID)):
raise BleakCharacteristicNotFoundError(char_specifier)
if isinstance(char_specifier, BleakGATTCharacteristic):
char_specifier = char_specifier.uuid
if not isinstance(char_specifier, uuid.UUID):
char_specifier = uuid.UUID(char_specifier)
char_specifier = _normalize_characteristic(char_specifier)
try:
return FIXTURE_GATT_CHARACTERISTICS[char_specifier]
return bytearray(self.characteristics[char_specifier])
except KeyError:
raise BleakCharacteristicNotFoundError(char_specifier)
async def write_gatt_char(
self,
char_specifier: BleakGATTCharacteristic | int | str | uuid.UUID,
data: Buffer,
response: bool | None = None,
) -> None:
"""Mock write_gatt_char."""
char_specifier = _normalize_characteristic(char_specifier)
if char_specifier not in WRITEABLE_CHARACTERISTICS:
raise BleakCharacteristicNotFoundError(char_specifier)
data = bytearray(data)
# when writing temperature it is possible that 128 will be sent, meaning "no change"
# we have to restore the original value in this case to keep tests working
if char_specifier in WRITEABLE_CHARACTERISTICS_ALLOW_UNCHANGED:
for i, byte in enumerate(data):
if byte == 128:
data[i] = self.characteristics[char_specifier][i]
self.characteristics[char_specifier] = data
@pytest.fixture
def mock_gatt_characteristics() -> dict[uuid.UUID, bytearray]:
"""Provide a mutable per-test GATT characteristic store."""
return {
characteristic: bytearray(value)
for characteristic, value in FIXTURE_DEFAULT_CHARACTERISTICS.items()
}
@pytest.fixture
def mock_service_info() -> Generator[None]:
@@ -133,13 +175,26 @@ def mock_ble_device() -> Generator[None]:
@pytest.fixture(autouse=True)
def mock_bluetooth(enable_bluetooth: None) -> Generator[None]:
def mock_bluetooth(
enable_bluetooth: None,
mock_gatt_characteristics: dict[uuid.UUID, bytearray],
) -> Generator[None]:
"""Auto mock bluetooth."""
with patch(
"eurotronic_cometblue_ha.CometBlueBleakClient", MockCometBlueBleakClient
MockCometBlueBleakClient.characteristics = mock_gatt_characteristics
with (
patch(
"homeassistant.components.eurotronic_cometblue.entity.bluetooth.async_address_present",
return_value=True,
),
patch(
"homeassistant.components.eurotronic_cometblue.coordinator.COMMAND_RETRY_INTERVAL",
0,
),
patch("eurotronic_cometblue_ha.CometBlueBleakClient", MockCometBlueBleakClient),
):
yield
MockCometBlueBleakClient.characteristics = {}
# Home Assistant related fixtures
@@ -164,3 +219,16 @@ def mock_setup_entry() -> Generator[AsyncMock]:
return_value=True,
) as mock_setup:
yield mock_setup
async def setup_with_selected_platforms(
hass: HomeAssistant, entry: MockConfigEntry, platforms: list[Platform] | None = None
) -> None:
"""Set up the Eurotronic Comet Blue integration with the selected platforms."""
entry.add_to_hass(hass)
with patch(
"homeassistant.components.eurotronic_cometblue.PLATFORMS",
platforms or PLATFORMS,
):
assert await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()

View File

@@ -1,29 +0,0 @@
"""Constants for Eurotronic CometBlue tests."""
from uuid import UUID
from homeassistant.const import CONF_PIN
FIXTURE_DEVICE_NAME = "Comet Blue"
FIXTURE_MAC = "aa:bb:cc:dd:ee:ff"
FIXTURE_RSSI = -60
FIXTURE_SERVICE_UUID = "47e9ee00-47e9-11e4-8939-164230d1df67"
FIXTURE_GATT_CHARACTERISTICS = {
UUID("00002a24-0000-1000-8000-00805f9b34fb"): bytearray(b"Comet Blue"), # model
UUID("00002a26-0000-1000-8000-00805f9b34fb"): bytearray(b"0.0.10"), # version
UUID("00002a29-0000-1000-8000-00805f9b34fb"): bytearray(
b"Eurotronic GmbH"
), # manufacturer
UUID("47e9ee20-47e9-11e4-8939-164230d1df67"): bytearray(
b'\x80\x1b\x0b\x16\x80\x1b\x0b\x16"'
), # holiday 1
UUID("47e9ee2b-47e9-11e4-8939-164230d1df67"): bytearray(
b"/999\x00\x04\n"
), # temperature
UUID("47e9ee2c-47e9-11e4-8939-164230d1df67"): bytearray(b"48"), # battery
}
FIXTURE_USER_INPUT = {
CONF_PIN: "000000",
}

View File

@@ -0,0 +1,88 @@
# serializer version: 1
# name: test_climate_state[climate.comet_blue_aa_bb_cc_dd_ee_ff-entry]
EntityRegistryEntrySnapshot({
'aliases': list([
None,
]),
'area_id': None,
'capabilities': dict({
'hvac_modes': list([
<HVACMode.AUTO: 'auto'>,
<HVACMode.HEAT: 'heat'>,
<HVACMode.OFF: 'off'>,
]),
'max_temp': 28.5,
'min_temp': 7.5,
'preset_modes': list([
'comfort',
'eco',
'boost',
'away',
'none',
]),
'target_temp_step': 0.5,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'climate',
'entity_category': None,
'entity_id': 'climate.comet_blue_aa_bb_cc_dd_ee_ff',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': None,
'platform': 'eurotronic_cometblue',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': <ClimateEntityFeature: 403>,
'translation_key': None,
'unique_id': 'aa:bb:cc:dd:ee:ff',
'unit_of_measurement': None,
})
# ---
# name: test_climate_state[climate.comet_blue_aa_bb_cc_dd_ee_ff-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'current_temperature': 20.5,
'friendly_name': 'Comet Blue aa:bb:cc:dd:ee:ff',
'hvac_modes': list([
<HVACMode.AUTO: 'auto'>,
<HVACMode.HEAT: 'heat'>,
<HVACMode.OFF: 'off'>,
]),
'max_temp': 28.5,
'min_temp': 7.5,
'preset_mode': 'none',
'preset_modes': list([
'comfort',
'eco',
'boost',
'away',
'none',
]),
'supported_features': <ClimateEntityFeature: 403>,
'target_temp_high': 21.0,
'target_temp_low': 17.0,
'target_temp_step': 0.5,
'temperature': 20.0,
}),
'context': <ANY>,
'entity_id': 'climate.comet_blue_aa_bb_cc_dd_ee_ff',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'auto',
})
# ---

View File

@@ -0,0 +1,331 @@
"""Test the eurotronic_cometblue climate platform."""
from unittest.mock import patch
import uuid
from eurotronic_cometblue_ha import const as cometblue_const
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.climate import (
ATTR_CURRENT_TEMPERATURE,
ATTR_HVAC_MODE,
ATTR_PRESET_MODE,
DOMAIN as CLIMATE_DOMAIN,
PRESET_AWAY,
PRESET_BOOST,
PRESET_COMFORT,
PRESET_ECO,
PRESET_NONE,
SERVICE_SET_HVAC_MODE,
SERVICE_SET_PRESET_MODE,
SERVICE_SET_TEMPERATURE,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
HVACMode,
)
from homeassistant.components.eurotronic_cometblue.climate import MAX_TEMP, MIN_TEMP
from homeassistant.const import ATTR_ENTITY_ID, ATTR_TEMPERATURE, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.helpers import entity_registry as er
from .conftest import setup_with_selected_platforms
from tests.common import MockConfigEntry, snapshot_platform
ENTITY_ID = "climate.comet_blue_aa_bb_cc_dd_ee_ff"
async def test_climate_state(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test climate entity state and registry data."""
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
@pytest.mark.parametrize(
("temperature_values", "expected_hvac_mode", "expected_preset"),
[
([47, 15, 34, 42, 0, 4, 10], HVACMode.OFF, PRESET_NONE),
([47, 40, 34, 42, 0, 4, 10], HVACMode.AUTO, PRESET_NONE),
([47, 42, 34, 42, 0, 4, 10], HVACMode.AUTO, PRESET_COMFORT),
([47, 34, 34, 42, 0, 4, 10], HVACMode.AUTO, PRESET_ECO),
([47, 57, 57, 57, 0, 4, 10], HVACMode.HEAT, PRESET_BOOST),
],
)
async def test_climate_hvac_and_preset_states(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_gatt_characteristics: dict[uuid.UUID, bytearray],
temperature_values: list[int],
expected_hvac_mode: HVACMode,
expected_preset: str,
) -> None:
"""Test climate state mapping from device temperatures."""
mock_gatt_characteristics[cometblue_const.CHARACTERISTIC_TEMPERATURE] = bytearray(
temperature_values
)
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
assert (state := hass.states.get(ENTITY_ID))
assert state.state == expected_hvac_mode
assert state.attributes[ATTR_PRESET_MODE] == expected_preset
async def test_set_temperature(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test setting target temperature."""
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
assert (state := hass.states.get(ENTITY_ID))
assert state.attributes[ATTR_TEMPERATURE] == 20.0
assert state.attributes[ATTR_CURRENT_TEMPERATURE] == 20.5
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_TEMPERATURE,
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_TEMPERATURE: 21.0},
blocking=True,
)
assert (state := hass.states.get(ENTITY_ID))
assert state.attributes[ATTR_TEMPERATURE] == 21.0
assert state.attributes[ATTR_CURRENT_TEMPERATURE] == 20.5
async def test_climate_preset_away_active(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_gatt_characteristics: dict[uuid.UUID, bytearray],
) -> None:
"""Test away preset detection from holiday data."""
# Holiday active if start hour >= 128 and end hour < 128
mock_gatt_characteristics[cometblue_const.CHARACTERISTIC_HOLIDAY_1] = bytearray(
[128, 1, 1, 26, 10, 2, 1, 26, 34]
)
# Current target temperature must match holiday temperature for away preset to be active
mock_gatt_characteristics[cometblue_const.CHARACTERISTIC_TEMPERATURE] = bytearray(
[47, 34, 34, 42, 0, 4, 10]
)
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
assert (state := hass.states.get(ENTITY_ID))
assert state.attributes[ATTR_PRESET_MODE] == PRESET_AWAY
with pytest.raises(
ServiceValidationError,
match="Cannot adjust TRV remotely",
):
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_TEMPERATURE,
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_TEMPERATURE: 21.0},
blocking=True,
)
@pytest.mark.parametrize(
("preset_mode", "expected_temperature", "expected_state"),
[
(PRESET_ECO, 17.0, HVACMode.AUTO),
(PRESET_COMFORT, 21.0, HVACMode.AUTO),
(PRESET_BOOST, MAX_TEMP, HVACMode.HEAT),
],
)
async def test_set_preset_mode(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
preset_mode: str,
expected_temperature: float,
expected_state: HVACMode,
) -> None:
"""Test setting preset modes."""
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_PRESET_MODE,
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_PRESET_MODE: preset_mode},
blocking=True,
)
assert (state := hass.states.get(ENTITY_ID))
assert state.attributes[ATTR_TEMPERATURE] == expected_temperature
assert state.attributes[ATTR_PRESET_MODE] == preset_mode
assert state.state == expected_state
@pytest.mark.parametrize("preset_mode", [PRESET_NONE, PRESET_AWAY])
async def test_set_preset_mode_display_only_raises(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
preset_mode: str,
) -> None:
"""Test display-only presets cannot be set."""
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
with pytest.raises(ServiceValidationError, match="Unable to set preset"):
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_PRESET_MODE,
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_PRESET_MODE: preset_mode},
blocking=True,
)
@pytest.mark.parametrize(
("hvac_mode", "expected_temperature", "expected_preset"),
[
(HVACMode.OFF, MIN_TEMP, PRESET_NONE),
(HVACMode.HEAT, MAX_TEMP, PRESET_BOOST),
(HVACMode.AUTO, 17.0, PRESET_ECO),
],
)
async def test_set_hvac_mode(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
hvac_mode: HVACMode,
expected_temperature: float,
expected_preset: str,
) -> None:
"""Test setting HVAC modes."""
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_HVAC_MODE,
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_HVAC_MODE: hvac_mode},
blocking=True,
)
assert (state := hass.states.get(ENTITY_ID))
assert state.attributes[ATTR_TEMPERATURE] == expected_temperature
assert state.attributes[ATTR_PRESET_MODE] == expected_preset
assert state.state == hvac_mode
@pytest.mark.parametrize(
("service", "expected_temperature"),
[
(SERVICE_TURN_OFF, MIN_TEMP),
(SERVICE_TURN_ON, 17.0),
],
)
async def test_turn_on_turn_off(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
service: str,
expected_temperature: float,
) -> None:
"""Test turn_on and turn_off services."""
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
assert (state := hass.states.get(ENTITY_ID))
assert state.attributes[ATTR_TEMPERATURE] == 20.0
await hass.services.async_call(
CLIMATE_DOMAIN,
service,
{ATTR_ENTITY_ID: ENTITY_ID},
blocking=True,
)
assert (state := hass.states.get(ENTITY_ID))
assert state.attributes[ATTR_TEMPERATURE] == expected_temperature
@pytest.mark.parametrize(
("raise_exception", "raised_exception"),
[
(TimeoutError, HomeAssistantError),
(ValueError, ServiceValidationError),
],
)
async def test_set_temperature_errors(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
raise_exception: type[Exception],
raised_exception: type[Exception],
) -> None:
"""Test setting target temperature."""
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
# raise exceptions to test error handling
with (
pytest.raises(raised_exception),
patch(
"homeassistant.components.eurotronic_cometblue.coordinator.AsyncCometBlue.set_temperature_async",
side_effect=raise_exception(),
),
):
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_TEMPERATURE,
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_TEMPERATURE: 21.0},
blocking=True,
)
async def test_update_data_error_handling(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test that update data errors are handled and retried."""
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
assert (state := hass.states.get(ENTITY_ID))
assert state.attributes[ATTR_TEMPERATURE] == 20.0
# Fail with TimeoutError (expected) and raise UpdateFailed after 3 retries
with patch.object(
mock_config_entry.runtime_data.device,
"get_temperature_async",
side_effect=TimeoutError(),
) as mock_get_temperature:
await mock_config_entry.runtime_data.async_refresh()
await hass.async_block_till_done()
assert mock_get_temperature.call_count == 3
assert mock_config_entry.runtime_data.last_update_success is False
assert (state := hass.states.get(ENTITY_ID))
assert state.attributes[ATTR_TEMPERATURE] == 20.0
# Fail with OSError (unexpected) and raise UpdateFailed directly
with patch.object(
mock_config_entry.runtime_data.device,
"get_temperature_async",
side_effect=OSError(),
) as mock_get_temperature:
await mock_config_entry.runtime_data.async_refresh()
await hass.async_block_till_done()
assert mock_get_temperature.call_count == 1
assert mock_config_entry.runtime_data.last_update_success is False
assert (state := hass.states.get(ENTITY_ID))
assert state.attributes[ATTR_TEMPERATURE] == 20.0
# Fail once with TimeoutError and then succeed, verify that data is updated
updated_temperatures = dict(mock_config_entry.runtime_data.data.temperatures)
updated_temperatures["manualTemp"] = 27.0
with patch.object(
mock_config_entry.runtime_data.device,
"get_temperature_async",
side_effect=[TimeoutError(), updated_temperatures],
) as mock_get_temperature:
await mock_config_entry.runtime_data.async_refresh()
await hass.async_block_till_done()
assert mock_get_temperature.call_count == 2
assert mock_config_entry.runtime_data.last_update_success is True
assert (state := hass.states.get(ENTITY_ID))
assert state.attributes[ATTR_TEMPERATURE] == 27.0

View File

@@ -16,8 +16,8 @@ from homeassistant.const import CONF_ADDRESS, CONF_PIN
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from . import FIXTURE_DEVICE_NAME, FIXTURE_MAC, FIXTURE_USER_INPUT
from .conftest import FAKE_SERVICE_INFO
from .const import FIXTURE_DEVICE_NAME, FIXTURE_MAC, FIXTURE_USER_INPUT
from tests.common import MockConfigEntry