mirror of
https://github.com/home-assistant/core.git
synced 2026-06-11 19:51:39 +02:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 30d8bf4231 | |||
| 5436d8af9b | |||
| 88adf39ef3 | |||
| 14b14bddf1 | |||
| 3c4a30be6b | |||
| 2988eb4b19 | |||
| 00eef14558 | |||
| d02516dd09 | |||
| aabb6b3d04 | |||
| 50c2c7c4bc | |||
| e81dd426bb | |||
| c4c569c181 | |||
| 6182426132 | |||
| a073cc4f7d | |||
| 07ddc08d84 | |||
| 17673dcf55 | |||
| a864bc1c80 | |||
| a15d80daa2 | |||
| e123b29258 | |||
| 5669a7b602 | |||
| fe358a4a1f | |||
| 3a93d6370b | |||
| 89576f01e6 | |||
| f51895b0c9 | |||
| d0dcbfadaa | |||
| 5e0d3627c2 | |||
| 80c90732a3 | |||
| 16eca3909a | |||
| 1b471da31f |
@@ -1326,7 +1326,7 @@ jobs:
|
||||
pattern: coverage-*
|
||||
- name: Upload coverage to Codecov
|
||||
if: needs.info.outputs.test_full_suite == 'true'
|
||||
uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1
|
||||
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
||||
with:
|
||||
fail_ci_if_error: true
|
||||
flags: full-suite
|
||||
@@ -1485,7 +1485,7 @@ jobs:
|
||||
pattern: coverage-*
|
||||
- name: Upload coverage to Codecov
|
||||
if: needs.info.outputs.test_full_suite == 'false'
|
||||
uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1
|
||||
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
||||
with:
|
||||
fail_ci_if_error: true
|
||||
token: ${{ secrets.CODECOV_TOKEN }} # zizmor: ignore[secrets-outside-env]
|
||||
@@ -1513,7 +1513,7 @@ jobs:
|
||||
with:
|
||||
pattern: test-results-*
|
||||
- name: Upload test results to Codecov
|
||||
uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1
|
||||
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
||||
with:
|
||||
report_type: test_results
|
||||
fail_ci_if_error: true
|
||||
|
||||
@@ -6,7 +6,7 @@ from homeassistant.helpers.entity import EntityDescription
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.util import slugify
|
||||
|
||||
from .coordinator import AmazonConfigEntry, AmazonDevicesCoordinator
|
||||
from .coordinator import AmazonConfigEntry, AmazonDevicesCoordinator, alexa_api_call
|
||||
from .entity import AmazonServiceEntity
|
||||
|
||||
# Coordinator is used to centralize the data updates
|
||||
@@ -49,4 +49,5 @@ class AmazonRoutineButton(AmazonServiceEntity, ButtonEntity):
|
||||
|
||||
async def async_press(self) -> None:
|
||||
"""Handle button press action."""
|
||||
await self.coordinator.api.call_routine(self._routine)
|
||||
async with alexa_api_call(self.coordinator):
|
||||
await self.coordinator.api.call_routine(self._routine)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""Support for Alexa Devices."""
|
||||
|
||||
from collections.abc import AsyncGenerator
|
||||
from contextlib import asynccontextmanager
|
||||
from datetime import timedelta
|
||||
|
||||
from aioamazondevices.api import AmazonEchoApi
|
||||
@@ -19,7 +21,11 @@ from aiohttp import ClientSession
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||
from homeassistant.exceptions import (
|
||||
ConfigEntryAuthFailed,
|
||||
ConfigEntryNotReady,
|
||||
HomeAssistantError,
|
||||
)
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.helpers.debounce import Debouncer
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
@@ -29,6 +35,65 @@ from .const import _LOGGER, CONF_LOGIN_DATA, DOMAIN
|
||||
|
||||
SCAN_INTERVAL = 300
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def alexa_api_call(
|
||||
coordinator: DataUpdateCoordinator | None = None,
|
||||
) -> AsyncGenerator[None]:
|
||||
"""Handle common Alexa API exceptions as HomeAssistantError."""
|
||||
try:
|
||||
yield
|
||||
except CannotAuthenticate as err:
|
||||
if coordinator:
|
||||
coordinator.last_update_success = False
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="invalid_auth",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
except CannotConnect as err:
|
||||
if coordinator:
|
||||
coordinator.last_update_success = False
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_connect_with_error",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
except (CannotRetrieveData, ValueError) as err:
|
||||
if coordinator:
|
||||
coordinator.last_update_success = False
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_retrieve_data_with_error",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def alexa_config_entry_errors() -> AsyncGenerator[None]:
|
||||
"""Handle common Alexa API exceptions as ConfigEntry errors."""
|
||||
try:
|
||||
yield
|
||||
except CannotAuthenticate as err:
|
||||
raise ConfigEntryAuthFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="invalid_auth",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
except (CannotConnect, TimeoutError) as err:
|
||||
raise ConfigEntryNotReady(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_connect_with_error",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
except (CannotRetrieveData, ValueError, KeyError, StopIteration) as err:
|
||||
raise ConfigEntryNotReady(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_retrieve_data_with_error",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
|
||||
|
||||
type AmazonConfigEntry = ConfigEntry[AmazonDevicesCoordinator]
|
||||
|
||||
|
||||
@@ -113,6 +178,12 @@ class AmazonDevicesCoordinator(DataUpdateCoordinator[dict[str, AmazonDevice]]):
|
||||
translation_key="invalid_auth",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
except ValueError as err:
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_retrieve_data_with_error",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
else:
|
||||
current_devices = set(data.keys())
|
||||
if stale_devices := self.previous_devices - current_devices:
|
||||
@@ -169,26 +240,8 @@ class AmazonDevicesCoordinator(DataUpdateCoordinator[dict[str, AmazonDevice]]):
|
||||
|
||||
async def sync_history_state(self) -> None:
|
||||
"""Sync history state."""
|
||||
try:
|
||||
async with alexa_config_entry_errors():
|
||||
self._vocal_records = await self.api.sync_history_state()
|
||||
except CannotAuthenticate as e:
|
||||
raise ConfigEntryAuthFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="invalid_auth",
|
||||
translation_placeholders={"error": repr(e)},
|
||||
) from e
|
||||
except CannotConnect as e:
|
||||
raise ConfigEntryNotReady(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_connect_with_error",
|
||||
translation_placeholders={"error": repr(e)},
|
||||
) from e
|
||||
except BaseException as e:
|
||||
raise ConfigEntryNotReady(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_retrieve_data_with_error",
|
||||
translation_placeholders={"error": repr(e)},
|
||||
) from e
|
||||
|
||||
async def history_state_event_handler(
|
||||
self, vocal_records: dict[str, AmazonVocalRecord]
|
||||
@@ -204,26 +257,8 @@ class AmazonDevicesCoordinator(DataUpdateCoordinator[dict[str, AmazonDevice]]):
|
||||
|
||||
async def sync_media_state(self) -> None:
|
||||
"""Sync media state."""
|
||||
try:
|
||||
async with alexa_config_entry_errors():
|
||||
await self.api.sync_media_state()
|
||||
except CannotAuthenticate as err:
|
||||
raise ConfigEntryAuthFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="invalid_auth",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
except (CannotConnect, TimeoutError) as err:
|
||||
raise ConfigEntryNotReady(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_connect_with_error",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
except (CannotRetrieveData, ValueError) as err:
|
||||
raise ConfigEntryNotReady(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_retrieve_data_with_error",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
|
||||
async def media_state_event_handler(
|
||||
self, media_state: dict[str, AmazonMediaState]
|
||||
|
||||
@@ -22,9 +22,8 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .const import _LOGGER
|
||||
from .coordinator import AmazonConfigEntry, AmazonDevicesCoordinator
|
||||
from .coordinator import AmazonConfigEntry, AmazonDevicesCoordinator, alexa_api_call
|
||||
from .entity import AmazonEntity
|
||||
from .utils import alexa_api_call
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
|
||||
@@ -216,16 +215,15 @@ class AlexaDevicesMediaPlayer(AmazonEntity, MediaPlayerEntity):
|
||||
provider = media_type.value if isinstance(media_type, MediaType) else media_type
|
||||
await self.async_call_alexa_music(media_id, provider)
|
||||
|
||||
@alexa_api_call
|
||||
async def async_call_alexa_music(
|
||||
self, search_phrase: str, provider_id: str
|
||||
) -> None:
|
||||
"""Call alexa music."""
|
||||
await self.coordinator.api.call_alexa_music(
|
||||
self.device, search_phrase, provider_id
|
||||
)
|
||||
async with alexa_api_call(self.coordinator):
|
||||
await self.coordinator.api.call_alexa_music(
|
||||
self.device, search_phrase, provider_id
|
||||
)
|
||||
|
||||
@alexa_api_call
|
||||
async def async_set_device_volume(self, volume: int) -> None:
|
||||
"""Set the device volume."""
|
||||
_LOGGER.debug(
|
||||
@@ -233,7 +231,8 @@ class AlexaDevicesMediaPlayer(AmazonEntity, MediaPlayerEntity):
|
||||
self.device.serial_number,
|
||||
volume,
|
||||
)
|
||||
await self.coordinator.api.set_device_volume(self.device, volume)
|
||||
async with alexa_api_call(self.coordinator):
|
||||
await self.coordinator.api.set_device_volume(self.device, volume)
|
||||
|
||||
async def async_set_volume_level(self, volume: float) -> None:
|
||||
"""Set the volume level (0.0 to 1.0)."""
|
||||
@@ -263,12 +262,12 @@ class AlexaDevicesMediaPlayer(AmazonEntity, MediaPlayerEntity):
|
||||
await self.async_set_volume_level(target_volume / 100)
|
||||
self._prev_volume = None
|
||||
|
||||
@alexa_api_call
|
||||
async def _send_media_command(self, command: AmazonMediaControls) -> None:
|
||||
_LOGGER.debug(
|
||||
"Sending media command '%s' to %s", command, self.device.serial_number
|
||||
)
|
||||
await self.coordinator.api.send_media_command(self.device, command)
|
||||
async with alexa_api_call(self.coordinator):
|
||||
await self.coordinator.api.send_media_command(self.device, command)
|
||||
|
||||
async def async_media_stop(self) -> None:
|
||||
"""Send stop command."""
|
||||
|
||||
@@ -12,9 +12,8 @@ from homeassistant.components.notify import NotifyEntity, NotifyEntityDescriptio
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .coordinator import AmazonConfigEntry
|
||||
from .coordinator import AmazonConfigEntry, alexa_api_call
|
||||
from .entity import AmazonEntity
|
||||
from .utils import alexa_api_call
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
|
||||
@@ -80,10 +79,11 @@ class AmazonNotifyEntity(AmazonEntity, NotifyEntity):
|
||||
|
||||
entity_description: AmazonNotifyEntityDescription
|
||||
|
||||
@alexa_api_call
|
||||
async def async_send_message(
|
||||
self, message: str, title: str | None = None, **kwargs: Any
|
||||
) -> None:
|
||||
"""Send a message."""
|
||||
|
||||
await self.entity_description.method(self.coordinator.api, self.device, message)
|
||||
async with alexa_api_call(self.coordinator):
|
||||
await self.entity_description.method(
|
||||
self.coordinator.api, self.device, message
|
||||
)
|
||||
|
||||
@@ -11,7 +11,7 @@ from homeassistant.exceptions import ServiceValidationError
|
||||
from homeassistant.helpers import config_validation as cv, device_registry as dr
|
||||
|
||||
from .const import DOMAIN, INFO_SKILLS_MAPPING
|
||||
from .coordinator import AmazonConfigEntry
|
||||
from .coordinator import AmazonConfigEntry, alexa_api_call
|
||||
|
||||
ATTR_TEXT_COMMAND = "text_command"
|
||||
ATTR_SOUND = "sound"
|
||||
@@ -85,13 +85,15 @@ async def _async_execute_action(call: ServiceCall, attribute: str) -> None:
|
||||
translation_key="invalid_sound_value",
|
||||
translation_placeholders={"sound": value},
|
||||
)
|
||||
await coordinator.api.call_alexa_sound(
|
||||
coordinator.data[device.serial_number], value
|
||||
)
|
||||
async with alexa_api_call():
|
||||
await coordinator.api.call_alexa_sound(
|
||||
coordinator.data[device.serial_number], value
|
||||
)
|
||||
elif attribute == ATTR_TEXT_COMMAND:
|
||||
await coordinator.api.call_alexa_text_command(
|
||||
coordinator.data[device.serial_number], value
|
||||
)
|
||||
async with alexa_api_call():
|
||||
await coordinator.api.call_alexa_text_command(
|
||||
coordinator.data[device.serial_number], value
|
||||
)
|
||||
elif attribute == ATTR_INFO_SKILL:
|
||||
info_skill = INFO_SKILLS_MAPPING.get(value)
|
||||
if info_skill not in ALEXA_INFO_SKILLS:
|
||||
@@ -100,9 +102,10 @@ async def _async_execute_action(call: ServiceCall, attribute: str) -> None:
|
||||
translation_key="invalid_info_skill_value",
|
||||
translation_placeholders={"info_skill": value},
|
||||
)
|
||||
await coordinator.api.call_alexa_info_skill(
|
||||
coordinator.data[device.serial_number], info_skill
|
||||
)
|
||||
async with alexa_api_call():
|
||||
await coordinator.api.call_alexa_info_skill(
|
||||
coordinator.data[device.serial_number], info_skill
|
||||
)
|
||||
|
||||
|
||||
async def async_send_sound_notification(call: ServiceCall) -> None:
|
||||
|
||||
@@ -14,13 +14,9 @@ from homeassistant.components.switch import (
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .coordinator import AmazonConfigEntry
|
||||
from .coordinator import AmazonConfigEntry, alexa_api_call
|
||||
from .entity import AmazonEntity
|
||||
from .utils import (
|
||||
alexa_api_call,
|
||||
async_remove_dnd_from_virtual_group,
|
||||
async_update_unique_id,
|
||||
)
|
||||
from .utils import async_remove_dnd_from_virtual_group, async_update_unique_id
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
|
||||
@@ -90,7 +86,6 @@ class AmazonSwitchEntity(AmazonEntity, SwitchEntity):
|
||||
|
||||
entity_description: AmazonSwitchEntityDescription
|
||||
|
||||
@alexa_api_call
|
||||
async def _switch_set_state(self, state: bool) -> None:
|
||||
"""Set desired switch state."""
|
||||
method = getattr(self.coordinator.api, self.entity_description.method)
|
||||
@@ -98,7 +93,8 @@ class AmazonSwitchEntity(AmazonEntity, SwitchEntity):
|
||||
if TYPE_CHECKING:
|
||||
assert method is not None
|
||||
|
||||
await method(self.device, state)
|
||||
async with alexa_api_call(self.coordinator):
|
||||
await method(self.device, state)
|
||||
self.coordinator.data[self.device.serial_number].sensors[
|
||||
self.entity_description.key
|
||||
].value = state
|
||||
|
||||
@@ -1,54 +1,19 @@
|
||||
"""Utils for Alexa Devices."""
|
||||
|
||||
from collections.abc import Awaitable, Callable, Coroutine
|
||||
from functools import wraps
|
||||
from typing import Any, Concatenate
|
||||
|
||||
from aioamazondevices.const.devices import SPEAKER_GROUP_FAMILY
|
||||
from aioamazondevices.const.schedules import (
|
||||
NOTIFICATION_ALARM,
|
||||
NOTIFICATION_REMINDER,
|
||||
NOTIFICATION_TIMER,
|
||||
)
|
||||
from aioamazondevices.exceptions import CannotConnect, CannotRetrieveData
|
||||
|
||||
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
import homeassistant.helpers.entity_registry as er
|
||||
|
||||
from .const import _LOGGER, DOMAIN
|
||||
from .coordinator import AmazonDevicesCoordinator
|
||||
from .entity import AmazonEntity
|
||||
|
||||
|
||||
def alexa_api_call[_T: AmazonEntity, **_P](
|
||||
func: Callable[Concatenate[_T, _P], Awaitable[None]],
|
||||
) -> Callable[Concatenate[_T, _P], Coroutine[Any, Any, None]]:
|
||||
"""Catch Alexa API call exceptions."""
|
||||
|
||||
@wraps(func)
|
||||
async def cmd_wrapper(self: _T, *args: _P.args, **kwargs: _P.kwargs) -> None:
|
||||
"""Wrap all command methods."""
|
||||
try:
|
||||
await func(self, *args, **kwargs)
|
||||
except CannotConnect as err:
|
||||
self.coordinator.last_update_success = False
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_connect_with_error",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
except CannotRetrieveData as err:
|
||||
self.coordinator.last_update_success = False
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_retrieve_data_with_error",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
|
||||
return cmd_wrapper
|
||||
|
||||
|
||||
async def async_update_unique_id(
|
||||
|
||||
@@ -1816,6 +1816,11 @@ class PipelineInput:
|
||||
await self.run.text_to_speech(tts_input)
|
||||
|
||||
except PipelineError as err:
|
||||
if self.run.tts_stream:
|
||||
# Clean up TTS stream
|
||||
self.run.tts_stream.delete()
|
||||
self.run.tts_stream = None
|
||||
|
||||
self.run.process_event(
|
||||
PipelineEvent(
|
||||
PipelineEventType.ERROR,
|
||||
@@ -1885,15 +1890,17 @@ class PipelineInput:
|
||||
):
|
||||
prepare_tasks.append(self.run.prepare_recognize_intent(self.session))
|
||||
|
||||
if prepare_tasks:
|
||||
await asyncio.gather(*prepare_tasks)
|
||||
|
||||
# Do TTS prepare separately so we don't create a ResultStream if the
|
||||
# pipeline is invalid.
|
||||
if (
|
||||
start_stage_index
|
||||
<= PIPELINE_STAGE_ORDER.index(PipelineStage.TTS)
|
||||
<= end_stage_index
|
||||
):
|
||||
prepare_tasks.append(self.run.prepare_text_to_speech())
|
||||
|
||||
if prepare_tasks:
|
||||
await asyncio.gather(*prepare_tasks)
|
||||
await self.run.prepare_text_to_speech()
|
||||
|
||||
|
||||
class PipelinePreferred(CollectionError):
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["pydaikin"],
|
||||
"requirements": ["pydaikin==2.17.2"],
|
||||
"requirements": ["pydaikin==2.18.1"],
|
||||
"zeroconf": ["_dkapi._tcp.local."]
|
||||
}
|
||||
|
||||
@@ -166,6 +166,8 @@ class RuntimeEntryData:
|
||||
)
|
||||
loaded_platforms: set[Platform] = field(default_factory=set)
|
||||
platform_load_lock: asyncio.Lock = field(default_factory=asyncio.Lock)
|
||||
# Set once the first connection has finished scanner setup or teardown.
|
||||
first_connect_done: asyncio.Event = field(default_factory=asyncio.Event)
|
||||
_storage_contents: StoreData | None = None
|
||||
_pending_storage: Callable[[], StoreData] | None = None
|
||||
assist_pipeline_update_callbacks: list[CALLBACK_TYPE] = field(default_factory=list)
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
"""Manager for esphome devices."""
|
||||
|
||||
import asyncio
|
||||
import base64
|
||||
from functools import partial
|
||||
import logging
|
||||
import secrets
|
||||
import struct
|
||||
from typing import TYPE_CHECKING, Any, NamedTuple
|
||||
from typing import TYPE_CHECKING, Any, Final, NamedTuple
|
||||
|
||||
from aioesphomeapi import (
|
||||
APIClient,
|
||||
@@ -106,6 +107,9 @@ if TYPE_CHECKING:
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
# Max time to wait at startup for a BLE proxy to register its scanner.
|
||||
STARTUP_SCANNER_WAIT: Final = 3.0
|
||||
|
||||
LOG_LEVEL_TO_LOGGER = {
|
||||
LogLevel.LOG_LEVEL_NONE: logging.DEBUG,
|
||||
LogLevel.LOG_LEVEL_ERROR: logging.ERROR,
|
||||
@@ -677,6 +681,8 @@ class ESPHomeManager:
|
||||
hass, device_info.bluetooth_mac_address or device_info.mac_address
|
||||
)
|
||||
|
||||
entry_data.first_connect_done.set()
|
||||
|
||||
if device_info.voice_assistant_feature_flags_compat(api_version) and (
|
||||
Platform.ASSIST_SATELLITE not in entry_data.loaded_platforms
|
||||
):
|
||||
@@ -988,6 +994,21 @@ class ESPHomeManager:
|
||||
|
||||
await reconnect_logic.start()
|
||||
|
||||
# Wait for a cached BLE proxy to register its scanner before finishing setup.
|
||||
if (
|
||||
device_info := entry_data.device_info
|
||||
) is not None and device_info.bluetooth_proxy_feature_flags_compat(
|
||||
entry_data.api_version
|
||||
):
|
||||
try:
|
||||
async with asyncio.timeout(STARTUP_SCANNER_WAIT):
|
||||
await entry_data.first_connect_done.wait()
|
||||
except TimeoutError:
|
||||
_LOGGER.debug(
|
||||
"%s: Timed out waiting for Bluetooth scanner to register",
|
||||
self.host,
|
||||
)
|
||||
|
||||
|
||||
@callback
|
||||
def _async_setup_device_registry(
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
"integration_type": "system",
|
||||
"preview_features": { "winter_mode": {} },
|
||||
"quality_scale": "internal",
|
||||
"requirements": ["home-assistant-frontend==20260527.4"]
|
||||
"requirements": ["home-assistant-frontend==20260527.5"]
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
"""The Gardena Bluetooth integration."""
|
||||
|
||||
from contextlib import suppress
|
||||
import logging
|
||||
|
||||
from bleak.backends.device import BLEDevice
|
||||
from gardena_bluetooth.client import CachedConnection, Client
|
||||
from gardena_bluetooth.const import ProductType
|
||||
from gardena_bluetooth.scan import async_get_manufacturer_data
|
||||
from gardena_bluetooth.const import ScanService
|
||||
from gardena_bluetooth.parse import ManufacturerData, ProductType
|
||||
from habluetooth import BluetoothServiceInfoBleak
|
||||
|
||||
from homeassistant.components import bluetooth
|
||||
from homeassistant.const import CONF_ADDRESS, Platform
|
||||
@@ -30,6 +32,64 @@ PLATFORMS: list[Platform] = [
|
||||
]
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
DISCONNECT_DELAY = 5
|
||||
PRODUCTS_SCAN_TIMEOUT = 10
|
||||
PRODUCT_TYPE_TIMEOUT = 30
|
||||
|
||||
|
||||
async def async_get_product_type(hass: HomeAssistant, address: str) -> ProductType:
|
||||
"""Get a product type for the given address."""
|
||||
|
||||
data = ManufacturerData()
|
||||
|
||||
def _data_callback(info: BluetoothServiceInfoBleak) -> bool:
|
||||
LOGGER.debug("Processing advertisement from %s: %s", info.address, info)
|
||||
if info.device.address != address:
|
||||
return False
|
||||
|
||||
data.update(info.manufacturer_data.get(ManufacturerData.company, b""))
|
||||
return data.product_type is not ProductType.UNKNOWN
|
||||
|
||||
with suppress(TimeoutError):
|
||||
await bluetooth.async_process_advertisements(
|
||||
hass,
|
||||
_data_callback,
|
||||
bluetooth.BluetoothCallbackMatcher(
|
||||
address=address, manufacturer_id=ManufacturerData.company
|
||||
),
|
||||
mode=bluetooth.BluetoothScanningMode.ACTIVE,
|
||||
timeout=PRODUCT_TYPE_TIMEOUT,
|
||||
)
|
||||
return data.product_type
|
||||
|
||||
|
||||
async def async_get_products(hass: HomeAssistant) -> dict[str, ManufacturerData]:
|
||||
"""Get all products that are currently advertising."""
|
||||
products: dict[str, ManufacturerData] = {}
|
||||
|
||||
def _data_callback(info: BluetoothServiceInfoBleak) -> bool:
|
||||
LOGGER.debug("Processing advertisement from %s: %s", info.address, info)
|
||||
if ScanService not in info.service_uuids:
|
||||
return False
|
||||
|
||||
raw = info.manufacturer_data.get(ManufacturerData.company, b"")
|
||||
if (data := products.get(info.device.address)) is None:
|
||||
data = ManufacturerData()
|
||||
products[info.device.address] = data
|
||||
|
||||
data.update(raw)
|
||||
return False
|
||||
|
||||
with suppress(TimeoutError):
|
||||
await bluetooth.async_process_advertisements(
|
||||
hass,
|
||||
_data_callback,
|
||||
bluetooth.BluetoothCallbackMatcher(
|
||||
manufacturer_id=ManufacturerData.company
|
||||
),
|
||||
mode=bluetooth.BluetoothScanningMode.ACTIVE,
|
||||
timeout=PRODUCTS_SCAN_TIMEOUT,
|
||||
)
|
||||
return products
|
||||
|
||||
|
||||
def get_connection(hass: HomeAssistant, address: str) -> CachedConnection:
|
||||
@@ -53,12 +113,7 @@ async def async_setup_entry(
|
||||
|
||||
address = entry.data[CONF_ADDRESS]
|
||||
|
||||
try:
|
||||
mfg_data = await async_get_manufacturer_data({address})
|
||||
except TimeoutError as exc:
|
||||
raise ConfigEntryNotReady("Unable to find product type") from exc
|
||||
|
||||
product_type = mfg_data[address].product_type
|
||||
product_type = await async_get_product_type(hass, address)
|
||||
if product_type is ProductType.UNKNOWN:
|
||||
raise ConfigEntryNotReady("Unable to find product type")
|
||||
|
||||
|
||||
@@ -4,21 +4,17 @@ import logging
|
||||
from typing import Any
|
||||
|
||||
from gardena_bluetooth.client import Client
|
||||
from gardena_bluetooth.const import PRODUCT_NAMES, DeviceInformation, ScanService
|
||||
from gardena_bluetooth.const import PRODUCT_NAMES, DeviceInformation
|
||||
from gardena_bluetooth.exceptions import CharacteristicNotFound, CommunicationFailure
|
||||
from gardena_bluetooth.parse import ManufacturerData, ProductType
|
||||
from gardena_bluetooth.scan import async_get_manufacturer_data
|
||||
from gardena_bluetooth.parse import ProductType
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.bluetooth import (
|
||||
BluetoothServiceInfo,
|
||||
async_discovered_service_info,
|
||||
)
|
||||
from homeassistant.components.bluetooth import BluetoothServiceInfo
|
||||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
||||
from homeassistant.const import CONF_ADDRESS
|
||||
from homeassistant.data_entry_flow import AbortFlow
|
||||
|
||||
from . import get_connection
|
||||
from . import async_get_product_type, async_get_products, get_connection
|
||||
from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@@ -33,17 +29,6 @@ _SUPPORTED_PRODUCT_TYPES = {
|
||||
}
|
||||
|
||||
|
||||
def _is_supported(discovery_info: BluetoothServiceInfo):
|
||||
"""Check if device is supported."""
|
||||
if ScanService not in discovery_info.service_uuids:
|
||||
return False
|
||||
|
||||
if discovery_info.manufacturer_data.get(ManufacturerData.company) is None:
|
||||
_LOGGER.debug("Missing manufacturer data: %s", discovery_info)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class GardenaBluetoothConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a config flow for Gardena Bluetooth."""
|
||||
|
||||
@@ -75,8 +60,7 @@ class GardenaBluetoothConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle the bluetooth discovery step."""
|
||||
_LOGGER.debug("Discovered device: %s", discovery_info)
|
||||
data = await async_get_manufacturer_data({discovery_info.address})
|
||||
product_type = data[discovery_info.address].product_type
|
||||
product_type = await async_get_product_type(self.hass, discovery_info.address)
|
||||
if product_type not in _SUPPORTED_PRODUCT_TYPES:
|
||||
return self.async_abort(reason="no_devices_found")
|
||||
|
||||
@@ -117,22 +101,16 @@ class GardenaBluetoothConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
self._abort_if_unique_id_configured()
|
||||
return await self.async_step_confirm()
|
||||
|
||||
current_addresses = self._async_current_ids(include_ignore=False)
|
||||
candidates = set()
|
||||
for discovery_info in async_discovered_service_info(self.hass):
|
||||
address = discovery_info.address
|
||||
if address in current_addresses or not _is_supported(discovery_info):
|
||||
continue
|
||||
candidates.add(address)
|
||||
|
||||
data = await async_get_manufacturer_data(candidates)
|
||||
for address, mfg_data in data.items():
|
||||
if mfg_data.product_type not in _SUPPORTED_PRODUCT_TYPES:
|
||||
continue
|
||||
self.devices[address] = PRODUCT_NAMES[mfg_data.product_type]
|
||||
current = self._async_current_ids(include_ignore=False)
|
||||
devices = await async_get_products(self.hass)
|
||||
|
||||
# Keep selection sorted by address to ensure stable tests
|
||||
self.devices = dict(sorted(self.devices.items(), key=lambda x: x[0]))
|
||||
self.devices = {
|
||||
address: PRODUCT_NAMES[data.product_type]
|
||||
for address in sorted(devices)
|
||||
if address not in current
|
||||
and (data := devices[address]).product_type in _SUPPORTED_PRODUCT_TYPES
|
||||
}
|
||||
|
||||
if not self.devices:
|
||||
return self.async_abort(reason="no_devices_found")
|
||||
|
||||
@@ -135,7 +135,24 @@ async def async_migrate_entry(
|
||||
)
|
||||
|
||||
if canonical.entry_id != config_entry.entry_id:
|
||||
# The canonical entry's migration will remove this duplicate.
|
||||
if canonical.minor_version < 2:
|
||||
# The canonical entry has not been migrated yet and its
|
||||
# migration will remove this duplicate.
|
||||
return False
|
||||
|
||||
# The canonical entry is already fully migrated and will not run
|
||||
# a migration that removes this duplicate, so remove it here. The
|
||||
# entry can't remove itself while its setup lock is held, so
|
||||
# schedule the removal instead.
|
||||
_LOGGER.debug(
|
||||
"Removing duplicate config entry %s for serial %s in favor of %s",
|
||||
config_entry.entry_id,
|
||||
serial_number,
|
||||
canonical.entry_id,
|
||||
)
|
||||
hass.async_create_task(
|
||||
hass.config_entries.async_remove(config_entry.entry_id)
|
||||
)
|
||||
return False
|
||||
|
||||
for duplicate in duplicates:
|
||||
|
||||
@@ -239,7 +239,24 @@ async def async_migrate_entry(
|
||||
)
|
||||
|
||||
if canonical.entry_id != config_entry.entry_id:
|
||||
# The canonical entry's migration will remove this duplicate.
|
||||
if canonical.minor_version < 5:
|
||||
# The canonical entry has not been migrated yet and its
|
||||
# migration will remove this duplicate.
|
||||
return False
|
||||
|
||||
# The canonical entry is already fully migrated and will not run
|
||||
# a migration that removes this duplicate, so remove it here. The
|
||||
# entry can't remove itself while its setup lock is held, so
|
||||
# schedule the removal instead.
|
||||
_LOGGER.warning(
|
||||
"Removing duplicate config entry %s for serial %s in favor of %s",
|
||||
config_entry.entry_id,
|
||||
serial_number,
|
||||
canonical.entry_id,
|
||||
)
|
||||
hass.async_create_task(
|
||||
hass.config_entries.async_remove(config_entry.entry_id)
|
||||
)
|
||||
return False
|
||||
|
||||
for duplicate in duplicates:
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_polling",
|
||||
"quality_scale": "bronze",
|
||||
"requirements": ["mitsubishi-comfort==0.3.0"]
|
||||
"requirements": ["mitsubishi-comfort==0.3.1"]
|
||||
}
|
||||
|
||||
@@ -412,6 +412,12 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
|
||||
async def _reload_config(call: ServiceCall) -> None:
|
||||
"""Reload the platforms."""
|
||||
if not mqtt_config_entry_enabled(hass):
|
||||
_LOGGER.debug(
|
||||
"Skipped reloading MQTT integration, "
|
||||
"the MQTT config entry is not enabled"
|
||||
)
|
||||
return
|
||||
entry: ConfigEntry = next(iter(hass.config_entries.async_entries(DOMAIN)))
|
||||
mqtt_data = hass.data[DATA_MQTT]
|
||||
|
||||
|
||||
@@ -159,11 +159,14 @@ class OpenThermGatewayHub:
|
||||
_LOGGER.debug("Received report: %s", status)
|
||||
async_dispatcher_send(self.hass, self.update_signal, status)
|
||||
|
||||
boiler_manufacturer = status[OpenThermDataSource.BOILER].get(
|
||||
gw_vars.DATA_SLAVE_MEMBERID
|
||||
)
|
||||
dev_reg.async_update_device(
|
||||
boiler_device.id,
|
||||
manufacturer=status[OpenThermDataSource.BOILER].get(
|
||||
gw_vars.DATA_SLAVE_MEMBERID
|
||||
),
|
||||
manufacturer=str(boiler_manufacturer)
|
||||
if boiler_manufacturer is not None
|
||||
else None,
|
||||
model_id=status[OpenThermDataSource.BOILER].get(
|
||||
gw_vars.DATA_SLAVE_PRODUCT_TYPE
|
||||
),
|
||||
@@ -175,11 +178,14 @@ class OpenThermGatewayHub:
|
||||
),
|
||||
)
|
||||
|
||||
thermostat_manufacturer = status[OpenThermDataSource.THERMOSTAT].get(
|
||||
gw_vars.DATA_MASTER_MEMBERID
|
||||
)
|
||||
dev_reg.async_update_device(
|
||||
thermostat_device.id,
|
||||
manufacturer=status[OpenThermDataSource.THERMOSTAT].get(
|
||||
gw_vars.DATA_MASTER_MEMBERID
|
||||
),
|
||||
manufacturer=str(thermostat_manufacturer)
|
||||
if thermostat_manufacturer is not None
|
||||
else None,
|
||||
model_id=status[OpenThermDataSource.THERMOSTAT].get(
|
||||
gw_vars.DATA_MASTER_PRODUCT_TYPE
|
||||
),
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["opower"],
|
||||
"quality_scale": "platinum",
|
||||
"requirements": ["opower==0.18.2"]
|
||||
"requirements": ["opower==0.18.4"]
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ USER_SCHEMA = vol.Schema(
|
||||
): str,
|
||||
vol.Required(
|
||||
CONF_API_VERSION,
|
||||
default=1,
|
||||
): vol.In([1, 5, 6]),
|
||||
default="1",
|
||||
): vol.In(["1", "5", "6"]),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -223,7 +223,7 @@ class PhilipsJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
self._current = user_input
|
||||
try:
|
||||
await self._async_attempt_prepare(
|
||||
user_input[CONF_HOST], user_input[CONF_API_VERSION], False
|
||||
user_input[CONF_HOST], int(user_input[CONF_API_VERSION]), False
|
||||
)
|
||||
except GeneralFailure as exc:
|
||||
LOGGER.error(exc)
|
||||
|
||||
@@ -155,9 +155,9 @@ class PlugwiseClimateEntity(PlugwiseEntity, ClimateEntity, RestoreEntity):
|
||||
)
|
||||
|
||||
@property
|
||||
def current_temperature(self) -> float:
|
||||
def current_temperature(self) -> float | None:
|
||||
"""Return the current temperature."""
|
||||
return self.device["sensors"]["temperature"]
|
||||
return self.device["sensors"].get("temperature")
|
||||
|
||||
@property
|
||||
def target_temperature(self) -> float:
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["plugwise"],
|
||||
"quality_scale": "platinum",
|
||||
"requirements": ["plugwise==1.11.3"],
|
||||
"requirements": ["plugwise==1.11.4"],
|
||||
"zeroconf": ["_plugwise._tcp.local."]
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["renault_api"],
|
||||
"quality_scale": "silver",
|
||||
"requirements": ["renault-api==0.5.11"]
|
||||
"requirements": ["renault-api==0.5.12"]
|
||||
}
|
||||
|
||||
@@ -369,7 +369,11 @@ class ReolinkHost:
|
||||
)
|
||||
|
||||
# start long polling if ONVIF push failed immediately
|
||||
if not self._onvif_push_supported and not self._api.baichuan.privacy_mode():
|
||||
if (
|
||||
self._onvif_long_poll_supported
|
||||
and not self._onvif_push_supported
|
||||
and not self._api.baichuan.privacy_mode()
|
||||
):
|
||||
_LOGGER.debug(
|
||||
"Camera model %s does not support ONVIF push,"
|
||||
" using ONVIF long polling instead",
|
||||
@@ -378,14 +382,8 @@ class ReolinkHost:
|
||||
try:
|
||||
await self._async_start_long_polling(initial=True)
|
||||
except NotSupportedError:
|
||||
_LOGGER.debug(
|
||||
"Camera model %s does not support ONVIF long"
|
||||
" polling, using fast polling instead",
|
||||
self._api.model,
|
||||
)
|
||||
self._onvif_long_poll_supported = False
|
||||
await self._api.unsubscribe()
|
||||
await self._async_poll_all_motion()
|
||||
else:
|
||||
self._cancel_long_poll_check = async_call_later(
|
||||
self._hass,
|
||||
@@ -393,6 +391,13 @@ class ReolinkHost:
|
||||
self._async_check_onvif_long_poll,
|
||||
)
|
||||
|
||||
if not self._onvif_long_poll_supported:
|
||||
_LOGGER.debug(
|
||||
"Camera model %s does not support ONVIF push and long polling, using fast polling instead",
|
||||
self._api.model,
|
||||
)
|
||||
await self._async_poll_all_motion()
|
||||
|
||||
self._cancel_tcp_push_check = None
|
||||
|
||||
async def _async_check_onvif(self, *_: Any) -> None:
|
||||
@@ -822,7 +827,7 @@ class ReolinkHost:
|
||||
return
|
||||
|
||||
try:
|
||||
if self._api.session_active:
|
||||
if self._api.session_active and not self._api.baichuan.privacy_mode():
|
||||
await self._api.get_motion_state_all_ch()
|
||||
except ReolinkError as err:
|
||||
if not self._fast_poll_error:
|
||||
@@ -834,7 +839,7 @@ class ReolinkHost:
|
||||
)
|
||||
self._fast_poll_error = True
|
||||
else:
|
||||
if self._api.session_active:
|
||||
if self._api.session_active and not self._api.baichuan.privacy_mode():
|
||||
self._fast_poll_error = False
|
||||
finally:
|
||||
# schedule next poll
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""The Shelly integration."""
|
||||
|
||||
import asyncio
|
||||
from functools import partial
|
||||
from typing import Final
|
||||
|
||||
@@ -73,6 +74,7 @@ from .utils import (
|
||||
get_http_port,
|
||||
get_rpc_scripts_event_types,
|
||||
get_ws_context,
|
||||
is_rpc_ble_scanner_supported,
|
||||
remove_empty_sub_devices,
|
||||
remove_stale_blu_trv_devices,
|
||||
)
|
||||
@@ -114,6 +116,9 @@ COAP_SCHEMA: Final = vol.Schema(
|
||||
)
|
||||
CONFIG_SCHEMA: Final = vol.Schema({DOMAIN: COAP_SCHEMA}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
# Max time to wait at startup for a BLE proxy to register its scanner.
|
||||
STARTUP_SCANNER_WAIT: Final = 3.0
|
||||
|
||||
|
||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
"""Set up the Shelly component."""
|
||||
@@ -365,6 +370,21 @@ async def _async_setup_rpc_entry(hass: HomeAssistant, entry: ShellyConfigEntry)
|
||||
|
||||
runtime_data.rpc = ShellyRpcCoordinator(hass, entry, device)
|
||||
runtime_data.rpc.async_setup()
|
||||
|
||||
if (
|
||||
is_rpc_ble_scanner_supported(entry)
|
||||
and entry.options.get(CONF_BLE_SCANNER_MODE, BLEScannerMode.DISABLED)
|
||||
!= BLEScannerMode.DISABLED
|
||||
):
|
||||
# Wait for the proxy to register its scanner before finishing setup.
|
||||
try:
|
||||
async with asyncio.timeout(STARTUP_SCANNER_WAIT):
|
||||
await runtime_data.rpc.ble_scanner_setup_done.wait()
|
||||
except TimeoutError:
|
||||
LOGGER.debug(
|
||||
"%s: Timed out waiting for BLE scanner to register", entry.title
|
||||
)
|
||||
|
||||
runtime_data.rpc_poll = ShellyRpcPollingCoordinator(hass, entry, device)
|
||||
await hass.config_entries.async_forward_entry_setups(
|
||||
entry, runtime_data.platforms
|
||||
|
||||
@@ -521,6 +521,8 @@ class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]):
|
||||
super().__init__(hass, entry, device, update_interval)
|
||||
|
||||
self.connected = False
|
||||
# Set once BLE scanner setup has been attempted after connecting.
|
||||
self.ble_scanner_setup_done = asyncio.Event()
|
||||
self._disconnected_callbacks: list[CALLBACK_TYPE] = []
|
||||
self._connection_lock = asyncio.Lock()
|
||||
self._event_listeners: list[Callable[[dict[str, Any]], None]] = []
|
||||
@@ -759,27 +761,30 @@ class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]):
|
||||
|
||||
async def _async_connect_ble_scanner(self) -> None:
|
||||
"""Connect BLE scanner."""
|
||||
ble_scanner_mode = self.config_entry.options.get(
|
||||
CONF_BLE_SCANNER_MODE, BLEScannerMode.DISABLED
|
||||
)
|
||||
if ble_scanner_mode == BLEScannerMode.DISABLED and self.connected:
|
||||
await async_stop_scanner(self.device)
|
||||
async_remove_scanner(self.hass, self.bluetooth_source)
|
||||
return
|
||||
if await async_ensure_ble_enabled(self.device):
|
||||
# BLE enable required a reboot, don't bother connecting
|
||||
# the scanner since it will be disconnected anyway
|
||||
LOGGER.debug(
|
||||
"Device %s BLE enable required a reboot, skipping scanner connect",
|
||||
self.name,
|
||||
try:
|
||||
ble_scanner_mode = self.config_entry.options.get(
|
||||
CONF_BLE_SCANNER_MODE, BLEScannerMode.DISABLED
|
||||
)
|
||||
return
|
||||
assert self.device_id is not None
|
||||
self._disconnected_callbacks.append(
|
||||
await async_connect_scanner(
|
||||
self.hass, self, ble_scanner_mode, self.device_id
|
||||
if ble_scanner_mode == BLEScannerMode.DISABLED and self.connected:
|
||||
await async_stop_scanner(self.device)
|
||||
async_remove_scanner(self.hass, self.bluetooth_source)
|
||||
return
|
||||
if await async_ensure_ble_enabled(self.device):
|
||||
# BLE enable required a reboot, don't bother connecting
|
||||
# the scanner since it will be disconnected anyway
|
||||
LOGGER.debug(
|
||||
"Device %s BLE enable required a reboot, skipping scanner connect",
|
||||
self.name,
|
||||
)
|
||||
return
|
||||
assert self.device_id is not None
|
||||
self._disconnected_callbacks.append(
|
||||
await async_connect_scanner(
|
||||
self.hass, self, ble_scanner_mode, self.device_id
|
||||
)
|
||||
)
|
||||
)
|
||||
finally:
|
||||
self.ble_scanner_setup_done.set()
|
||||
|
||||
@callback
|
||||
def _async_handle_rpc_device_online(self) -> None:
|
||||
|
||||
@@ -663,9 +663,9 @@ def is_view_for_platform(config: dict[str, Any], key: str, platform: str) -> boo
|
||||
def get_virtual_component_unit(config: dict[str, Any]) -> str | None:
|
||||
"""Return the unit of a virtual component.
|
||||
|
||||
If the unit is not set, the device sends an empty string
|
||||
If the unit is not set, the device sends an empty string or the key may be absent.
|
||||
"""
|
||||
unit = config["meta"]["ui"]["unit"]
|
||||
unit = config["meta"]["ui"].get("unit")
|
||||
return DEVICE_UNIT_MAP.get(unit, unit) if unit else None
|
||||
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ ATTR_QUERY_RESULT = "query_result"
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
ATTR_OTHER_PLAYER = "other_player"
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ from .entity import SqueezeboxEntity
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
|
||||
@@ -613,6 +613,10 @@ class ResultStream:
|
||||
async for chunk in converted_audio:
|
||||
yield chunk
|
||||
|
||||
def delete(self) -> None:
|
||||
"""Remove the result stream from the manager."""
|
||||
self._manager.async_delete_result_stream(self.token)
|
||||
|
||||
|
||||
def _hash_options(options: dict) -> str:
|
||||
"""Hashes an options dictionary."""
|
||||
@@ -809,6 +813,11 @@ class SpeechManager:
|
||||
stream.last_used = monotonic()
|
||||
return stream
|
||||
|
||||
@callback
|
||||
def async_delete_result_stream(self, token: str) -> None:
|
||||
"""Delete a result stream given a token."""
|
||||
self.token_to_stream.pop(token, None)
|
||||
|
||||
@callback
|
||||
def async_create_result_stream(
|
||||
self,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Diagnostics support for V2C."""
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
|
||||
from homeassistant.components.diagnostics import async_redact_data
|
||||
from homeassistant.const import CONF_HOST
|
||||
@@ -21,11 +21,11 @@ async def async_get_config_entry_diagnostics(
|
||||
assert coordinator.evse
|
||||
|
||||
coordinator_data = coordinator.evse.data
|
||||
evse_raw_data = coordinator.evse.raw_data
|
||||
evse_raw_data = cast(dict[str, Any], coordinator.evse.raw_data)
|
||||
|
||||
return {
|
||||
"config_entry": async_redact_data(entry.as_dict(), TO_REDACT),
|
||||
"data": str(coordinator_data),
|
||||
"raw_data": evse_raw_data["content"].decode("utf-8"), # type: ignore[attr-defined]
|
||||
"raw_data": evse_raw_data["content"].decode("utf-8"),
|
||||
"host_status": evse_raw_data["status_code"],
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/v2c",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"requirements": ["pytrydan==1.0.0"]
|
||||
"requirements": ["pytrydan==1.0.1"]
|
||||
}
|
||||
|
||||
@@ -348,6 +348,8 @@ class WyomingAssistSatellite(WyomingSatelliteEntity, AssistSatelliteEntity):
|
||||
# Use ffmpeg to convert to raw PCM audio with the appropriate format
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
self._ffmpeg_manager.binary,
|
||||
"-protocol_whitelist",
|
||||
"http,https,file,tcp,tls",
|
||||
"-i",
|
||||
announcement.media_id,
|
||||
"-f",
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/yardian",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"requirements": ["pyyardian==1.3.3"]
|
||||
"requirements": ["pyyardian==1.4.0"]
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ POINT_ENTITIES = {
|
||||
class ZinvoltBatteryStateDescription(BinarySensorEntityDescription):
|
||||
"""Binary sensor description for Zinvolt battery state."""
|
||||
|
||||
is_on_fn: Callable[[ZinvoltData], bool]
|
||||
is_on_fn: Callable[[ZinvoltData], bool | None]
|
||||
|
||||
|
||||
SENSORS: tuple[ZinvoltBatteryStateDescription, ...] = (
|
||||
@@ -84,7 +84,7 @@ class ZinvoltBatteryStateBinarySensor(ZinvoltEntity, BinarySensorEntity):
|
||||
)
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
def is_on(self) -> bool | None:
|
||||
"""Return the state of the binary sensor."""
|
||||
return self.entity_description.is_on_fn(self.coordinator.data)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Base entity for Zinvolt integration."""
|
||||
|
||||
from zinvolt.models import Unit
|
||||
from zinvolt.models import OnlineStatus, Unit
|
||||
|
||||
from homeassistant.const import ATTR_VIA_DEVICE
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
@@ -25,6 +25,15 @@ class ZinvoltEntity(CoordinatorEntity[ZinvoltDeviceCoordinator]):
|
||||
serial_number=coordinator.data.battery.serial_number,
|
||||
)
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return if the entity is available."""
|
||||
return (
|
||||
super().available
|
||||
and self.coordinator.data.battery.current_power.online_status
|
||||
is OnlineStatus.ONLINE
|
||||
)
|
||||
|
||||
|
||||
class ZinvoltUnitEntity(ZinvoltEntity):
|
||||
"""Base entity for Zinvolt units."""
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["zinvolt"],
|
||||
"quality_scale": "bronze",
|
||||
"requirements": ["zinvolt==0.4.3"]
|
||||
"requirements": ["zinvolt==1.0.0"]
|
||||
}
|
||||
|
||||
@@ -34,7 +34,11 @@ NUMBERS: tuple[ZinvoltBatteryStateDescription, ...] = (
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
device_class=NumberDeviceClass.POWER,
|
||||
native_unit_of_measurement=UnitOfPower.WATT,
|
||||
value_fn=lambda state: state.battery.global_settings.max_output,
|
||||
value_fn=lambda state: (
|
||||
2000
|
||||
if state.battery.global_settings.max_output_unlocked
|
||||
else state.battery.global_settings.max_output
|
||||
),
|
||||
set_value_fn=lambda client, battery_id, value: client.set_max_output(
|
||||
battery_id, value
|
||||
),
|
||||
|
||||
@@ -21,7 +21,7 @@ from .entity import ZinvoltEntity
|
||||
class ZinvoltBatteryStateDescription(SensorEntityDescription):
|
||||
"""Sensor description for Zinvolt battery state."""
|
||||
|
||||
value_fn: Callable[[ZinvoltData], float]
|
||||
value_fn: Callable[[ZinvoltData], float | None]
|
||||
|
||||
|
||||
SENSORS: tuple[ZinvoltBatteryStateDescription, ...] = (
|
||||
@@ -37,7 +37,13 @@ SENSORS: tuple[ZinvoltBatteryStateDescription, ...] = (
|
||||
device_class=SensorDeviceClass.POWER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfPower.WATT,
|
||||
value_fn=lambda state: 0 - state.battery.current_power.power_socket_output,
|
||||
value_fn=(
|
||||
lambda state: (
|
||||
None
|
||||
if state.battery.current_power.power_socket_output is None
|
||||
else 0 - state.battery.current_power.power_socket_output
|
||||
)
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -74,6 +80,6 @@ class ZinvoltBatteryStateSensor(ZinvoltEntity, SensorEntity):
|
||||
)
|
||||
|
||||
@property
|
||||
def native_value(self) -> float:
|
||||
def native_value(self) -> float | None:
|
||||
"""Return the state of the sensor."""
|
||||
return self.entity_description.value_fn(self.coordinator.data)
|
||||
|
||||
@@ -15,7 +15,7 @@ if TYPE_CHECKING:
|
||||
APPLICATION_NAME: Final = "HomeAssistant"
|
||||
MAJOR_VERSION: Final = 2026
|
||||
MINOR_VERSION: Final = 6
|
||||
PATCH_VERSION: Final = "1"
|
||||
PATCH_VERSION: Final = "2"
|
||||
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
||||
__version__: Final = f"{__short_version__}.{PATCH_VERSION}"
|
||||
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 14, 2)
|
||||
|
||||
@@ -39,7 +39,7 @@ habluetooth==6.8.1
|
||||
hass-nabucasa==2.2.0
|
||||
hassil==3.5.0
|
||||
home-assistant-bluetooth==2.0.0
|
||||
home-assistant-frontend==20260527.4
|
||||
home-assistant-frontend==20260527.5
|
||||
home-assistant-intents==2026.6.1
|
||||
httpx==0.28.1
|
||||
ifaddr==0.2.0
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ To update, run python3 -m script.hassfest
|
||||
|
||||
from typing import Final
|
||||
|
||||
FRONTEND_VERSION: Final[str] = "20260527.4"
|
||||
FRONTEND_VERSION: Final[str] = "20260527.5"
|
||||
|
||||
MDI_ICONS: Final[set[str]] = {
|
||||
"ab-testing",
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "homeassistant"
|
||||
version = "2026.6.1"
|
||||
version = "2026.6.2"
|
||||
license = "Apache-2.0"
|
||||
license-files = ["LICENSE*", "homeassistant/backports/LICENSE*"]
|
||||
description = "Open-source home automation platform running on Python 3."
|
||||
|
||||
Generated
+9
-9
@@ -1266,7 +1266,7 @@ hole==0.9.0
|
||||
holidays==0.98
|
||||
|
||||
# homeassistant.components.frontend
|
||||
home-assistant-frontend==20260527.4
|
||||
home-assistant-frontend==20260527.5
|
||||
|
||||
# homeassistant.components.conversation
|
||||
home-assistant-intents==2026.6.1
|
||||
@@ -1577,7 +1577,7 @@ millheater==0.14.1
|
||||
minio==7.1.12
|
||||
|
||||
# homeassistant.components.mitsubishi_comfort
|
||||
mitsubishi-comfort==0.3.0
|
||||
mitsubishi-comfort==0.3.1
|
||||
|
||||
# homeassistant.components.moat
|
||||
moat-ble==0.1.1
|
||||
@@ -1776,7 +1776,7 @@ openwrt-luci-rpc==1.1.17
|
||||
openwrt-ubus-rpc==0.0.2
|
||||
|
||||
# homeassistant.components.opower
|
||||
opower==0.18.2
|
||||
opower==0.18.4
|
||||
|
||||
# homeassistant.components.oralb
|
||||
oralb-ble==1.1.0
|
||||
@@ -1843,7 +1843,7 @@ plexauth==0.0.6
|
||||
plexwebsocket==0.0.14
|
||||
|
||||
# homeassistant.components.plugwise
|
||||
plugwise==1.11.3
|
||||
plugwise==1.11.4
|
||||
|
||||
# homeassistant.components.serial_pm
|
||||
pmsensor==0.4
|
||||
@@ -2081,7 +2081,7 @@ pycsspeechtts==1.0.8
|
||||
pycync==0.5.0
|
||||
|
||||
# homeassistant.components.daikin
|
||||
pydaikin==2.17.2
|
||||
pydaikin==2.18.1
|
||||
|
||||
# homeassistant.components.danfoss_air
|
||||
pydanfossair==0.1.0
|
||||
@@ -2773,7 +2773,7 @@ pytradfri[async]==9.0.1
|
||||
pytrafikverket==1.1.1
|
||||
|
||||
# homeassistant.components.v2c
|
||||
pytrydan==1.0.0
|
||||
pytrydan==1.0.1
|
||||
|
||||
# homeassistant.components.uptimerobot
|
||||
pyuptimerobot==25.0.0
|
||||
@@ -2824,7 +2824,7 @@ pyws66i==1.1
|
||||
pyxeoma==1.4.2
|
||||
|
||||
# homeassistant.components.yardian
|
||||
pyyardian==1.3.3
|
||||
pyyardian==1.4.0
|
||||
|
||||
# homeassistant.components.qrcode
|
||||
pyzbar==0.1.9
|
||||
@@ -2872,7 +2872,7 @@ refoss-ha==1.2.5
|
||||
regenmaschine==2024.03.0
|
||||
|
||||
# homeassistant.components.renault
|
||||
renault-api==0.5.11
|
||||
renault-api==0.5.12
|
||||
|
||||
# homeassistant.components.renson
|
||||
renson-endura-delta==1.7.2
|
||||
@@ -3451,7 +3451,7 @@ zhong-hong-hvac==1.0.13
|
||||
ziggo-mediabox-xl==1.1.0
|
||||
|
||||
# homeassistant.components.zinvolt
|
||||
zinvolt==0.4.3
|
||||
zinvolt==1.0.0
|
||||
|
||||
# homeassistant.components.zoneminder
|
||||
zm-py==0.5.4
|
||||
|
||||
@@ -91,6 +91,48 @@ async def test_coordinator_load_previous_devices_from_registry(
|
||||
assert coordinator.previous_devices == {TEST_DEVICE_1_SN}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("side_effect", "expected_state"),
|
||||
[
|
||||
pytest.param(
|
||||
CannotConnect,
|
||||
ConfigEntryState.SETUP_RETRY,
|
||||
id="cannot_connect",
|
||||
),
|
||||
pytest.param(
|
||||
CannotRetrieveData,
|
||||
ConfigEntryState.SETUP_RETRY,
|
||||
id="cannot_retrieve_data",
|
||||
),
|
||||
pytest.param(
|
||||
CannotAuthenticate,
|
||||
ConfigEntryState.SETUP_ERROR,
|
||||
id="cannot_authenticate",
|
||||
),
|
||||
pytest.param(
|
||||
ValueError,
|
||||
ConfigEntryState.SETUP_RETRY,
|
||||
id="value_error",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_async_update_data_errors(
|
||||
hass: HomeAssistant,
|
||||
mock_amazon_devices_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
side_effect: type[Exception],
|
||||
expected_state: ConfigEntryState,
|
||||
) -> None:
|
||||
"""Test _async_update_data error handling."""
|
||||
mock_amazon_devices_client.get_devices_data.side_effect = side_effect
|
||||
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert mock_config_entry.state is expected_state
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("side_effect", "expected_state"),
|
||||
[
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from aioamazondevices.const.devices import SPEAKER_GROUP_FAMILY
|
||||
from aioamazondevices.exceptions import CannotConnect, CannotRetrieveData
|
||||
from aioamazondevices.exceptions import (
|
||||
CannotAuthenticate,
|
||||
CannotConnect,
|
||||
CannotRetrieveData,
|
||||
)
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.alexa_devices.const import DOMAIN
|
||||
@@ -25,15 +29,37 @@ ENTITY_ID = "switch.echo_test_do_not_disturb"
|
||||
@pytest.mark.parametrize(
|
||||
("side_effect", "key", "error"),
|
||||
[
|
||||
(CannotConnect, "cannot_connect_with_error", "CannotConnect()"),
|
||||
(CannotRetrieveData, "cannot_retrieve_data_with_error", "CannotRetrieveData()"),
|
||||
pytest.param(
|
||||
CannotAuthenticate,
|
||||
"invalid_auth",
|
||||
"CannotAuthenticate()",
|
||||
id="cannot_authenticate",
|
||||
),
|
||||
pytest.param(
|
||||
CannotConnect,
|
||||
"cannot_connect_with_error",
|
||||
"CannotConnect()",
|
||||
id="cannot_connect",
|
||||
),
|
||||
pytest.param(
|
||||
CannotRetrieveData,
|
||||
"cannot_retrieve_data_with_error",
|
||||
"CannotRetrieveData()",
|
||||
id="cannot_retrieve_data",
|
||||
),
|
||||
pytest.param(
|
||||
ValueError,
|
||||
"cannot_retrieve_data_with_error",
|
||||
"ValueError()",
|
||||
id="value_error",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_alexa_api_call_exceptions(
|
||||
hass: HomeAssistant,
|
||||
mock_amazon_devices_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
side_effect: Exception,
|
||||
side_effect: type[Exception],
|
||||
key: str,
|
||||
error: str,
|
||||
) -> None:
|
||||
|
||||
@@ -2274,3 +2274,86 @@ async def test_stt_vad_enabled_based_on_audio_processing(
|
||||
|
||||
# VAD should NOT be created when requires_external_vad is False
|
||||
mock_vad.assert_not_called()
|
||||
|
||||
|
||||
async def test_invalid_pipeline_does_not_create_tts_stream(
|
||||
hass: HomeAssistant,
|
||||
mock_wake_word_provider_entity: MockWakeWordEntity,
|
||||
init_components,
|
||||
) -> None:
|
||||
"""Test that an invalid pipeline won't create a TTS ResultStream."""
|
||||
pipeline = async_get_pipeline(hass, None)
|
||||
await async_update_pipeline(hass, pipeline, stt_engine="does-not-exist")
|
||||
|
||||
async def audio_data() -> AsyncGenerator[bytes]:
|
||||
yield make_10ms_chunk(b"not used")
|
||||
|
||||
with patch.object(
|
||||
mock_wake_word_provider_entity,
|
||||
"async_process_audio_stream",
|
||||
side_effect=assist_pipeline.error.WakeWordTimeoutError(
|
||||
code="timeout", message="timeout"
|
||||
),
|
||||
):
|
||||
await assist_pipeline.async_pipeline_from_audio_stream(
|
||||
hass,
|
||||
context=Context(),
|
||||
event_callback=lambda event: None,
|
||||
stt_metadata=stt.SpeechMetadata(
|
||||
language="",
|
||||
format=stt.AudioFormats.WAV,
|
||||
codec=stt.AudioCodecs.PCM,
|
||||
bit_rate=stt.AudioBitRates.BITRATE_16,
|
||||
sample_rate=stt.AudioSampleRates.SAMPLERATE_16000,
|
||||
channel=stt.AudioChannels.CHANNEL_MONO,
|
||||
),
|
||||
stt_stream=audio_data(),
|
||||
start_stage=assist_pipeline.PipelineStage.STT,
|
||||
end_stage=assist_pipeline.PipelineStage.TTS,
|
||||
audio_settings=assist_pipeline.AudioSettings(is_vad_enabled=False),
|
||||
)
|
||||
|
||||
assert len(hass.data[tts.DATA_TTS_MANAGER].token_to_stream) == 0
|
||||
|
||||
|
||||
async def test_pipeline_error_before_tts_does_not_leak_result_stream(
|
||||
hass: HomeAssistant,
|
||||
mock_wake_word_provider_entity: MockWakeWordEntity,
|
||||
init_components,
|
||||
) -> None:
|
||||
"""Test that a pipeline error before TTS will not leak a ResultStream."""
|
||||
|
||||
async def audio_data() -> AsyncGenerator[bytes]:
|
||||
yield make_10ms_chunk(b"not used")
|
||||
|
||||
with patch.object(
|
||||
mock_wake_word_provider_entity,
|
||||
"async_process_audio_stream",
|
||||
side_effect=assist_pipeline.error.WakeWordTimeoutError(
|
||||
code="timeout", message="timeout"
|
||||
),
|
||||
):
|
||||
for i in range(10):
|
||||
with patch("secrets.token_urlsafe", return_value=f"mocked-token-{i}"):
|
||||
await assist_pipeline.async_pipeline_from_audio_stream(
|
||||
hass,
|
||||
context=Context(),
|
||||
event_callback=lambda event: None,
|
||||
stt_metadata=stt.SpeechMetadata(
|
||||
language="",
|
||||
format=stt.AudioFormats.WAV,
|
||||
codec=stt.AudioCodecs.PCM,
|
||||
bit_rate=stt.AudioBitRates.BITRATE_16,
|
||||
sample_rate=stt.AudioSampleRates.SAMPLERATE_16000,
|
||||
channel=stt.AudioChannels.CHANNEL_MONO,
|
||||
),
|
||||
stt_stream=audio_data(),
|
||||
start_stage=assist_pipeline.PipelineStage.WAKE_WORD,
|
||||
end_stage=assist_pipeline.PipelineStage.TTS,
|
||||
wake_word_settings=assist_pipeline.WakeWordSettings(
|
||||
audio_seconds_to_buffer=1.5
|
||||
),
|
||||
audio_settings=assist_pipeline.AudioSettings(is_vad_enabled=False),
|
||||
)
|
||||
|
||||
assert len(hass.data[tts.DATA_TTS_MANAGER].token_to_stream) == 0
|
||||
|
||||
@@ -9,7 +9,9 @@ from unittest.mock import AsyncMock, Mock, call, patch
|
||||
from aioesphomeapi import (
|
||||
APIClient,
|
||||
APIConnectionError,
|
||||
APIVersion,
|
||||
AreaInfo,
|
||||
BluetoothProxyFeature,
|
||||
DeviceInfo,
|
||||
EncryptionPlaintextAPIError,
|
||||
ExecuteServiceResponse,
|
||||
@@ -3274,3 +3276,124 @@ async def test_service_registration_response_types(
|
||||
hass.services.supports_response(DOMAIN, "test_status_service")
|
||||
== SupportsResponse.NONE
|
||||
)
|
||||
|
||||
|
||||
def _create_cached_bluetooth_proxy_entry(
|
||||
hass: HomeAssistant,
|
||||
hass_storage: dict[str, Any],
|
||||
bluetooth_proxy_feature_flags: BluetoothProxyFeature,
|
||||
) -> tuple[MockConfigEntry, DeviceInfo]:
|
||||
"""Create an entry with cached device info so setup knows the proxy state."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id="11:22:33:44:55:aa",
|
||||
data={
|
||||
CONF_HOST: "test.local",
|
||||
CONF_PORT: 6053,
|
||||
CONF_PASSWORD: "",
|
||||
CONF_BLUETOOTH_MAC_ADDRESS: "AA:BB:CC:DD:EE:FC",
|
||||
},
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
device_info = DeviceInfo(
|
||||
name="test",
|
||||
mac_address="11:22:33:44:55:AA",
|
||||
bluetooth_mac_address="AA:BB:CC:DD:EE:FC",
|
||||
bluetooth_proxy_feature_flags=bluetooth_proxy_feature_flags,
|
||||
)
|
||||
storage_key = f"{DOMAIN}.{entry.entry_id}"
|
||||
hass_storage[storage_key] = {
|
||||
"version": 1,
|
||||
"minor_version": 1,
|
||||
"key": storage_key,
|
||||
"data": {
|
||||
"device_info": device_info.to_dict(),
|
||||
"api_version": APIVersion(1, 9).to_dict(),
|
||||
},
|
||||
}
|
||||
return entry, device_info
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_zeroconf")
|
||||
async def test_bluetooth_proxy_waits_for_scanner_at_startup(
|
||||
hass: HomeAssistant,
|
||||
mock_client: APIClient,
|
||||
hass_storage: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test setup waits for a cached bluetooth proxy to register its scanner."""
|
||||
entry, device_info = _create_cached_bluetooth_proxy_entry(
|
||||
hass, hass_storage, BluetoothProxyFeature.PASSIVE_SCAN
|
||||
)
|
||||
connect_event = asyncio.Event()
|
||||
reached_connect = asyncio.Event()
|
||||
|
||||
async def _block_until_released() -> tuple[DeviceInfo, list[Any], list[Any]]:
|
||||
reached_connect.set()
|
||||
await connect_event.wait()
|
||||
return (device_info, [], [])
|
||||
|
||||
mock_client.device_info_and_list_entities = _block_until_released
|
||||
|
||||
setup_task = hass.async_create_task(hass.config_entries.async_setup(entry.entry_id))
|
||||
async with asyncio.timeout(2):
|
||||
await reached_connect.wait()
|
||||
|
||||
# Setup must still be waiting for the scanner to be registered.
|
||||
assert not setup_task.done()
|
||||
|
||||
connect_event.set()
|
||||
async with asyncio.timeout(2):
|
||||
assert await setup_task is True
|
||||
assert entry.runtime_data.first_connect_done.is_set()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_zeroconf")
|
||||
async def test_bluetooth_proxy_startup_wait_times_out(
|
||||
hass: HomeAssistant,
|
||||
mock_client: APIClient,
|
||||
hass_storage: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test setup finishes if a cached bluetooth proxy never connects."""
|
||||
entry, device_info = _create_cached_bluetooth_proxy_entry(
|
||||
hass, hass_storage, BluetoothProxyFeature.PASSIVE_SCAN
|
||||
)
|
||||
connect_event = asyncio.Event()
|
||||
|
||||
async def _never_returns() -> tuple[DeviceInfo, list[Any], list[Any]]:
|
||||
await connect_event.wait()
|
||||
return (device_info, [], [])
|
||||
|
||||
mock_client.device_info_and_list_entities = _never_returns
|
||||
|
||||
with patch("homeassistant.components.esphome.manager.STARTUP_SCANNER_WAIT", 0.05):
|
||||
async with asyncio.timeout(2):
|
||||
assert await hass.config_entries.async_setup(entry.entry_id) is True
|
||||
|
||||
connect_event.set()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_zeroconf")
|
||||
async def test_non_bluetooth_device_does_not_wait_at_startup(
|
||||
hass: HomeAssistant,
|
||||
mock_client: APIClient,
|
||||
hass_storage: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test setup does not wait for a device that is not a bluetooth proxy."""
|
||||
entry, device_info = _create_cached_bluetooth_proxy_entry(
|
||||
hass, hass_storage, BluetoothProxyFeature(0)
|
||||
)
|
||||
connect_event = asyncio.Event()
|
||||
|
||||
async def _never_returns() -> tuple[DeviceInfo, list[Any], list[Any]]:
|
||||
await connect_event.wait()
|
||||
return (device_info, [], [])
|
||||
|
||||
mock_client.device_info_and_list_entities = _never_returns
|
||||
|
||||
# The connection is blocked, but without proxy flags setup must not wait.
|
||||
async with asyncio.timeout(2):
|
||||
assert await hass.config_entries.async_setup(entry.entry_id) is True
|
||||
|
||||
connect_event.set()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
@@ -11,11 +11,10 @@ from gardena_bluetooth.client import Client
|
||||
from gardena_bluetooth.const import DeviceInformation
|
||||
from gardena_bluetooth.exceptions import CharacteristicNotFound
|
||||
from gardena_bluetooth.parse import Characteristic, Service
|
||||
from gardena_bluetooth.scan import (
|
||||
async_get_manufacturer_data as _async_get_manufacturer_data,
|
||||
)
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import bluetooth
|
||||
from homeassistant.components.gardena_bluetooth import async_get_product_type
|
||||
from homeassistant.components.gardena_bluetooth.const import DOMAIN
|
||||
from homeassistant.components.gardena_bluetooth.coordinator import SCAN_INTERVAL
|
||||
from homeassistant.core import HomeAssistant
|
||||
@@ -178,23 +177,49 @@ def enable_all_entities(entity_registry_enabled_by_default: None) -> None:
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def manufacturer_request_event() -> Generator[asyncio.Event]:
|
||||
"""Track manufacturer data requests with an event."""
|
||||
def get_product_type_event() -> Generator[asyncio.Event]:
|
||||
"""Track product type data requests with an event."""
|
||||
|
||||
event = asyncio.Event()
|
||||
|
||||
async def _get(*args, **kwargs):
|
||||
event.set()
|
||||
return await _async_get_manufacturer_data(*args, **kwargs)
|
||||
return await async_get_product_type(*args, **kwargs)
|
||||
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.gardena_bluetooth.async_get_manufacturer_data",
|
||||
"homeassistant.components.gardena_bluetooth.async_get_product_type",
|
||||
wraps=_get,
|
||||
),
|
||||
patch(
|
||||
"homeassistant.components.gardena_bluetooth.config_flow.async_get_manufacturer_data",
|
||||
"homeassistant.components.gardena_bluetooth.config_flow.async_get_product_type",
|
||||
wraps=_get,
|
||||
),
|
||||
):
|
||||
yield event
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def constant_advertisements() -> Generator[None]:
|
||||
"""Ensure async_process_advertisements only return a constant list."""
|
||||
|
||||
async def _advertisements(
|
||||
hass: HomeAssistant,
|
||||
callback: bluetooth.models.ProcessAdvertisementCallback,
|
||||
match_dict: bluetooth.match.BluetoothCallbackMatcher,
|
||||
mode: bluetooth.BluetoothScanningMode,
|
||||
timeout: int,
|
||||
) -> bluetooth.BluetoothServiceInfoBleak:
|
||||
|
||||
last = None
|
||||
for advertisement in bluetooth.async_discovered_service_info(hass):
|
||||
callback(advertisement)
|
||||
last = advertisement
|
||||
if not last:
|
||||
raise TimeoutError
|
||||
return last
|
||||
|
||||
with (
|
||||
patch.object(bluetooth, "async_process_advertisements", new=_advertisements),
|
||||
):
|
||||
yield
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""Test the Gardena Bluetooth config flow."""
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Awaitable, Callable
|
||||
from unittest.mock import Mock
|
||||
|
||||
from gardena_bluetooth.exceptions import CharacteristicNotFound
|
||||
@@ -26,13 +24,10 @@ from . import (
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.components.bluetooth import inject_bluetooth_service_info
|
||||
|
||||
pytestmark = pytest.mark.usefixtures("mock_setup_entry")
|
||||
pytestmark = pytest.mark.usefixtures("mock_setup_entry", "constant_advertisements")
|
||||
|
||||
|
||||
async def test_user_selection(
|
||||
hass: HomeAssistant,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
async def test_user_selection(hass: HomeAssistant, snapshot: SnapshotAssertion) -> None:
|
||||
"""Test we can select a device."""
|
||||
|
||||
inject_bluetooth_service_info(hass, WATER_TIMER_SERVICE_INFO)
|
||||
@@ -138,9 +133,6 @@ async def test_no_valid_devices(
|
||||
|
||||
async def test_timeout_manufacturer_data(
|
||||
hass: HomeAssistant,
|
||||
snapshot: SnapshotAssertion,
|
||||
scan_step: Callable[[], Awaitable[None]],
|
||||
manufacturer_request_event: asyncio.Event,
|
||||
) -> None:
|
||||
"""Test the flow aborts with no_devices_found.
|
||||
|
||||
@@ -149,24 +141,9 @@ async def test_timeout_manufacturer_data(
|
||||
"""
|
||||
|
||||
inject_bluetooth_service_info(hass, MISSING_PRODUCT_SERVICE_INFO)
|
||||
|
||||
# The injected advertisement starts a bluetooth discovery flow which also
|
||||
# calls async_get_manufacturer_data. Drain it first so it doesn't race
|
||||
# with the user flow's own request.
|
||||
await manufacturer_request_event.wait()
|
||||
await scan_step()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
manufacturer_request_event.clear()
|
||||
|
||||
async with asyncio.TaskGroup() as tg:
|
||||
task = tg.create_task(
|
||||
hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
)
|
||||
await manufacturer_request_event.wait()
|
||||
await scan_step()
|
||||
result = await task
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
assert result.get("type") == "abort"
|
||||
assert result.get("reason") == "no_devices_found"
|
||||
|
||||
@@ -72,6 +72,7 @@ from tests.components.bluetooth import inject_bluetooth_service_info
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.usefixtures("constant_advertisements")
|
||||
async def test_setup(
|
||||
hass: HomeAssistant,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
@@ -99,7 +100,7 @@ async def test_setup_delayed_product(
|
||||
device_registry: dr.DeviceRegistry,
|
||||
mock_entry: MockConfigEntry,
|
||||
mock_read_char_raw: dict[str, bytes],
|
||||
manufacturer_request_event: asyncio.Event,
|
||||
get_product_type_event: asyncio.Event,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test setup creates expected devices."""
|
||||
@@ -107,15 +108,16 @@ async def test_setup_delayed_product(
|
||||
mock_read_char_raw[Battery.battery_level.uuid] = Battery.battery_level.encode(100)
|
||||
|
||||
mock_entry.add_to_hass(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
manufacturer_request_event.clear()
|
||||
get_product_type_event.clear()
|
||||
|
||||
async with asyncio.TaskGroup() as tg:
|
||||
setup_task = tg.create_task(
|
||||
hass.config_entries.async_setup(mock_entry.entry_id)
|
||||
)
|
||||
|
||||
await manufacturer_request_event.wait()
|
||||
await get_product_type_event.wait()
|
||||
assert mock_entry.state is ConfigEntryState.SETUP_IN_PROGRESS
|
||||
inject_bluetooth_service_info(hass, MISSING_MANUFACTURER_DATA_SERVICE_INFO)
|
||||
inject_bluetooth_service_info(hass, WATER_TIMER_SERVICE_INFO)
|
||||
@@ -123,6 +125,7 @@ async def test_setup_delayed_product(
|
||||
assert await setup_task is True
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("constant_advertisements")
|
||||
async def test_setup_retry(
|
||||
hass: HomeAssistant, mock_entry: MockConfigEntry, mock_client: Mock
|
||||
) -> None:
|
||||
|
||||
@@ -26,6 +26,8 @@ from . import AQUA_CONTOUR_SERVICE_INFO, WATER_TIMER_SERVICE_INFO, setup_entry
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
pytestmark = pytest.mark.usefixtures("constant_advertisements")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("service_info", "uuid", "raw", "entity_id"),
|
||||
|
||||
@@ -25,6 +25,8 @@ from . import AQUA_CONTOUR_SERVICE_INFO, setup_entry
|
||||
|
||||
from tests.common import MockConfigEntry, snapshot_platform
|
||||
|
||||
pytestmark = pytest.mark.usefixtures("constant_advertisements")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_chars(mock_read_char_raw):
|
||||
|
||||
@@ -27,6 +27,8 @@ from . import AQUA_CONTOUR_SERVICE_INFO, WATER_TIMER_SERVICE_INFO, setup_entry
|
||||
|
||||
from tests.common import MockConfigEntry, snapshot_platform
|
||||
|
||||
pytestmark = pytest.mark.usefixtures("constant_advertisements")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("service_info", "uuid", "raw", "entity_id"),
|
||||
|
||||
@@ -20,6 +20,8 @@ from . import setup_entry
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
pytestmark = pytest.mark.usefixtures("constant_advertisements")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_switch_chars(mock_read_char_raw):
|
||||
|
||||
@@ -20,6 +20,8 @@ from . import AQUA_CONTOUR_SERVICE_INFO, setup_entry
|
||||
|
||||
from tests.common import snapshot_platform
|
||||
|
||||
pytestmark = pytest.mark.usefixtures("constant_advertisements")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("service_info", "raw"),
|
||||
|
||||
@@ -20,6 +20,8 @@ from . import setup_entry
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
pytestmark = pytest.mark.usefixtures("constant_advertisements")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_switch_chars(mock_read_char_raw):
|
||||
|
||||
@@ -234,6 +234,75 @@ async def test_config_entry_migration_v2_prefers_active_entry(
|
||||
assert active_entry.unique_id == serial_number
|
||||
|
||||
|
||||
async def test_config_entry_migration_v2_removes_duplicates_of_migrated_entry(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test v1.2 migration removes duplicates of an already migrated entry.
|
||||
|
||||
A migrated entry (minor version 2) never runs the migration again, so the
|
||||
remaining minor version 1 duplicates have to remove themselves instead of
|
||||
relying on the canonical entry's migration to remove them.
|
||||
"""
|
||||
serial_number = "E072A1D90104"
|
||||
data = {
|
||||
"device": "/dev/serial/by-id/usb-Nabu_Casa_ZBT-2_E072A1D90104-if00",
|
||||
"firmware": "spinel",
|
||||
"firmware_version": (
|
||||
"SL-OPENTHREAD/2.7.2.0_GitHub-fb0446f53; EFR32; Feb 24 2026 00:58:55"
|
||||
),
|
||||
"manufacturer": "Nabu Casa",
|
||||
"pid": "831A",
|
||||
"product": "ZBT-2",
|
||||
"serial_number": serial_number,
|
||||
"vid": "303A",
|
||||
}
|
||||
|
||||
older_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id="303A:831A_E072A1D90104_Nabu Casa_ZBT-2 - Nabu Casa ZBT-2",
|
||||
source="usb",
|
||||
data=dict(data),
|
||||
version=1,
|
||||
minor_version=1,
|
||||
)
|
||||
older_entry.add_to_hass(hass)
|
||||
|
||||
duplicate_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id="303A:831A_E072A1D90104_Nabu Casa_ZBT-2",
|
||||
source="import",
|
||||
data=dict(data),
|
||||
version=1,
|
||||
minor_version=1,
|
||||
)
|
||||
duplicate_entry.add_to_hass(hass)
|
||||
|
||||
migrated_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id=serial_number,
|
||||
source="import",
|
||||
data=dict(data),
|
||||
version=1,
|
||||
minor_version=2,
|
||||
)
|
||||
migrated_entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.homeassistant_connect_zbt2.os.path.exists",
|
||||
return_value=True,
|
||||
):
|
||||
await async_setup_component(hass, DOMAIN, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
remaining_entries = hass.config_entries.async_entries(DOMAIN)
|
||||
assert len(remaining_entries) == 1
|
||||
assert remaining_entries[0].entry_id == migrated_entry.entry_id
|
||||
assert remaining_entries[0].minor_version == 2
|
||||
assert remaining_entries[0].unique_id == serial_number
|
||||
assert hass.config_entries.async_get_entry(older_entry.entry_id) is None
|
||||
assert hass.config_entries.async_get_entry(duplicate_entry.entry_id) is None
|
||||
|
||||
|
||||
async def test_setup_fails_on_missing_usb_port(hass: HomeAssistant) -> None:
|
||||
"""Test setup failing when the USB port is missing."""
|
||||
|
||||
|
||||
@@ -306,6 +306,79 @@ async def test_config_entry_migration_v5_prefers_active_entry(
|
||||
assert active_entry.unique_id == serial_number
|
||||
|
||||
|
||||
async def test_config_entry_migration_v5_removes_duplicates_of_migrated_entry(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test v1.5 migration removes duplicates of an already migrated entry.
|
||||
|
||||
A migrated entry (minor version 5) never runs the migration again, so the
|
||||
remaining minor version 4 duplicates have to remove themselves instead of
|
||||
relying on the canonical entry's migration to remove them.
|
||||
"""
|
||||
serial_number = "9e2adbd75b8beb119fe564a0f320645d"
|
||||
data = {
|
||||
"description": "SkyConnect v1.0",
|
||||
"device": (
|
||||
"/dev/serial/by-id/"
|
||||
"usb-Nabu_Casa_SkyConnect_v1.0_9e2adbd75b8beb119fe564a0f320645d-if00-port0"
|
||||
),
|
||||
"vid": "10C4",
|
||||
"pid": "EA60",
|
||||
"serial_number": serial_number,
|
||||
"manufacturer": "Nabu Casa",
|
||||
"product": "SkyConnect v1.0",
|
||||
"firmware": "ezsp",
|
||||
"firmware_version": "7.4.4.0",
|
||||
}
|
||||
|
||||
older_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id=(
|
||||
"10C4:EA60_9e2adbd75b8beb119fe564a0f320645d_Nabu Casa_SkyConnect v1.0"
|
||||
),
|
||||
source="usb",
|
||||
data=dict(data),
|
||||
version=1,
|
||||
minor_version=4,
|
||||
)
|
||||
older_entry.add_to_hass(hass)
|
||||
|
||||
duplicate_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id="10C4:EA60_9e2adbd75b8beb119fe564a0f320645d_Nabu_Casa_SkyConnect",
|
||||
source="import",
|
||||
data=dict(data),
|
||||
version=1,
|
||||
minor_version=4,
|
||||
)
|
||||
duplicate_entry.add_to_hass(hass)
|
||||
|
||||
migrated_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id=serial_number,
|
||||
source="import",
|
||||
data=dict(data),
|
||||
version=1,
|
||||
minor_version=5,
|
||||
)
|
||||
migrated_entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.homeassistant_sky_connect.os.path.exists",
|
||||
return_value=True,
|
||||
):
|
||||
await async_setup_component(hass, DOMAIN, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
remaining = hass.config_entries.async_entries(DOMAIN)
|
||||
assert len(remaining) == 1
|
||||
assert remaining[0].entry_id == migrated_entry.entry_id
|
||||
assert remaining[0].minor_version == 5
|
||||
assert remaining[0].unique_id == serial_number
|
||||
assert hass.config_entries.async_get_entry(older_entry.entry_id) is None
|
||||
assert hass.config_entries.async_get_entry(duplicate_entry.entry_id) is None
|
||||
|
||||
|
||||
async def test_setup_fails_on_missing_usb_port(hass: HomeAssistant) -> None:
|
||||
"""Test setup failing when the USB port is missing."""
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ from homeassistant import config as module_hass_config
|
||||
from homeassistant.components import mqtt
|
||||
from homeassistant.components.mqtt import debug_info
|
||||
from homeassistant.components.mqtt.const import (
|
||||
DOMAIN,
|
||||
MQTT_CONNECTION_STATE,
|
||||
SUPPORTED_COMPONENTS,
|
||||
)
|
||||
@@ -1004,12 +1005,10 @@ def help_custom_config(
|
||||
config: ConfigType = copy.deepcopy(mqtt_base_config)
|
||||
entity_instances: list[ConfigType] = []
|
||||
for instance in mqtt_entity_configs:
|
||||
base: ConfigType = copy.deepcopy(
|
||||
mqtt_base_config[mqtt.DOMAIN][mqtt_entity_domain]
|
||||
)
|
||||
base: ConfigType = copy.deepcopy(mqtt_base_config[DOMAIN][mqtt_entity_domain])
|
||||
base.update(instance)
|
||||
entity_instances.append(base)
|
||||
config[mqtt.DOMAIN][mqtt_entity_domain] = entity_instances
|
||||
config[DOMAIN][mqtt_entity_domain] = entity_instances
|
||||
return config
|
||||
|
||||
|
||||
@@ -1038,7 +1037,7 @@ async def help_test_availability_without_topic(
|
||||
config: ConfigType,
|
||||
) -> None:
|
||||
"""Test availability without defined availability topic."""
|
||||
assert "availability_topic" not in config[mqtt.DOMAIN][domain]
|
||||
assert "availability_topic" not in config[DOMAIN][domain]
|
||||
await mqtt_mock_entry()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
@@ -1061,7 +1060,7 @@ async def help_test_default_availability_payload(
|
||||
"""
|
||||
# Add availability settings to config
|
||||
config = copy.deepcopy(config)
|
||||
config[mqtt.DOMAIN][domain]["availability_topic"] = "availability-topic"
|
||||
config[DOMAIN][domain]["availability_topic"] = "availability-topic"
|
||||
|
||||
with patch("homeassistant.config.load_yaml_config_file", return_value=config):
|
||||
await mqtt_mock_entry()
|
||||
@@ -1108,7 +1107,7 @@ async def help_test_default_availability_list_payload(
|
||||
"""
|
||||
# Add availability settings to config
|
||||
config = copy.deepcopy(config)
|
||||
config[mqtt.DOMAIN][domain]["availability"] = [
|
||||
config[DOMAIN][domain]["availability"] = [
|
||||
{"topic": "availability-topic1"},
|
||||
{"topic": "availability-topic2"},
|
||||
]
|
||||
@@ -1167,8 +1166,8 @@ async def help_test_default_availability_list_payload_all(
|
||||
"""
|
||||
# Add availability settings to config
|
||||
config = copy.deepcopy(config)
|
||||
config[mqtt.DOMAIN][domain]["availability_mode"] = "all"
|
||||
config[mqtt.DOMAIN][domain]["availability"] = [
|
||||
config[DOMAIN][domain]["availability_mode"] = "all"
|
||||
config[DOMAIN][domain]["availability"] = [
|
||||
{"topic": "availability-topic1"},
|
||||
{"topic": "availability-topic2"},
|
||||
]
|
||||
@@ -1228,8 +1227,8 @@ async def help_test_default_availability_list_payload_any(
|
||||
"""
|
||||
# Add availability settings to config
|
||||
config = copy.deepcopy(config)
|
||||
config[mqtt.DOMAIN][domain]["availability_mode"] = "any"
|
||||
config[mqtt.DOMAIN][domain]["availability"] = [
|
||||
config[DOMAIN][domain]["availability_mode"] = "any"
|
||||
config[DOMAIN][domain]["availability"] = [
|
||||
{"topic": "availability-topic1"},
|
||||
{"topic": "availability-topic2"},
|
||||
]
|
||||
@@ -1284,10 +1283,10 @@ async def help_test_default_availability_list_single(
|
||||
"""
|
||||
# Add availability settings to config
|
||||
config = copy.deepcopy(config)
|
||||
config[mqtt.DOMAIN][domain]["availability"] = [
|
||||
config[DOMAIN][domain]["availability"] = [
|
||||
{"topic": "availability-topic1"},
|
||||
]
|
||||
config[mqtt.DOMAIN][domain]["availability_topic"] = "availability-topic"
|
||||
config[DOMAIN][domain]["availability_topic"] = "availability-topic"
|
||||
|
||||
with (
|
||||
patch("homeassistant.config.load_yaml_config_file", return_value=config),
|
||||
@@ -1316,9 +1315,9 @@ async def help_test_custom_availability_payload(
|
||||
"""
|
||||
# Add availability settings to config
|
||||
config = copy.deepcopy(config)
|
||||
config[mqtt.DOMAIN][domain]["availability_topic"] = "availability-topic"
|
||||
config[mqtt.DOMAIN][domain]["payload_available"] = "good"
|
||||
config[mqtt.DOMAIN][domain]["payload_not_available"] = "nogood"
|
||||
config[DOMAIN][domain]["availability_topic"] = "availability-topic"
|
||||
config[DOMAIN][domain]["payload_available"] = "good"
|
||||
config[DOMAIN][domain]["payload_not_available"] = "nogood"
|
||||
with patch("homeassistant.config.load_yaml_config_file", return_value=config):
|
||||
await mqtt_mock_entry()
|
||||
|
||||
@@ -1362,17 +1361,17 @@ async def help_test_discovery_update_availability(
|
||||
await mqtt_mock_entry()
|
||||
# Add availability settings to config
|
||||
config1 = copy.deepcopy(config)
|
||||
config1[mqtt.DOMAIN][domain]["availability_topic"] = "availability-topic1"
|
||||
config1[DOMAIN][domain]["availability_topic"] = "availability-topic1"
|
||||
config2 = copy.deepcopy(config)
|
||||
config2[mqtt.DOMAIN][domain]["availability"] = [
|
||||
config2[DOMAIN][domain]["availability"] = [
|
||||
{"topic": "availability-topic2"},
|
||||
{"topic": "availability-topic3"},
|
||||
]
|
||||
config3 = copy.deepcopy(config)
|
||||
config3[mqtt.DOMAIN][domain]["availability_topic"] = "availability-topic4"
|
||||
data1 = json.dumps(config1[mqtt.DOMAIN][domain])
|
||||
data2 = json.dumps(config2[mqtt.DOMAIN][domain])
|
||||
data3 = json.dumps(config3[mqtt.DOMAIN][domain])
|
||||
config3[DOMAIN][domain]["availability_topic"] = "availability-topic4"
|
||||
data1 = json.dumps(config1[DOMAIN][domain])
|
||||
data2 = json.dumps(config2[DOMAIN][domain])
|
||||
data3 = json.dumps(config3[DOMAIN][domain])
|
||||
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
@@ -1439,7 +1438,7 @@ async def help_test_setting_attribute_via_mqtt_json_message(
|
||||
"""
|
||||
# Add JSON attributes settings to config
|
||||
config = copy.deepcopy(config)
|
||||
config[mqtt.DOMAIN][domain]["json_attributes_topic"] = "attr-topic"
|
||||
config[DOMAIN][domain]["json_attributes_topic"] = "attr-topic"
|
||||
with patch("homeassistant.config.load_yaml_config_file", return_value=config):
|
||||
await mqtt_mock_entry()
|
||||
|
||||
@@ -1465,8 +1464,8 @@ async def help_test_setting_blocked_attribute_via_mqtt_json_message(
|
||||
|
||||
# Add JSON attributes settings to config
|
||||
config = copy.deepcopy(config)
|
||||
config[mqtt.DOMAIN][domain]["json_attributes_topic"] = "attr-topic"
|
||||
data = json.dumps(config[mqtt.DOMAIN][domain])
|
||||
config[DOMAIN][domain]["json_attributes_topic"] = "attr-topic"
|
||||
data = json.dumps(config[DOMAIN][domain])
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
val = "abc123"
|
||||
@@ -1494,8 +1493,8 @@ async def help_test_setting_attribute_with_template(
|
||||
"""
|
||||
# Add JSON attributes settings to config
|
||||
config = copy.deepcopy(config)
|
||||
config[mqtt.DOMAIN][domain]["json_attributes_topic"] = "attr-topic"
|
||||
config[mqtt.DOMAIN][domain]["json_attributes_template"] = (
|
||||
config[DOMAIN][domain]["json_attributes_topic"] = "attr-topic"
|
||||
config[DOMAIN][domain]["json_attributes_template"] = (
|
||||
"{{ value_json['Timer1'] | tojson }}"
|
||||
)
|
||||
with patch("homeassistant.config.load_yaml_config_file", return_value=config):
|
||||
@@ -1524,7 +1523,7 @@ async def help_test_update_with_json_attrs_not_dict(
|
||||
"""
|
||||
# Add JSON attributes settings to config
|
||||
config = copy.deepcopy(config)
|
||||
config[mqtt.DOMAIN][domain]["json_attributes_topic"] = "attr-topic"
|
||||
config[DOMAIN][domain]["json_attributes_topic"] = "attr-topic"
|
||||
with patch("homeassistant.config.load_yaml_config_file", return_value=config):
|
||||
await mqtt_mock_entry()
|
||||
|
||||
@@ -1548,7 +1547,7 @@ async def help_test_update_with_json_attrs_bad_json(
|
||||
"""
|
||||
# Add JSON attributes settings to config
|
||||
config = copy.deepcopy(config)
|
||||
config[mqtt.DOMAIN][domain]["json_attributes_topic"] = "attr-topic"
|
||||
config[DOMAIN][domain]["json_attributes_topic"] = "attr-topic"
|
||||
with patch("homeassistant.config.load_yaml_config_file", return_value=config):
|
||||
await mqtt_mock_entry()
|
||||
|
||||
@@ -1572,11 +1571,11 @@ async def help_test_discovery_update_attr(
|
||||
await mqtt_mock_entry()
|
||||
# Add JSON attributes settings to config
|
||||
config1 = copy.deepcopy(config)
|
||||
config1[mqtt.DOMAIN][domain]["json_attributes_topic"] = "attr-topic1"
|
||||
config1[DOMAIN][domain]["json_attributes_topic"] = "attr-topic1"
|
||||
config2 = copy.deepcopy(config)
|
||||
config2[mqtt.DOMAIN][domain]["json_attributes_topic"] = "attr-topic2"
|
||||
data1 = json.dumps(config1[mqtt.DOMAIN][domain])
|
||||
data2 = json.dumps(config2[mqtt.DOMAIN][domain])
|
||||
config2[DOMAIN][domain]["json_attributes_topic"] = "attr-topic2"
|
||||
data1 = json.dumps(config1[DOMAIN][domain])
|
||||
data2 = json.dumps(config2[DOMAIN][domain])
|
||||
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
@@ -1895,7 +1894,7 @@ async def help_test_entity_device_info_with_identifier(
|
||||
"""
|
||||
await mqtt_mock_entry()
|
||||
# Add device settings to config
|
||||
config = copy.deepcopy(config[mqtt.DOMAIN][domain])
|
||||
config = copy.deepcopy(config[DOMAIN][domain])
|
||||
config["device"] = copy.deepcopy(DEFAULT_CONFIG_DEVICE_INFO_ID)
|
||||
config["unique_id"] = "veryunique"
|
||||
|
||||
@@ -1931,7 +1930,7 @@ async def help_test_entity_device_info_with_connection(
|
||||
"""
|
||||
await mqtt_mock_entry()
|
||||
# Add device settings to config
|
||||
config = copy.deepcopy(config[mqtt.DOMAIN][domain])
|
||||
config = copy.deepcopy(config[DOMAIN][domain])
|
||||
config["device"] = copy.deepcopy(DEFAULT_CONFIG_DEVICE_INFO_MAC)
|
||||
config["unique_id"] = "veryunique"
|
||||
|
||||
@@ -1966,7 +1965,7 @@ async def help_test_entity_device_info_remove(
|
||||
"""Test device registry remove."""
|
||||
await mqtt_mock_entry()
|
||||
# Add device settings to config
|
||||
config = copy.deepcopy(config[mqtt.DOMAIN][domain])
|
||||
config = copy.deepcopy(config[DOMAIN][domain])
|
||||
config["device"] = copy.deepcopy(DEFAULT_CONFIG_DEVICE_INFO_ID)
|
||||
config["unique_id"] = "veryunique"
|
||||
|
||||
@@ -1979,14 +1978,14 @@ async def help_test_entity_device_info_remove(
|
||||
|
||||
device = dev_registry.async_get_device(identifiers={("mqtt", "helloworld")})
|
||||
assert device is not None
|
||||
assert ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, "veryunique")
|
||||
assert ent_registry.async_get_entity_id(domain, DOMAIN, "veryunique")
|
||||
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", "")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = dev_registry.async_get_device(identifiers={("mqtt", "helloworld")})
|
||||
assert device is None
|
||||
assert not ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, "veryunique")
|
||||
assert not ent_registry.async_get_entity_id(domain, DOMAIN, "veryunique")
|
||||
|
||||
|
||||
async def help_test_entity_device_info_update(
|
||||
@@ -2001,7 +2000,7 @@ async def help_test_entity_device_info_update(
|
||||
"""
|
||||
await mqtt_mock_entry()
|
||||
# Add device settings to config
|
||||
config = copy.deepcopy(config[mqtt.DOMAIN][domain])
|
||||
config = copy.deepcopy(config[DOMAIN][domain])
|
||||
config["device"] = copy.deepcopy(DEFAULT_CONFIG_DEVICE_INFO_ID)
|
||||
config["unique_id"] = "veryunique"
|
||||
|
||||
@@ -2039,7 +2038,7 @@ async def help_test_entity_name(
|
||||
"""
|
||||
await mqtt_mock_entry()
|
||||
# Add device settings to config
|
||||
config = copy.deepcopy(config[mqtt.DOMAIN][domain])
|
||||
config = copy.deepcopy(config[DOMAIN][domain])
|
||||
config["device"] = copy.deepcopy(DEFAULT_CONFIG_DEVICE_INFO_ID)
|
||||
config["unique_id"] = "veryunique"
|
||||
expected_entity_name = "test"
|
||||
@@ -2074,12 +2073,12 @@ async def help_test_entity_id_update_subscriptions(
|
||||
"""Test MQTT subscriptions are managed when entity_id is updated."""
|
||||
# Add unique_id to config
|
||||
config = copy.deepcopy(config)
|
||||
config[mqtt.DOMAIN][domain]["unique_id"] = "TOTALLY_UNIQUE"
|
||||
config[DOMAIN][domain]["unique_id"] = "TOTALLY_UNIQUE"
|
||||
|
||||
if topics is None:
|
||||
# Add default topics to config
|
||||
config[mqtt.DOMAIN][domain]["availability_topic"] = "avty-topic"
|
||||
config[mqtt.DOMAIN][domain]["state_topic"] = "test-topic"
|
||||
config[DOMAIN][domain]["availability_topic"] = "avty-topic"
|
||||
config[DOMAIN][domain]["state_topic"] = "test-topic"
|
||||
topics = ["avty-topic", "test-topic"]
|
||||
assert len(topics) > 0
|
||||
entity_registry = er.async_get(hass)
|
||||
@@ -2130,15 +2129,15 @@ async def help_test_entity_id_update_discovery_update(
|
||||
# Add unique_id to config
|
||||
await mqtt_mock_entry()
|
||||
config = copy.deepcopy(config)
|
||||
config[mqtt.DOMAIN][domain]["unique_id"] = "TOTALLY_UNIQUE"
|
||||
config[DOMAIN][domain]["unique_id"] = "TOTALLY_UNIQUE"
|
||||
|
||||
if topic is None:
|
||||
# Add default topic to config
|
||||
config[mqtt.DOMAIN][domain]["availability_topic"] = "avty-topic"
|
||||
config[DOMAIN][domain]["availability_topic"] = "avty-topic"
|
||||
topic = "avty-topic"
|
||||
|
||||
entity_registry = er.async_get(hass)
|
||||
data = json.dumps(config[mqtt.DOMAIN][domain])
|
||||
data = json.dumps(config[DOMAIN][domain])
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
@@ -2155,8 +2154,8 @@ async def help_test_entity_id_update_discovery_update(
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
config[mqtt.DOMAIN][domain]["availability_topic"] = f"{topic}_2"
|
||||
data = json.dumps(config[mqtt.DOMAIN][domain])
|
||||
config[DOMAIN][domain]["availability_topic"] = f"{topic}_2"
|
||||
data = json.dumps(config[DOMAIN][domain])
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
assert len(hass.states.async_entity_ids(domain)) == 1
|
||||
@@ -2178,7 +2177,7 @@ async def help_test_entity_debug_info(
|
||||
"""
|
||||
await mqtt_mock_entry()
|
||||
# Add device settings to config
|
||||
config = copy.deepcopy(config[mqtt.DOMAIN][domain])
|
||||
config = copy.deepcopy(config[DOMAIN][domain])
|
||||
config["device"] = copy.deepcopy(DEFAULT_CONFIG_DEVICE_INFO_ID)
|
||||
config["unique_id"] = "veryunique"
|
||||
config["platform"] = "mqtt"
|
||||
@@ -2219,7 +2218,7 @@ async def help_test_entity_debug_info_max_messages(
|
||||
"""
|
||||
await mqtt_mock_entry()
|
||||
# Add device settings to config
|
||||
config = copy.deepcopy(config[mqtt.DOMAIN][domain])
|
||||
config = copy.deepcopy(config[DOMAIN][domain])
|
||||
config["device"] = copy.deepcopy(DEFAULT_CONFIG_DEVICE_INFO_ID)
|
||||
config["unique_id"] = "veryunique"
|
||||
|
||||
@@ -2282,7 +2281,7 @@ async def help_test_entity_debug_info_message(
|
||||
"""
|
||||
# Add device settings to config
|
||||
await mqtt_mock_entry()
|
||||
config = copy.deepcopy(config[mqtt.DOMAIN][domain])
|
||||
config = copy.deepcopy(config[DOMAIN][domain])
|
||||
config["device"] = copy.deepcopy(DEFAULT_CONFIG_DEVICE_INFO_ID)
|
||||
config["unique_id"] = "veryunique"
|
||||
|
||||
@@ -2385,7 +2384,7 @@ async def help_test_entity_debug_info_remove(
|
||||
"""
|
||||
await mqtt_mock_entry()
|
||||
# Add device settings to config
|
||||
config = copy.deepcopy(config[mqtt.DOMAIN][domain])
|
||||
config = copy.deepcopy(config[DOMAIN][domain])
|
||||
config["device"] = copy.deepcopy(DEFAULT_CONFIG_DEVICE_INFO_ID)
|
||||
config["unique_id"] = "veryunique"
|
||||
config["platform"] = "mqtt"
|
||||
@@ -2438,7 +2437,7 @@ async def help_test_entity_debug_info_update_entity_id(
|
||||
"""
|
||||
await mqtt_mock_entry()
|
||||
# Add device settings to config
|
||||
config = copy.deepcopy(config[mqtt.DOMAIN][domain])
|
||||
config = copy.deepcopy(config[DOMAIN][domain])
|
||||
config["device"] = copy.deepcopy(DEFAULT_CONFIG_DEVICE_INFO_ID)
|
||||
config["unique_id"] = "veryunique"
|
||||
config["platform"] = "mqtt"
|
||||
@@ -2502,7 +2501,7 @@ async def help_test_entity_disabled_by_default(
|
||||
"""Test device registry remove."""
|
||||
await mqtt_mock_entry()
|
||||
# Add device settings to config
|
||||
config = copy.deepcopy(config[mqtt.DOMAIN][domain])
|
||||
config = copy.deepcopy(config[DOMAIN][domain])
|
||||
config["device"] = copy.deepcopy(DEFAULT_CONFIG_DEVICE_INFO_ID)
|
||||
config["enabled_by_default"] = False
|
||||
config["unique_id"] = "veryunique1"
|
||||
@@ -2514,7 +2513,7 @@ async def help_test_entity_disabled_by_default(
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla1/config", data)
|
||||
await hass.async_block_till_done()
|
||||
entity_id = ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, "veryunique1")
|
||||
entity_id = ent_registry.async_get_entity_id(domain, DOMAIN, "veryunique1")
|
||||
assert entity_id is not None and hass.states.get(entity_id) is None
|
||||
assert dev_registry.async_get_device(identifiers={("mqtt", "helloworld")})
|
||||
|
||||
@@ -2524,14 +2523,14 @@ async def help_test_entity_disabled_by_default(
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla2/config", data)
|
||||
await hass.async_block_till_done()
|
||||
entity_id = ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, "veryunique2")
|
||||
entity_id = ent_registry.async_get_entity_id(domain, DOMAIN, "veryunique2")
|
||||
assert entity_id is not None and hass.states.get(entity_id) is not None
|
||||
|
||||
# Remove the enabled entity, both entities and the device should be removed
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla2/config", "")
|
||||
await hass.async_block_till_done()
|
||||
assert not ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, "veryunique1")
|
||||
assert not ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, "veryunique2")
|
||||
assert not ent_registry.async_get_entity_id(domain, DOMAIN, "veryunique1")
|
||||
assert not ent_registry.async_get_entity_id(domain, DOMAIN, "veryunique2")
|
||||
assert not dev_registry.async_get_device(identifiers={("mqtt", "helloworld")})
|
||||
|
||||
|
||||
@@ -2544,7 +2543,7 @@ async def help_test_entity_category(
|
||||
"""Test device registry remove."""
|
||||
await mqtt_mock_entry()
|
||||
# Add device settings to config
|
||||
config = copy.deepcopy(config[mqtt.DOMAIN][domain])
|
||||
config = copy.deepcopy(config[DOMAIN][domain])
|
||||
config["device"] = copy.deepcopy(DEFAULT_CONFIG_DEVICE_INFO_ID)
|
||||
|
||||
ent_registry = er.async_get(hass)
|
||||
@@ -2555,7 +2554,7 @@ async def help_test_entity_category(
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/{unique_id}/config", data)
|
||||
await hass.async_block_till_done()
|
||||
entity_id = ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, unique_id)
|
||||
entity_id = ent_registry.async_get_entity_id(domain, DOMAIN, unique_id)
|
||||
assert entity_id is not None and hass.states.get(entity_id)
|
||||
entry = ent_registry.async_get(entity_id)
|
||||
assert entry is not None and entry.entity_category is None
|
||||
@@ -2567,7 +2566,7 @@ async def help_test_entity_category(
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/{unique_id}/config", data)
|
||||
await hass.async_block_till_done()
|
||||
entity_id = ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, unique_id)
|
||||
entity_id = ent_registry.async_get_entity_id(domain, DOMAIN, unique_id)
|
||||
assert entity_id is not None and hass.states.get(entity_id)
|
||||
entry = ent_registry.async_get(entity_id)
|
||||
assert entry is not None and entry.entity_category == EntityCategory.DIAGNOSTIC
|
||||
@@ -2579,7 +2578,7 @@ async def help_test_entity_category(
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/{unique_id}/config", data)
|
||||
await hass.async_block_till_done()
|
||||
assert not ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, unique_id)
|
||||
assert not ent_registry.async_get_entity_id(domain, DOMAIN, unique_id)
|
||||
|
||||
|
||||
async def help_test_entity_icon_and_entity_picture(
|
||||
@@ -2591,7 +2590,7 @@ async def help_test_entity_icon_and_entity_picture(
|
||||
"""Test entity picture and icon."""
|
||||
await mqtt_mock_entry()
|
||||
# Add device settings to config
|
||||
config = copy.deepcopy(config[mqtt.DOMAIN][domain])
|
||||
config = copy.deepcopy(config[DOMAIN][domain])
|
||||
config["device"] = copy.deepcopy(DEFAULT_CONFIG_DEVICE_INFO_ID)
|
||||
|
||||
ent_registry = er.async_get(hass)
|
||||
@@ -2602,7 +2601,7 @@ async def help_test_entity_icon_and_entity_picture(
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/{unique_id}/config", data)
|
||||
await hass.async_block_till_done()
|
||||
entity_id = ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, unique_id)
|
||||
entity_id = ent_registry.async_get_entity_id(domain, DOMAIN, unique_id)
|
||||
state = hass.states.get(entity_id)
|
||||
assert entity_id is not None and state
|
||||
assert state.attributes.get("icon") is None
|
||||
@@ -2615,7 +2614,7 @@ async def help_test_entity_icon_and_entity_picture(
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/{unique_id}/config", data)
|
||||
await hass.async_block_till_done()
|
||||
entity_id = ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, unique_id)
|
||||
entity_id = ent_registry.async_get_entity_id(domain, DOMAIN, unique_id)
|
||||
state = hass.states.get(entity_id)
|
||||
assert entity_id is not None and state
|
||||
assert state.attributes.get("icon") is None
|
||||
@@ -2629,7 +2628,7 @@ async def help_test_entity_icon_and_entity_picture(
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/{unique_id}/config", data)
|
||||
await hass.async_block_till_done()
|
||||
entity_id = ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, unique_id)
|
||||
entity_id = ent_registry.async_get_entity_id(domain, DOMAIN, unique_id)
|
||||
state = hass.states.get(entity_id)
|
||||
assert entity_id is not None and state
|
||||
assert state.attributes.get("icon") == "mdi:emoji-happy-outline"
|
||||
@@ -2662,7 +2661,7 @@ async def help_test_publishing_with_custom_encoding(
|
||||
setup_config = []
|
||||
service_data = {}
|
||||
for test_id, test_data in test_config.items():
|
||||
test_config_setup: dict[str, Any] = copy.copy(config[mqtt.DOMAIN][domain])
|
||||
test_config_setup: dict[str, Any] = copy.copy(config[DOMAIN][domain])
|
||||
test_config_setup.update(
|
||||
{
|
||||
topic: f"cmd/{test_id}",
|
||||
@@ -2802,7 +2801,7 @@ async def help_test_reloadable(
|
||||
) -> None:
|
||||
"""Test reloading an MQTT platform."""
|
||||
# Set up with empty config
|
||||
config = copy.deepcopy(config[mqtt.DOMAIN][domain])
|
||||
config = copy.deepcopy(config[DOMAIN][domain])
|
||||
# Create and test an old config of 2 entities based on the config supplied
|
||||
old_config_1 = copy.deepcopy(config)
|
||||
old_config_1["name"] = "test_old_1"
|
||||
@@ -2810,11 +2809,11 @@ async def help_test_reloadable(
|
||||
old_config_2["name"] = "test_old_2"
|
||||
|
||||
old_config = {
|
||||
mqtt.DOMAIN: {domain: [old_config_1, old_config_2]},
|
||||
DOMAIN: {domain: [old_config_1, old_config_2]},
|
||||
}
|
||||
# Start the MQTT entry with the old config
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={mqtt.CONF_BROKER: "test-broker"},
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
@@ -2838,7 +2837,7 @@ async def help_test_reloadable(
|
||||
new_config_extra["name"] = "test_new_3"
|
||||
|
||||
new_config = {
|
||||
mqtt.DOMAIN: {domain: [new_config_1, new_config_2, new_config_extra]},
|
||||
DOMAIN: {domain: [new_config_1, new_config_2, new_config_extra]},
|
||||
}
|
||||
with patch("homeassistant.config.load_yaml_config_file", return_value=new_config):
|
||||
# Reload the mqtt entry with the new config
|
||||
@@ -2859,7 +2858,7 @@ async def help_test_reloadable(
|
||||
|
||||
async def help_test_unload_config_entry(hass: HomeAssistant) -> None:
|
||||
"""Test unloading the MQTT config entry."""
|
||||
mqtt_config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
mqtt_config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
assert mqtt_config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
assert await hass.config_entries.async_unload(mqtt_config_entry.entry_id)
|
||||
@@ -2878,14 +2877,14 @@ async def help_test_unload_config_entry_with_platform(
|
||||
"""Test unloading the MQTT config entry with a specific platform domain."""
|
||||
# prepare setup through configuration.yaml
|
||||
config_setup: dict[str, dict[str, Any]] = copy.deepcopy(config)
|
||||
config_setup[mqtt.DOMAIN][domain]["name"] = "config_setup"
|
||||
config_setup[DOMAIN][domain]["name"] = "config_setup"
|
||||
config_name = config_setup
|
||||
|
||||
with patch("homeassistant.config.load_yaml_config_file", return_value=config_name):
|
||||
await mqtt_mock_entry()
|
||||
|
||||
# prepare setup through discovery
|
||||
discovery_setup = copy.deepcopy(config[mqtt.DOMAIN][domain])
|
||||
discovery_setup = copy.deepcopy(config[DOMAIN][domain])
|
||||
discovery_setup["name"] = "discovery_setup"
|
||||
async_fire_mqtt_message(
|
||||
hass, f"homeassistant/{domain}/bla/config", json.dumps(discovery_setup)
|
||||
|
||||
@@ -10,6 +10,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt
|
||||
from homeassistant.components.mqtt import DOMAIN
|
||||
from homeassistant.components.mqtt.models import MessageCallbackType, ReceiveMessage
|
||||
from homeassistant.components.mqtt.util import EnsureJobAfterCooldown
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_STARTED
|
||||
@@ -115,14 +116,14 @@ async def setup_with_birth_msg_client_mock(
|
||||
patch("homeassistant.components.mqtt.client.SUBSCRIBE_COOLDOWN", 0.0),
|
||||
):
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data=mqtt_config_entry_data or {mqtt.CONF_BROKER: "test-broker"},
|
||||
options=mqtt_config_entry_options or {},
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
hass.config.components.add(mqtt.DOMAIN)
|
||||
hass.config.components.add(DOMAIN)
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import alarm_control_panel, mqtt
|
||||
from homeassistant.components import alarm_control_panel
|
||||
from homeassistant.components.alarm_control_panel import (
|
||||
AlarmControlPanelEntityFeature,
|
||||
AlarmControlPanelState,
|
||||
@@ -16,6 +16,7 @@ from homeassistant.components.alarm_control_panel import (
|
||||
from homeassistant.components.mqtt.alarm_control_panel import (
|
||||
MQTT_ALARM_ATTRIBUTES_BLOCKED,
|
||||
)
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.mqtt.models import PublishPayloadType
|
||||
from homeassistant.const import (
|
||||
ATTR_CODE,
|
||||
@@ -83,7 +84,7 @@ DEFAULT_FEATURES = (
|
||||
)
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "alarm/state",
|
||||
@@ -93,7 +94,7 @@ DEFAULT_CONFIG = {
|
||||
}
|
||||
|
||||
DEFAULT_CONFIG_CODE_NOT_REQUIRED = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "alarm/state",
|
||||
@@ -104,7 +105,7 @@ DEFAULT_CONFIG_CODE_NOT_REQUIRED = {
|
||||
}
|
||||
|
||||
DEFAULT_CONFIG_CODE = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "alarm/state",
|
||||
@@ -116,7 +117,7 @@ DEFAULT_CONFIG_CODE = {
|
||||
}
|
||||
|
||||
DEFAULT_CONFIG_REMOTE_CODE = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "alarm/state",
|
||||
@@ -128,7 +129,7 @@ DEFAULT_CONFIG_REMOTE_CODE = {
|
||||
}
|
||||
|
||||
DEFAULT_CONFIG_REMOTE_CODE_TEXT = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "alarm/state",
|
||||
@@ -151,7 +152,7 @@ def does_not_raise():
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "alarm/command",
|
||||
@@ -162,7 +163,7 @@ def does_not_raise():
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "alarm/state",
|
||||
@@ -173,7 +174,7 @@ def does_not_raise():
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "alarm/command",
|
||||
@@ -753,7 +754,7 @@ async def test_disarm_publishes_mqtt_with_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
@@ -953,7 +954,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
alarm_control_panel.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -983,7 +984,7 @@ async def test_discovery_removal_alarm(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test removal of discovered alarm_control_panel."""
|
||||
data = json.dumps(DEFAULT_CONFIG[mqtt.DOMAIN][alarm_control_panel.DOMAIN])
|
||||
data = json.dumps(DEFAULT_CONFIG[DOMAIN][alarm_control_panel.DOMAIN])
|
||||
await help_test_discovery_removal(
|
||||
hass, mqtt_mock_entry, alarm_control_panel.DOMAIN, data
|
||||
)
|
||||
@@ -993,8 +994,8 @@ async def test_discovery_update_alarm_topic_and_template(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test update of discovered alarm_control_panel."""
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][alarm_control_panel.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][alarm_control_panel.DOMAIN])
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][alarm_control_panel.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][alarm_control_panel.DOMAIN])
|
||||
config1["name"] = "Beer"
|
||||
config2["name"] = "Milk"
|
||||
config1["state_topic"] = "alarm/state1"
|
||||
@@ -1027,8 +1028,8 @@ async def test_discovery_update_alarm_template(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test update of discovered alarm_control_panel."""
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][alarm_control_panel.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][alarm_control_panel.DOMAIN])
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][alarm_control_panel.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][alarm_control_panel.DOMAIN])
|
||||
config1["name"] = "Beer"
|
||||
config2["name"] = "Milk"
|
||||
config1["state_topic"] = "alarm/state1"
|
||||
@@ -1059,7 +1060,7 @@ async def test_discovery_update_unchanged_alarm(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test update of discovered alarm_control_panel."""
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][alarm_control_panel.DOMAIN])
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][alarm_control_panel.DOMAIN])
|
||||
config1["name"] = "Beer"
|
||||
|
||||
data1 = json.dumps(config1)
|
||||
@@ -1109,7 +1110,7 @@ async def test_encoding_subscribable_topics(
|
||||
hass,
|
||||
mqtt_mock_entry,
|
||||
alarm_control_panel.DOMAIN,
|
||||
DEFAULT_CONFIG[mqtt.DOMAIN][alarm_control_panel.DOMAIN],
|
||||
DEFAULT_CONFIG[DOMAIN][alarm_control_panel.DOMAIN],
|
||||
topic,
|
||||
value,
|
||||
)
|
||||
|
||||
@@ -11,7 +11,8 @@ from freezegun import freeze_time
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import binary_sensor, mqtt
|
||||
from homeassistant.components import binary_sensor
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.const import (
|
||||
EVENT_STATE_CHANGED,
|
||||
STATE_OFF,
|
||||
@@ -63,7 +64,7 @@ from tests.common import (
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -76,7 +77,7 @@ DEFAULT_CONFIG = {
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -111,7 +112,7 @@ async def test_setting_sensor_value_expires_availability_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -288,7 +289,7 @@ async def test_expiration_on_discovery_and_discovery_update_of_binary_sensor(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -326,7 +327,7 @@ async def test_setting_sensor_value_via_mqtt_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -370,7 +371,7 @@ async def test_invalid_sensor_value_via_mqtt_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -405,7 +406,7 @@ async def test_setting_sensor_value_via_mqtt_message_and_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -446,7 +447,7 @@ async def test_setting_sensor_value_via_mqtt_message_and_template2(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"encoding": "",
|
||||
@@ -485,7 +486,7 @@ async def test_setting_sensor_value_via_mqtt_msg_and_template_and_raw_state_enco
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -520,7 +521,7 @@ async def test_setting_sensor_value_via_mqtt_message_empty_template(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"device_class": "motion",
|
||||
@@ -532,7 +533,7 @@ async def test_setting_sensor_value_via_mqtt_message_empty_template(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"device_class": None,
|
||||
@@ -560,7 +561,7 @@ async def test_valid_device_class(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"device_class": "abc123",
|
||||
@@ -622,7 +623,7 @@ async def test_custom_availability_payload(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -661,7 +662,7 @@ async def test_force_update_disabled(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -701,7 +702,7 @@ async def test_force_update_enabled(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -801,7 +802,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
binary_sensor.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -829,7 +830,7 @@ async def test_discovery_removal_binary_sensor(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test removal of discovered binary_sensor."""
|
||||
data = json.dumps(DEFAULT_CONFIG[mqtt.DOMAIN][binary_sensor.DOMAIN])
|
||||
data = json.dumps(DEFAULT_CONFIG[DOMAIN][binary_sensor.DOMAIN])
|
||||
await help_test_discovery_removal(hass, mqtt_mock_entry, binary_sensor.DOMAIN, data)
|
||||
|
||||
|
||||
@@ -837,8 +838,8 @@ async def test_discovery_update_binary_sensor_topic_template(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test update of discovered binary_sensor."""
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][binary_sensor.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][binary_sensor.DOMAIN])
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][binary_sensor.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][binary_sensor.DOMAIN])
|
||||
config1["name"] = "Beer"
|
||||
config2["name"] = "Milk"
|
||||
config1["state_topic"] = "sensor/state1"
|
||||
@@ -873,8 +874,8 @@ async def test_discovery_update_binary_sensor_template(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test update of discovered binary_sensor."""
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][binary_sensor.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][binary_sensor.DOMAIN])
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][binary_sensor.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][binary_sensor.DOMAIN])
|
||||
config1["name"] = "Beer"
|
||||
config2["name"] = "Milk"
|
||||
config1["state_topic"] = "sensor/state1"
|
||||
@@ -929,7 +930,7 @@ async def test_encoding_subscribable_topics(
|
||||
hass,
|
||||
mqtt_mock_entry,
|
||||
binary_sensor.DOMAIN,
|
||||
DEFAULT_CONFIG[mqtt.DOMAIN][binary_sensor.DOMAIN],
|
||||
DEFAULT_CONFIG[DOMAIN][binary_sensor.DOMAIN],
|
||||
topic,
|
||||
value,
|
||||
attribute,
|
||||
@@ -941,7 +942,7 @@ async def test_discovery_update_unchanged_binary_sensor(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test update of discovered binary_sensor."""
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][binary_sensor.DOMAIN])
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][binary_sensor.DOMAIN])
|
||||
config1["name"] = "Beer"
|
||||
|
||||
data1 = json.dumps(config1)
|
||||
@@ -1097,9 +1098,7 @@ async def test_cleanup_triggers_and_restoring_state(
|
||||
|
||||
freezer.move_to("2022-02-02 12:01:10+01:00")
|
||||
|
||||
await help_test_reload_with_config(
|
||||
hass, caplog, tmp_path, {mqtt.DOMAIN: hass_config}
|
||||
)
|
||||
await help_test_reload_with_config(hass, caplog, tmp_path, {DOMAIN: hass_config})
|
||||
|
||||
state = hass.states.get("binary_sensor.test1")
|
||||
assert state.state == state1
|
||||
@@ -1137,7 +1136,7 @@ async def test_skip_restoring_state_with_over_due_expire_trigger(
|
||||
|
||||
freezer.move_to("2022-02-02 12:02:00+01:00")
|
||||
domain = binary_sensor.DOMAIN
|
||||
config3: ConfigType = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][domain])
|
||||
config3: ConfigType = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][domain])
|
||||
config3["name"] = "test3"
|
||||
config3["expire_after"] = 10
|
||||
config3["state_topic"] = "test-topic3"
|
||||
|
||||
@@ -6,7 +6,8 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import button, mqtt
|
||||
from homeassistant.components import button
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.const import ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME, STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
@@ -42,7 +43,7 @@ from .common import (
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {button.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
DOMAIN: {button.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +52,7 @@ DEFAULT_CONFIG = {
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
button.DOMAIN: {
|
||||
"command_topic": "command-topic",
|
||||
"name": "test",
|
||||
@@ -93,7 +94,7 @@ async def test_sending_mqtt_commands(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
button.DOMAIN: {
|
||||
"command_topic": "command-topic",
|
||||
"name": "test",
|
||||
@@ -110,7 +111,7 @@ async def test_sending_mqtt_commands(
|
||||
}
|
||||
},
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
button.DOMAIN: {
|
||||
"command_topic": "command-topic",
|
||||
"name": "test",
|
||||
@@ -152,7 +153,7 @@ async def test_sending_mqtt_commands_with_message_expiry_interval(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
button.DOMAIN: {
|
||||
"command_topic": "command-topic",
|
||||
"command_template": '{ "{{ value }}": "{{ entity_id }}" }',
|
||||
@@ -215,7 +216,7 @@ async def test_default_availability_payload(
|
||||
) -> None:
|
||||
"""Test availability by default payload with defined topic."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
button.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -233,7 +234,7 @@ async def test_custom_availability_payload(
|
||||
) -> None:
|
||||
"""Test availability by custom payload with defined topic."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
button.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -309,7 +310,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
button.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -345,8 +346,8 @@ async def test_discovery_update_button(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test update of discovered button."""
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][button.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][button.DOMAIN])
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][button.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][button.DOMAIN])
|
||||
config1["name"] = "Beer"
|
||||
config2["name"] = "Milk"
|
||||
|
||||
@@ -446,7 +447,7 @@ async def test_entity_debug_info_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
button.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
@@ -470,7 +471,7 @@ async def test_invalid_device_class(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
button.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
|
||||
@@ -7,8 +7,9 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import camera, mqtt
|
||||
from homeassistant.components import camera
|
||||
from homeassistant.components.mqtt.camera import MQTT_CAMERA_ATTRIBUTES_BLOCKED
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from .common import (
|
||||
@@ -45,12 +46,12 @@ from tests.typing import (
|
||||
MqttMockPahoClient,
|
||||
)
|
||||
|
||||
DEFAULT_CONFIG = {mqtt.DOMAIN: {camera.DOMAIN: {"name": "test", "topic": "test_topic"}}}
|
||||
DEFAULT_CONFIG = {DOMAIN: {camera.DOMAIN: {"name": "test", "topic": "test_topic"}}}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config",
|
||||
[{mqtt.DOMAIN: {camera.DOMAIN: {"topic": "test/camera", "name": "Test Camera"}}}],
|
||||
[{DOMAIN: {camera.DOMAIN: {"topic": "test/camera", "name": "Test Camera"}}}],
|
||||
)
|
||||
async def test_run_camera_setup(
|
||||
hass: HomeAssistant,
|
||||
@@ -76,7 +77,7 @@ async def test_run_camera_setup(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
camera.DOMAIN: {
|
||||
"topic": "test/camera",
|
||||
"name": "Test Camera",
|
||||
@@ -110,7 +111,7 @@ async def test_run_camera_b64_encoded(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
"camera": {
|
||||
"topic": "test/camera",
|
||||
"name": "Test Camera",
|
||||
@@ -250,7 +251,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
camera.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -278,7 +279,7 @@ async def test_discovery_removal_camera(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test removal of discovered camera."""
|
||||
data = json.dumps(DEFAULT_CONFIG[mqtt.DOMAIN][camera.DOMAIN])
|
||||
data = json.dumps(DEFAULT_CONFIG[DOMAIN][camera.DOMAIN])
|
||||
await help_test_discovery_removal(hass, mqtt_mock_entry, camera.DOMAIN, data)
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import pytest
|
||||
|
||||
from homeassistant.components import mqtt
|
||||
from homeassistant.components.mqtt.client import RECONNECT_INTERVAL_SECONDS
|
||||
from homeassistant.components.mqtt.const import SUPPORTED_COMPONENTS
|
||||
from homeassistant.components.mqtt.const import DOMAIN, SUPPORTED_COMPONENTS
|
||||
from homeassistant.components.mqtt.models import MessageCallbackType, ReceiveMessage
|
||||
from homeassistant.config_entries import ConfigEntryDisabler, ConfigEntryState
|
||||
from homeassistant.const import (
|
||||
@@ -99,7 +99,7 @@ async def test_mqtt_await_ack_at_disconnect(hass: HomeAssistant) -> None:
|
||||
)
|
||||
mqtt_client.publish = MagicMock(return_value=FakeInfo())
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={
|
||||
"certificate": "auto",
|
||||
mqtt.CONF_BROKER: "test-broker",
|
||||
@@ -276,7 +276,7 @@ async def test_message_expiry_interval_fails_for_legacy_protocols(
|
||||
await mqtt.async_publish(
|
||||
hass, "test-topic", "test-payload", 2, True, message_expiry_interval=60
|
||||
)
|
||||
assert exc.value.translation_domain == mqtt.DOMAIN
|
||||
assert exc.value.translation_domain == DOMAIN
|
||||
assert exc.value.translation_key == "mqtt_message_expiry_interval_not_supported"
|
||||
assert exc.value.translation_placeholders == {
|
||||
"topic": "test-topic",
|
||||
@@ -399,7 +399,7 @@ async def test_subscribe_mqtt_config_entry_disabled(
|
||||
"""Test the subscription of a topic when MQTT config entry is disabled."""
|
||||
mqtt_mock.connected = True
|
||||
|
||||
mqtt_config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
mqtt_config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
|
||||
mqtt_config_entry_state = mqtt_config_entry.state
|
||||
assert mqtt_config_entry_state is ConfigEntryState.LOADED
|
||||
@@ -1340,7 +1340,7 @@ async def test_initial_setup_logs_error(
|
||||
) -> None:
|
||||
"""Test for setup failure if initial client connection fails."""
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={mqtt.CONF_BROKER: "test-broker"},
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
@@ -1487,7 +1487,7 @@ async def test_publish_error(
|
||||
) -> None:
|
||||
"""Test publish error."""
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={mqtt.CONF_BROKER: "test-broker"},
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
@@ -1681,7 +1681,7 @@ async def test_handle_mqtt_timeout_on_callback(
|
||||
)
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={mqtt.CONF_BROKER: "test-broker"},
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
@@ -1718,7 +1718,7 @@ async def test_setup_raises_config_entry_not_ready_if_no_connect_broker(
|
||||
) -> None:
|
||||
"""Test for setup failure if connection to broker is missing."""
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={mqtt.CONF_BROKER: "test-broker"},
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
@@ -1863,14 +1863,14 @@ async def test_custom_birth_message(
|
||||
"""Test sending birth message."""
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data=mqtt_config_entry_data,
|
||||
options=mqtt_config_entry_options,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
hass.config.components.add(mqtt.DOMAIN)
|
||||
hass.config.components.add(DOMAIN)
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
mock_debouncer.clear()
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
||||
@@ -1913,14 +1913,14 @@ async def test_no_birth_message(
|
||||
) -> None:
|
||||
"""Test disabling birth message."""
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data=mqtt_config_entry_data,
|
||||
options=mqtt_config_entry_options,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
hass.config.components.add(mqtt.DOMAIN)
|
||||
hass.config.components.add(DOMAIN)
|
||||
mock_debouncer.clear()
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
# Wait for discovery cooldown
|
||||
@@ -1953,14 +1953,14 @@ async def test_delayed_birth_message(
|
||||
await hass.async_block_till_done()
|
||||
birth = asyncio.Event()
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data=mqtt_config_entry_data,
|
||||
options=mqtt_config_entry_options,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
hass.config.components.add(mqtt.DOMAIN)
|
||||
hass.config.components.add(DOMAIN)
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
|
||||
@callback
|
||||
@@ -2033,14 +2033,14 @@ async def test_custom_will_message(
|
||||
) -> None:
|
||||
"""Test will message."""
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data=mqtt_config_entry_data,
|
||||
options=mqtt_config_entry_options,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
hass.config.components.add(mqtt.DOMAIN)
|
||||
hass.config.components.add(DOMAIN)
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
@@ -2071,14 +2071,14 @@ async def test_no_will_message(
|
||||
) -> None:
|
||||
"""Test will message."""
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data=mqtt_config_entry_data,
|
||||
options=mqtt_config_entry_options,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
hass.config.components.add(mqtt.DOMAIN)
|
||||
hass.config.components.add(DOMAIN)
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
@@ -2619,7 +2619,7 @@ async def test_subscriptions_id_generation(hass: HomeAssistant) -> None:
|
||||
assert new_id_3 == mqtt.models.MAX_28BIT
|
||||
with pytest.raises(HomeAssistantError) as exc:
|
||||
generator.get_or_generate("test4/#")
|
||||
assert exc.value.translation_domain == mqtt.DOMAIN
|
||||
assert exc.value.translation_domain == DOMAIN
|
||||
assert exc.value.translation_key == "mqtt_max_subscription_id_reached"
|
||||
|
||||
generator.release("test2/#")
|
||||
@@ -2629,7 +2629,7 @@ async def test_subscriptions_id_generation(hass: HomeAssistant) -> None:
|
||||
|
||||
with pytest.raises(HomeAssistantError) as exc:
|
||||
generator.get_or_generate("test5/#")
|
||||
assert exc.value.translation_domain == mqtt.DOMAIN
|
||||
assert exc.value.translation_domain == DOMAIN
|
||||
assert exc.value.translation_key == "mqtt_max_subscription_id_reached"
|
||||
|
||||
generator.release("test1/#")
|
||||
@@ -2642,5 +2642,5 @@ async def test_subscriptions_id_generation(hass: HomeAssistant) -> None:
|
||||
|
||||
with pytest.raises(HomeAssistantError) as exc:
|
||||
generator.get_or_generate("test7/#")
|
||||
assert exc.value.translation_domain == mqtt.DOMAIN
|
||||
assert exc.value.translation_domain == DOMAIN
|
||||
assert exc.value.translation_key == "mqtt_max_subscription_id_reached"
|
||||
|
||||
@@ -8,7 +8,7 @@ from unittest.mock import call, patch
|
||||
import pytest
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components import climate, mqtt
|
||||
from homeassistant.components import climate
|
||||
from homeassistant.components.climate import (
|
||||
ATTR_CURRENT_HUMIDITY,
|
||||
ATTR_CURRENT_TEMPERATURE,
|
||||
@@ -34,6 +34,7 @@ from homeassistant.components.mqtt.climate import (
|
||||
)
|
||||
from homeassistant.components.mqtt.const import (
|
||||
DEFAULT_CLIMATE_INITIAL_TEMPERATURE as DEFAULT_INITIAL_TEMPERATURE,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.const import ATTR_TEMPERATURE, STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
@@ -83,7 +84,7 @@ from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
ENTITY_CLIMATE = "climate.test"
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
climate.DOMAIN: {
|
||||
"name": "test",
|
||||
"mode_command_topic": "mode-topic",
|
||||
@@ -1421,7 +1422,7 @@ async def test_get_target_temperature_low_high_with_templates(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
climate.DOMAIN: {
|
||||
"name": "test",
|
||||
"mode_command_topic": "mode-topic",
|
||||
@@ -1588,7 +1589,7 @@ async def test_get_with_templates(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
climate.DOMAIN: {
|
||||
"name": "test",
|
||||
"mode_command_topic": "mode-topic",
|
||||
@@ -2021,7 +2022,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
climate.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -2074,7 +2075,7 @@ async def test_encoding_subscribable_topics(
|
||||
attribute_value: Any,
|
||||
) -> None:
|
||||
"""Test handling of incoming encoded payload."""
|
||||
config = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][climate.DOMAIN])
|
||||
config = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][climate.DOMAIN])
|
||||
await help_test_encoding_subscribable_topics(
|
||||
hass,
|
||||
mqtt_mock_entry,
|
||||
@@ -2091,7 +2092,7 @@ async def test_discovery_removal_climate(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test removal of discovered climate."""
|
||||
data = json.dumps(DEFAULT_CONFIG[mqtt.DOMAIN][climate.DOMAIN])
|
||||
data = json.dumps(DEFAULT_CONFIG[DOMAIN][climate.DOMAIN])
|
||||
await help_test_discovery_removal(hass, mqtt_mock_entry, climate.DOMAIN, data)
|
||||
|
||||
|
||||
@@ -2172,7 +2173,7 @@ async def test_entity_id_update_subscriptions(
|
||||
) -> None:
|
||||
"""Test MQTT subscriptions are managed when entity_id is updated."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
climate.DOMAIN: {
|
||||
"name": "test",
|
||||
"mode_state_topic": "test-topic",
|
||||
@@ -2199,7 +2200,7 @@ async def test_entity_debug_info_message(
|
||||
) -> None:
|
||||
"""Test MQTT debug info."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
climate.DOMAIN: {
|
||||
"name": "test",
|
||||
"mode_command_topic": "command-topic",
|
||||
@@ -2362,8 +2363,8 @@ async def test_publishing_with_custom_encoding(
|
||||
domain = climate.DOMAIN
|
||||
config = copy.deepcopy(DEFAULT_CONFIG)
|
||||
if topic != "preset_mode_command_topic":
|
||||
del config[mqtt.DOMAIN][domain]["preset_mode_command_topic"]
|
||||
del config[mqtt.DOMAIN][domain]["preset_modes"]
|
||||
del config[DOMAIN][domain]["preset_mode_command_topic"]
|
||||
del config[DOMAIN][domain]["preset_modes"]
|
||||
|
||||
await help_test_publishing_with_custom_encoding(
|
||||
hass,
|
||||
@@ -2384,7 +2385,7 @@ async def test_publishing_with_custom_encoding(
|
||||
[
|
||||
( # test_valid_humidity_min_max
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
climate.DOMAIN: {
|
||||
"name": "test",
|
||||
"min_humidity": 20,
|
||||
@@ -2396,7 +2397,7 @@ async def test_publishing_with_custom_encoding(
|
||||
),
|
||||
( # test_invalid_humidity_min_max_1
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
climate.DOMAIN: {
|
||||
"name": "test",
|
||||
"min_humidity": 0,
|
||||
@@ -2408,7 +2409,7 @@ async def test_publishing_with_custom_encoding(
|
||||
),
|
||||
( # test_invalid_humidity_min_max_2
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
climate.DOMAIN: {
|
||||
"name": "test",
|
||||
"max_humidity": 20,
|
||||
@@ -2420,7 +2421,7 @@ async def test_publishing_with_custom_encoding(
|
||||
),
|
||||
( # test_valid_humidity_state
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
climate.DOMAIN: {
|
||||
"name": "test",
|
||||
"target_humidity_state_topic": "humidity-state",
|
||||
@@ -2432,7 +2433,7 @@ async def test_publishing_with_custom_encoding(
|
||||
),
|
||||
( # test_invalid_humidity_state
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
climate.DOMAIN: {
|
||||
"name": "test",
|
||||
"target_humidity_state_topic": "humidity-state",
|
||||
|
||||
@@ -21,7 +21,7 @@ from homeassistant.components.mqtt.config_flow import (
|
||||
PWD_NOT_CHANGED,
|
||||
TRANSLATION_DESCRIPTION_PLACEHOLDERS,
|
||||
)
|
||||
from homeassistant.components.mqtt.const import CONF_DISCOVERY_QOS
|
||||
from homeassistant.components.mqtt.const import CONF_DISCOVERY_QOS, DOMAIN
|
||||
from homeassistant.components.mqtt.util import learn_more_url
|
||||
from homeassistant.config_entries import ConfigSubentry, ConfigSubentryData
|
||||
from homeassistant.const import (
|
||||
@@ -541,7 +541,7 @@ async def test_manual_config_set(
|
||||
)
|
||||
# Check config entry got setup
|
||||
assert len(mock_finish_setup.mock_calls) == 1
|
||||
config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
assert config_entry.title == "127.0.0.1"
|
||||
|
||||
|
||||
@@ -563,7 +563,7 @@ async def test_user_single_instance(hass: HomeAssistant) -> None:
|
||||
async def test_hassio_already_configured(hass: HomeAssistant) -> None:
|
||||
"""Test we only allow a single config flow."""
|
||||
MockConfigEntry(
|
||||
domain="mqtt",
|
||||
domain=DOMAIN,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
).add_to_hass(hass)
|
||||
@@ -578,14 +578,14 @@ async def test_hassio_already_configured(hass: HomeAssistant) -> None:
|
||||
async def test_hassio_ignored(hass: HomeAssistant) -> None:
|
||||
"""Test we supervisor discovered instance can be ignored."""
|
||||
MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
source=config_entries.SOURCE_IGNORE,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
).add_to_hass(hass)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
mqtt.DOMAIN,
|
||||
DOMAIN,
|
||||
data=HassioServiceInfo(
|
||||
config={
|
||||
"addon": "Mosquitto",
|
||||
@@ -1101,7 +1101,7 @@ async def test_option_flow(
|
||||
"homeassistant.config.async_hass_config_yaml", AsyncMock(return_value={})
|
||||
) as yaml_mock:
|
||||
await mqtt_mock_entry()
|
||||
config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
@@ -1258,7 +1258,7 @@ async def test_bad_certificate(
|
||||
test_input.pop(mqtt.CONF_CLIENT_KEY)
|
||||
|
||||
mqtt_mock = await mqtt_mock_entry()
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
# Add at least one advanced option to get the full form
|
||||
hass.config_entries.async_update_entry(
|
||||
config_entry,
|
||||
@@ -1335,7 +1335,7 @@ async def test_keepalive_validation(
|
||||
|
||||
mqtt_mock = await mqtt_mock_entry()
|
||||
mock_try_connection.return_value = True
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
# Add at least one advanced option to get the full form
|
||||
hass.config_entries.async_update_entry(
|
||||
config_entry,
|
||||
@@ -1376,7 +1376,7 @@ async def test_disable_birth_will(
|
||||
"""Test disabling birth and will."""
|
||||
await mqtt_mock_entry()
|
||||
mock_try_connection.return_value = True
|
||||
config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
hass.config_entries.async_update_entry(
|
||||
config_entry,
|
||||
data={
|
||||
@@ -1441,7 +1441,7 @@ async def test_invalid_discovery_prefix(
|
||||
"""Test setting an invalid discovery prefix."""
|
||||
mqtt_mock = await mqtt_mock_entry()
|
||||
mock_try_connection.return_value = True
|
||||
config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
hass.config_entries.async_update_entry(
|
||||
config_entry,
|
||||
data={
|
||||
@@ -1506,7 +1506,7 @@ async def test_option_flow_default_suggested_values(
|
||||
) -> None:
|
||||
"""Test config flow options has default/suggested values."""
|
||||
await mqtt_mock_entry()
|
||||
config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
hass.config_entries.async_update_entry(
|
||||
config_entry,
|
||||
data={
|
||||
@@ -1653,7 +1653,7 @@ async def test_step_reauth(
|
||||
|
||||
# Prepare the config entry
|
||||
config_entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data=test_input,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
@@ -1734,7 +1734,7 @@ async def test_step_hassio_reauth(
|
||||
|
||||
# Prepare the config entry
|
||||
config_entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data=entry_data,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
@@ -1822,7 +1822,7 @@ async def test_step_hassio_reauth_no_discovery_info(
|
||||
|
||||
# Prepare the config entry
|
||||
config_entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data=entry_data,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
@@ -1853,7 +1853,7 @@ async def test_reconfigure_user_connection_fails(
|
||||
) -> None:
|
||||
"""Test if connection cannot be made."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
)
|
||||
@@ -1891,7 +1891,7 @@ async def test_options_bad_birth_message_fails(
|
||||
) -> None:
|
||||
"""Test bad birth message."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
)
|
||||
@@ -1929,7 +1929,7 @@ async def test_options_bad_will_message_fails(
|
||||
) -> None:
|
||||
"""Test bad will message."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
)
|
||||
@@ -1974,7 +1974,7 @@ async def test_try_connection_with_advanced_parameters(
|
||||
) -> None:
|
||||
"""Test config flow with advanced parameters from config."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
)
|
||||
@@ -2112,7 +2112,7 @@ async def test_setup_with_advanced_settings(
|
||||
file_id = mock_process_uploaded_file.file_id
|
||||
|
||||
config_entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
)
|
||||
@@ -2298,7 +2298,7 @@ async def test_setup_with_certificates(
|
||||
file_id = mock_process_uploaded_file.file_id
|
||||
|
||||
config_entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
)
|
||||
@@ -2419,7 +2419,7 @@ async def test_change_websockets_transport_to_tcp(
|
||||
) -> None:
|
||||
"""Test reconfiguration flow changing websockets transport settings."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
)
|
||||
@@ -2488,7 +2488,7 @@ async def test_reconfigure_flow_form(
|
||||
) -> None:
|
||||
"""Test reconfigure flow."""
|
||||
await mqtt_mock_entry()
|
||||
entry: MockConfigEntry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
entry: MockConfigEntry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
result = await entry.start_reconfigure_flow(hass)
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "broker"
|
||||
@@ -2542,7 +2542,7 @@ async def test_reconfigure_no_changed_password(
|
||||
) -> None:
|
||||
"""Test reconfigure flow."""
|
||||
await mqtt_mock_entry()
|
||||
entry: MockConfigEntry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
entry: MockConfigEntry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
result = await entry.start_reconfigure_flow(hass)
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "broker"
|
||||
@@ -2603,7 +2603,7 @@ async def test_migrate_config_entry(
|
||||
expected_minor_version: int,
|
||||
) -> None:
|
||||
"""Test migrating a config entry."""
|
||||
config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
# Mock to a migratable or compatbible config entry version
|
||||
hass.config_entries.async_update_entry(
|
||||
config_entry,
|
||||
@@ -2645,7 +2645,7 @@ async def test_migrate_of_incompatible_config_entry(
|
||||
options: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test migrating a config entry."""
|
||||
config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
# Mock an incompatible config entry version
|
||||
hass.config_entries.async_update_entry(
|
||||
config_entry,
|
||||
@@ -4109,7 +4109,7 @@ async def test_subentry_configflow(
|
||||
component = next(iter(config_subentries_data["components"].values()))
|
||||
|
||||
await mqtt_mock_entry()
|
||||
config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
|
||||
result = await hass.config_entries.subentries.async_init(
|
||||
(config_entry.entry_id, "device"),
|
||||
@@ -4266,7 +4266,7 @@ async def test_subentry_reconfigure_remove_entity(
|
||||
) -> None:
|
||||
"""Test the subentry ConfigFlow reconfigure removing an entity."""
|
||||
await mqtt_mock_entry()
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
subentry_id: str
|
||||
subentry: ConfigSubentry
|
||||
subentry_id, subentry = next(iter(config_entry.subentries.items()))
|
||||
@@ -4275,7 +4275,7 @@ async def test_subentry_reconfigure_remove_entity(
|
||||
assert result["step_id"] == "summary_menu"
|
||||
|
||||
# assert we have a device for the subentry
|
||||
device = device_registry.async_get_device(identifiers={(mqtt.DOMAIN, subentry_id)})
|
||||
device = device_registry.async_get_device(identifiers={(DOMAIN, subentry_id)})
|
||||
assert device is not None
|
||||
|
||||
# assert we have an entity for all subentry components
|
||||
@@ -4294,7 +4294,7 @@ async def test_subentry_reconfigure_remove_entity(
|
||||
unique_entity_id = f"{subentry_id}_{key}"
|
||||
entity_id = entity_registry.async_get_entity_id(
|
||||
domain=component["platform"],
|
||||
platform=mqtt.DOMAIN,
|
||||
platform=DOMAIN,
|
||||
unique_id=unique_entity_id,
|
||||
)
|
||||
assert entity_id is not None
|
||||
@@ -4355,7 +4355,7 @@ async def test_subentry_reconfigure_remove_entity(
|
||||
unique_entity_id = f"{subentry_id}_{object_list[1]}"
|
||||
entity_id = entity_registry.async_get_entity_id(
|
||||
domain=components[object_list[1]]["platform"],
|
||||
platform=mqtt.DOMAIN,
|
||||
platform=DOMAIN,
|
||||
unique_id=unique_entity_id,
|
||||
)
|
||||
assert entity_id is None
|
||||
@@ -4390,7 +4390,7 @@ async def test_subentry_reconfigure_edit_entity_multi_entitites(
|
||||
) -> None:
|
||||
"""Test the subentry ConfigFlow reconfigure with multi entities."""
|
||||
await mqtt_mock_entry()
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
subentry_id: str
|
||||
subentry: ConfigSubentry
|
||||
subentry_id, subentry = next(iter(config_entry.subentries.items()))
|
||||
@@ -4400,7 +4400,7 @@ async def test_subentry_reconfigure_edit_entity_multi_entitites(
|
||||
assert result["step_id"] == "summary_menu"
|
||||
|
||||
# assert we have a device for the subentry
|
||||
device = device_registry.async_get_device(identifiers={(mqtt.DOMAIN, subentry_id)})
|
||||
device = device_registry.async_get_device(identifiers={(DOMAIN, subentry_id)})
|
||||
assert device is not None
|
||||
|
||||
# assert we have an entity for all subentry components
|
||||
@@ -4418,7 +4418,7 @@ async def test_subentry_reconfigure_edit_entity_multi_entitites(
|
||||
for key in components:
|
||||
unique_entity_id = f"{subentry_id}_{key}"
|
||||
entity_id = entity_registry.async_get_entity_id(
|
||||
domain="notify", platform=mqtt.DOMAIN, unique_id=unique_entity_id
|
||||
domain="notify", platform=DOMAIN, unique_id=unique_entity_id
|
||||
)
|
||||
assert entity_id is not None
|
||||
entity_entry = entity_registry.async_get(entity_id)
|
||||
@@ -4832,7 +4832,7 @@ async def test_subentry_reconfigure_edit_entity_single_entity(
|
||||
) -> None:
|
||||
"""Test the subentry ConfigFlow reconfigure with single entity."""
|
||||
await mqtt_mock_entry()
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
subentry_id: str
|
||||
subentry: ConfigSubentry
|
||||
subentry_id, subentry = next(iter(config_entry.subentries.items()))
|
||||
@@ -4841,7 +4841,7 @@ async def test_subentry_reconfigure_edit_entity_single_entity(
|
||||
assert result["step_id"] == "summary_menu"
|
||||
|
||||
# assert we have a device for the subentry
|
||||
device = device_registry.async_get_device(identifiers={(mqtt.DOMAIN, subentry_id)})
|
||||
device = device_registry.async_get_device(identifiers={(DOMAIN, subentry_id)})
|
||||
assert device is not None
|
||||
|
||||
# assert we have an entity for the subentry component
|
||||
@@ -4853,7 +4853,7 @@ async def test_subentry_reconfigure_edit_entity_single_entity(
|
||||
|
||||
unique_entity_id = f"{subentry_id}_{component_id}"
|
||||
entity_id = entity_registry.async_get_entity_id(
|
||||
domain=component["platform"], platform=mqtt.DOMAIN, unique_id=unique_entity_id
|
||||
domain=component["platform"], platform=DOMAIN, unique_id=unique_entity_id
|
||||
)
|
||||
assert entity_id is not None
|
||||
entity_entry = entity_registry.async_get(entity_id)
|
||||
@@ -4971,7 +4971,7 @@ async def test_subentry_reconfigure_edit_entity_reset_fields(
|
||||
) -> None:
|
||||
"""Test the subentry ConfigFlow reconfigure resets filtered out fields."""
|
||||
await mqtt_mock_entry()
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
subentry_id: str
|
||||
subentry: ConfigSubentry
|
||||
subentry_id, subentry = next(iter(config_entry.subentries.items()))
|
||||
@@ -4980,7 +4980,7 @@ async def test_subentry_reconfigure_edit_entity_reset_fields(
|
||||
assert result["step_id"] == "summary_menu"
|
||||
|
||||
# assert we have a device for the subentry
|
||||
device = device_registry.async_get_device(identifiers={(mqtt.DOMAIN, subentry_id)})
|
||||
device = device_registry.async_get_device(identifiers={(DOMAIN, subentry_id)})
|
||||
assert device is not None
|
||||
|
||||
# assert we have an entity for the subentry component
|
||||
@@ -4993,7 +4993,7 @@ async def test_subentry_reconfigure_edit_entity_reset_fields(
|
||||
|
||||
unique_entity_id = f"{subentry_id}_{component_id}"
|
||||
entity_id = entity_registry.async_get_entity_id(
|
||||
domain=component["platform"], platform=mqtt.DOMAIN, unique_id=unique_entity_id
|
||||
domain=component["platform"], platform=DOMAIN, unique_id=unique_entity_id
|
||||
)
|
||||
assert entity_id is not None
|
||||
entity_entry = entity_registry.async_get(entity_id)
|
||||
@@ -5106,7 +5106,7 @@ async def test_subentry_reconfigure_add_entity(
|
||||
) -> None:
|
||||
"""Test the subentry ConfigFlow reconfigure and add an entity."""
|
||||
await mqtt_mock_entry()
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
subentry_id: str
|
||||
subentry: ConfigSubentry
|
||||
subentry_id, subentry = next(iter(config_entry.subentries.items()))
|
||||
@@ -5115,7 +5115,7 @@ async def test_subentry_reconfigure_add_entity(
|
||||
assert result["step_id"] == "summary_menu"
|
||||
|
||||
# assert we have a device for the subentry
|
||||
device = device_registry.async_get_device(identifiers={(mqtt.DOMAIN, subentry_id)})
|
||||
device = device_registry.async_get_device(identifiers={(DOMAIN, subentry_id)})
|
||||
assert device is not None
|
||||
|
||||
# assert we have an entity for the subentry component
|
||||
@@ -5124,7 +5124,7 @@ async def test_subentry_reconfigure_add_entity(
|
||||
component_id_1, component1 = next(iter(components.items()))
|
||||
unique_entity_id = f"{subentry_id}_{component_id_1}"
|
||||
entity_id = entity_registry.async_get_entity_id(
|
||||
domain=component1["platform"], platform=mqtt.DOMAIN, unique_id=unique_entity_id
|
||||
domain=component1["platform"], platform=DOMAIN, unique_id=unique_entity_id
|
||||
)
|
||||
assert entity_id is not None
|
||||
entity_entry = entity_registry.async_get(entity_id)
|
||||
@@ -5212,7 +5212,7 @@ async def test_subentry_reconfigure_update_device_properties(
|
||||
) -> None:
|
||||
"""Test the subentry ConfigFlow reconfigure and update device properties."""
|
||||
await mqtt_mock_entry()
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
subentry_id: str
|
||||
subentry: ConfigSubentry
|
||||
subentry_id, subentry = next(iter(config_entry.subentries.items()))
|
||||
@@ -5221,7 +5221,7 @@ async def test_subentry_reconfigure_update_device_properties(
|
||||
assert result["step_id"] == "summary_menu"
|
||||
|
||||
# assert we have a device for the subentry
|
||||
device = device_registry.async_get_device(identifiers={(mqtt.DOMAIN, subentry_id)})
|
||||
device = device_registry.async_get_device(identifiers={(DOMAIN, subentry_id)})
|
||||
assert device is not None
|
||||
|
||||
# assert we have an entity for all subentry components
|
||||
@@ -5367,7 +5367,7 @@ async def test_subentry_reconfigure_availablity(
|
||||
) -> None:
|
||||
"""Test the subentry ConfigFlow reconfigure and update device properties."""
|
||||
await mqtt_mock_entry()
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
subentry_id: str
|
||||
subentry: ConfigSubentry
|
||||
subentry_id, subentry = next(iter(config_entry.subentries.items()))
|
||||
@@ -5495,7 +5495,7 @@ async def test_subentry_reconfigure_export_settings(
|
||||
) -> None:
|
||||
"""Test the subentry ConfigFlow reconfigure export feature."""
|
||||
await mqtt_mock_entry()
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
subentry_id: str
|
||||
subentry: ConfigSubentry
|
||||
subentry_id, subentry = next(iter(config_entry.subentries.items()))
|
||||
@@ -5504,7 +5504,7 @@ async def test_subentry_reconfigure_export_settings(
|
||||
assert result["step_id"] == "summary_menu"
|
||||
|
||||
# assert we have a device for the subentry
|
||||
device = device_registry.async_get_device(identifiers={(mqtt.DOMAIN, subentry_id)})
|
||||
device = device_registry.async_get_device(identifiers={(DOMAIN, subentry_id)})
|
||||
assert device is not None
|
||||
|
||||
# assert we entity for all subentry components
|
||||
@@ -5561,7 +5561,7 @@ async def test_subentry_configflow_section_feature(
|
||||
) -> None:
|
||||
"""Test subentry sections are hidden with no configurable options."""
|
||||
await mqtt_mock_entry()
|
||||
config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
|
||||
result = await hass.config_entries.subentries.async_init(
|
||||
(config_entry.entry_id, "device"),
|
||||
|
||||
@@ -6,7 +6,7 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import cover, mqtt
|
||||
from homeassistant.components import cover
|
||||
from homeassistant.components.cover import (
|
||||
ATTR_CURRENT_POSITION,
|
||||
ATTR_CURRENT_TILT_POSITION,
|
||||
@@ -14,7 +14,7 @@ from homeassistant.components.cover import (
|
||||
ATTR_TILT_POSITION,
|
||||
CoverState,
|
||||
)
|
||||
from homeassistant.components.mqtt.const import CONF_STATE_TOPIC
|
||||
from homeassistant.components.mqtt.const import CONF_STATE_TOPIC, DOMAIN
|
||||
from homeassistant.components.mqtt.cover import (
|
||||
CONF_GET_POSITION_TEMPLATE,
|
||||
CONF_GET_POSITION_TOPIC,
|
||||
@@ -81,16 +81,14 @@ from .common import (
|
||||
from tests.common import async_fire_mqtt_message
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {cover.DOMAIN: {"name": "test", "state_topic": "test-topic"}}
|
||||
}
|
||||
DEFAULT_CONFIG = {DOMAIN: {cover.DOMAIN: {"name": "test", "state_topic": "test-topic"}}}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -134,7 +132,7 @@ async def test_state_via_state_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -180,7 +178,7 @@ async def test_opening_and_closing_state_via_custom_state_payload(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"position_topic": "position-topic",
|
||||
@@ -234,7 +232,7 @@ async def test_open_closed_state_from_position_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"position_topic": "position-topic",
|
||||
@@ -295,7 +293,7 @@ async def test_open_closed_state_from_position_optimistic_alt_positions(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"tilt_command_topic": "set-position-topic",
|
||||
@@ -356,7 +354,7 @@ async def test_tilt_open_closed_toggle_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"tilt_command_topic": "set-position-topic",
|
||||
@@ -421,7 +419,7 @@ async def test_tilt_open_closed_toggle_optimistic_alt_positions(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"position_topic": "get-position-topic",
|
||||
@@ -462,7 +460,7 @@ async def test_position_via_position_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -503,7 +501,7 @@ async def test_state_via_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -546,7 +544,7 @@ async def test_state_via_template_and_entity_id(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -592,7 +590,7 @@ async def test_state_via_template_with_json_value(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"position_topic": "get-position-topic",
|
||||
@@ -638,7 +636,7 @@ async def test_position_via_template_and_entity_id(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {"name": "test", "qos": 0, "command_topic": "abc"}
|
||||
}
|
||||
},
|
||||
@@ -646,7 +644,7 @@ async def test_position_via_template_and_entity_id(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"qos": 0,
|
||||
@@ -660,7 +658,7 @@ async def test_position_via_template_and_entity_id(
|
||||
# ({"set_position_topic": "abc"}, True), - not a valid configuration
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"qos": 0,
|
||||
@@ -673,7 +671,7 @@ async def test_position_via_template_and_entity_id(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"qos": 0,
|
||||
@@ -685,7 +683,7 @@ async def test_position_via_template_and_entity_id(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"qos": 0,
|
||||
@@ -716,7 +714,7 @@ async def test_optimistic_flag(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -784,7 +782,7 @@ async def test_optimistic_state_change(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"optimistic": True,
|
||||
@@ -859,7 +857,7 @@ async def test_optimistic_state_change_with_position(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -894,7 +892,7 @@ async def test_send_open_cover_command(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -929,7 +927,7 @@ async def test_send_close_cover_command(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -965,7 +963,7 @@ async def test_send_stop_cover_command(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -979,7 +977,7 @@ async def test_send_stop_cover_command(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -1021,7 +1019,7 @@ async def test_send_stop_tilt_command(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"position_topic": "get-position-topic",
|
||||
@@ -1076,7 +1074,7 @@ async def test_current_cover_position(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"position_topic": "get-position-topic",
|
||||
@@ -1142,7 +1140,7 @@ async def test_current_cover_position_inverted(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1167,7 +1165,7 @@ async def test_optimistic_position(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"position_topic": "get-position-topic",
|
||||
@@ -1209,7 +1207,7 @@ async def test_position_update(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"position_topic": "get-position-topic",
|
||||
@@ -1229,7 +1227,7 @@ async def test_position_update(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"position_topic": "get-position-topic",
|
||||
@@ -1274,7 +1272,7 @@ async def test_set_position_templated(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"position_topic": "get-position-topic",
|
||||
@@ -1322,7 +1320,7 @@ async def test_set_position_templated_and_attributes(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"position_topic": "get-position-topic",
|
||||
@@ -1363,7 +1361,7 @@ async def test_set_tilt_templated(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"position_topic": "get-position-topic",
|
||||
@@ -1457,7 +1455,7 @@ async def test_set_tilt_templated_and_attributes(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"position_topic": "state-topic",
|
||||
@@ -1493,7 +1491,7 @@ async def test_set_position_untemplated(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"position_topic": "state-topic",
|
||||
@@ -1531,7 +1529,7 @@ async def test_set_position_untemplated_custom_percentage_range(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"qos": 0,
|
||||
@@ -1558,7 +1556,7 @@ async def test_no_command_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1584,7 +1582,7 @@ async def test_no_payload_close(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1610,7 +1608,7 @@ async def test_no_payload_open(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1636,7 +1634,7 @@ async def test_no_payload_stop(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"command_topic": "test",
|
||||
"name": "test",
|
||||
@@ -1664,7 +1662,7 @@ async def test_with_command_topic_and_tilt(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -1695,7 +1693,7 @@ async def test_tilt_defaults(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -1785,7 +1783,7 @@ async def test_tilt_via_invocation_defaults(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -1877,7 +1875,7 @@ async def test_tilt_given_value(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -1957,7 +1955,7 @@ async def test_tilt_given_value_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -2039,7 +2037,7 @@ async def test_tilt_given_value_altered_range(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -2080,7 +2078,7 @@ async def test_tilt_via_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -2124,7 +2122,7 @@ async def test_tilt_via_topic_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -2177,7 +2175,7 @@ async def test_tilt_via_topic_template_json_value(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -2227,7 +2225,7 @@ async def test_tilt_via_topic_altered_range(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -2264,7 +2262,7 @@ async def test_tilt_status_out_of_range_warning(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -2299,7 +2297,7 @@ async def test_tilt_status_not_numeric_warning(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -2349,7 +2347,7 @@ async def test_tilt_via_topic_altered_range_inverted(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -2402,7 +2400,7 @@ async def test_tilt_via_topic_template_altered_range(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -2440,7 +2438,7 @@ async def test_tilt_position(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -2479,7 +2477,7 @@ async def test_tilt_position_templated(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -2559,7 +2557,7 @@ async def test_custom_availability_payload(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"device_class": "garage",
|
||||
@@ -2583,7 +2581,7 @@ async def test_valid_device_class(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"device_class": "abc123",
|
||||
@@ -2669,7 +2667,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -2807,7 +2805,7 @@ async def test_entity_debug_info_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -2868,7 +2866,7 @@ async def test_state_and_position_topics_state_not_set_via_position_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -2925,7 +2923,7 @@ async def test_set_state_via_position_using_stopped_state(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -2963,7 +2961,7 @@ async def test_position_via_position_topic_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -3010,7 +3008,7 @@ async def test_position_via_position_topic_template_json_value(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -3053,7 +3051,7 @@ async def test_position_template_with_entity_id(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -3084,7 +3082,7 @@ async def test_position_via_position_topic_template_return_json(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -3117,7 +3115,7 @@ async def test_position_via_position_topic_template_return_json_warning(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -3165,7 +3163,7 @@ async def test_position_and_tilt_via_position_topic_template_return_json(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -3213,7 +3211,7 @@ async def test_position_via_position_topic_template_all_variables(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -3271,7 +3269,7 @@ async def test_set_state_via_stopped_state_no_position_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -3301,7 +3299,7 @@ async def test_position_via_position_topic_template_return_invalid_json(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -3328,7 +3326,7 @@ async def test_set_position_topic_without_get_position_topic_error(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -3354,7 +3352,7 @@ async def test_value_template_without_state_topic_error(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -3381,7 +3379,7 @@ async def test_position_template_without_position_topic_error(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -3407,7 +3405,7 @@ async def test_set_position_template_without_set_position_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -3433,7 +3431,7 @@ async def test_tilt_command_template_without_tilt_command_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
cover.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -3494,7 +3492,7 @@ async def test_publishing_with_custom_encoding(
|
||||
"""Test publishing MQTT payload with different encoding."""
|
||||
domain = cover.DOMAIN
|
||||
config = deepcopy(DEFAULT_CONFIG)
|
||||
config[mqtt.DOMAIN][domain]["position_topic"] = "some-position-topic"
|
||||
config[DOMAIN][domain]["position_topic"] = "some-position-topic"
|
||||
|
||||
await help_test_publishing_with_custom_encoding(
|
||||
hass,
|
||||
@@ -3541,7 +3539,7 @@ async def test_encoding_subscribable_topics(
|
||||
hass,
|
||||
mqtt_mock_entry,
|
||||
cover.DOMAIN,
|
||||
DEFAULT_CONFIG[mqtt.DOMAIN][cover.DOMAIN],
|
||||
DEFAULT_CONFIG[DOMAIN][cover.DOMAIN],
|
||||
topic,
|
||||
value,
|
||||
attribute,
|
||||
|
||||
@@ -6,7 +6,8 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import date, mqtt
|
||||
from homeassistant.components import date
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.const import ATTR_ASSUMED_STATE, ATTR_ENTITY_ID, STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
@@ -44,7 +45,7 @@ from tests.common import async_fire_mqtt_message
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {date.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
DOMAIN: {date.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +65,7 @@ async def async_set_value(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
date.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -116,7 +117,7 @@ async def test_controlling_state_via_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
date.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -155,7 +156,7 @@ async def test_controlling_validation_state_via_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
date.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -219,7 +220,7 @@ async def test_default_availability_payload(
|
||||
) -> None:
|
||||
"""Test availability by default payload with defined topic."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
date.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -237,7 +238,7 @@ async def test_custom_availability_payload(
|
||||
) -> None:
|
||||
"""Test availability by custom payload with defined topic."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
date.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -313,7 +314,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
date.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -492,7 +493,7 @@ async def test_encoding_subscribable_topics(
|
||||
hass,
|
||||
mqtt_mock_entry,
|
||||
date.DOMAIN,
|
||||
DEFAULT_CONFIG[mqtt.DOMAIN][date.DOMAIN],
|
||||
DEFAULT_CONFIG[DOMAIN][date.DOMAIN],
|
||||
topic,
|
||||
value,
|
||||
attribute,
|
||||
|
||||
@@ -8,7 +8,8 @@ from dateutil.tz import UTC
|
||||
from freezegun import freeze_time
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import datetime, mqtt
|
||||
from homeassistant.components import datetime
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.const import ATTR_ASSUMED_STATE, ATTR_ENTITY_ID, STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
@@ -46,7 +47,7 @@ from tests.common import async_fire_mqtt_message
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {datetime.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
DOMAIN: {datetime.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +69,7 @@ async def async_set_value(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
datetime.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -84,7 +85,7 @@ async def async_set_value(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
datetime.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -143,7 +144,7 @@ async def test_controlling_state_via_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
datetime.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -186,7 +187,7 @@ async def test_controlling_validation_state_via_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
datetime.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -224,7 +225,7 @@ async def test_ambiguous_date_time_state_update(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
datetime.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -257,7 +258,7 @@ async def test_date_time_with_invalid_timezone_identifier(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
datetime.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -324,7 +325,7 @@ async def test_default_availability_payload(
|
||||
) -> None:
|
||||
"""Test availability by default payload with defined topic."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
datetime.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -348,7 +349,7 @@ async def test_custom_availability_payload(
|
||||
) -> None:
|
||||
"""Test availability by custom payload with defined topic."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
datetime.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -430,7 +431,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
datetime.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -611,7 +612,7 @@ async def test_encoding_subscribable_topics(
|
||||
hass,
|
||||
mqtt_mock_entry,
|
||||
datetime.DOMAIN,
|
||||
DEFAULT_CONFIG[mqtt.DOMAIN][datetime.DOMAIN],
|
||||
DEFAULT_CONFIG[DOMAIN][datetime.DOMAIN],
|
||||
topic,
|
||||
value,
|
||||
attribute,
|
||||
|
||||
@@ -5,7 +5,7 @@ from datetime import UTC, datetime
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import device_tracker, mqtt
|
||||
from homeassistant.components import device_tracker
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.const import STATE_HOME, STATE_NOT_HOME, STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
@@ -27,7 +27,7 @@ from tests.typing import (
|
||||
)
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
device_tracker.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -693,7 +693,7 @@ async def test_setting_blocked_attribute_via_mqtt_json_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
device_tracker.DOMAIN: {"name": "jan", "state_topic": "/location/jan"}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ from unittest.mock import ANY
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
@@ -29,7 +30,7 @@ async def test_entry_diagnostics(
|
||||
) -> None:
|
||||
"""Test config entry diagnostics."""
|
||||
mqtt_mock = await mqtt_mock_entry()
|
||||
config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
mqtt_mock.connected = True
|
||||
|
||||
await get_diagnostics_for_config_entry(hass, hass_client, config_entry)
|
||||
@@ -167,7 +168,7 @@ async def test_redact_diagnostics(
|
||||
expected_config["data"]["password"] = "**REDACTED**"
|
||||
expected_config["data"]["username"] = "**REDACTED**"
|
||||
|
||||
config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
mqtt_mock.connected = True
|
||||
|
||||
# Discover a device with a device tracker
|
||||
|
||||
@@ -18,7 +18,7 @@ from homeassistant.components.mqtt.abbreviations import (
|
||||
ABBREVIATIONS,
|
||||
DEVICE_ABBREVIATIONS,
|
||||
)
|
||||
from homeassistant.components.mqtt.const import SUPPORTED_COMPONENTS
|
||||
from homeassistant.components.mqtt.const import DOMAIN, SUPPORTED_COMPONENTS
|
||||
from homeassistant.components.mqtt.discovery import (
|
||||
MQTT_DISCOVERY_DONE,
|
||||
MQTT_DISCOVERY_NEW,
|
||||
@@ -207,7 +207,7 @@ async def test_subscribing_config_topic(
|
||||
) -> None:
|
||||
"""Test setting up discovery."""
|
||||
mqtt_mock = await mqtt_mock_entry()
|
||||
entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
|
||||
discovery_topic = "homeassistant"
|
||||
await async_start(hass, discovery_topic, entry)
|
||||
@@ -1754,7 +1754,7 @@ async def test_cleanup_device_manual(
|
||||
assert state is not None
|
||||
|
||||
# Remove MQTT from the device
|
||||
mqtt_config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
mqtt_config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
mock_debouncer.clear()
|
||||
response = await ws_client.remove_device(
|
||||
device_entry.id, mqtt_config_entry.entry_id
|
||||
@@ -2018,7 +2018,7 @@ async def test_cleanup_device_multiple_config_entries(
|
||||
)
|
||||
assert device_entry is not None
|
||||
|
||||
mqtt_config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
mqtt_config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
|
||||
sensor_config = {
|
||||
"device": {"connections": [["mac", "12:34:56:AB:CD:EF"]]},
|
||||
@@ -2063,7 +2063,7 @@ async def test_cleanup_device_multiple_config_entries(
|
||||
assert state is not None
|
||||
|
||||
# Remove MQTT from the device
|
||||
mqtt_config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
mqtt_config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
response = await ws_client.remove_device(
|
||||
device_entry.id, mqtt_config_entry.entry_id
|
||||
)
|
||||
@@ -2136,7 +2136,7 @@ async def test_cleanup_device_multiple_config_entries_mqtt(
|
||||
connections={("mac", "12:34:56:AB:CD:EF")},
|
||||
)
|
||||
|
||||
mqtt_config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
mqtt_config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
|
||||
sensor_config = {
|
||||
"device": {"connections": [["mac", "12:34:56:AB:CD:EF"]]},
|
||||
@@ -2599,7 +2599,7 @@ async def test_mqtt_integration_discovery_flow_fitering_on_redundant_payload(
|
||||
birth.set()
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={mqtt.CONF_BROKER: "mock-broker"},
|
||||
options=ENTRY_DEFAULT_BIRTH_MESSAGE,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
@@ -2670,7 +2670,7 @@ async def test_mqtt_discovery_flow_starts_once(
|
||||
birth.set()
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={mqtt.CONF_BROKER: "mock-broker"},
|
||||
options=ENTRY_DEFAULT_BIRTH_MESSAGE,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
@@ -2808,7 +2808,7 @@ async def test_mqtt_discovery_flow_subscribes_atr_configured_qos(
|
||||
birth.set()
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={mqtt.CONF_BROKER: "mock-broker"},
|
||||
options=mqtt_config_entry_options,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
|
||||
@@ -7,7 +7,8 @@ from unittest.mock import patch
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import event, mqtt
|
||||
from homeassistant.components import event
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.mqtt.event import MQTT_EVENT_ATTRIBUTES_BLOCKED
|
||||
from homeassistant.const import STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
@@ -56,7 +57,7 @@ from tests.common import MockConfigEntry, async_fire_mqtt_message
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
event.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -186,7 +187,7 @@ async def test_setting_event_value_with_invalid_payload(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
event.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -319,7 +320,7 @@ async def test_discovery_update_availability(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
event.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -405,7 +406,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
event.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -630,7 +631,7 @@ async def test_entity_category(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
event.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
|
||||
@@ -7,7 +7,7 @@ from unittest.mock import patch
|
||||
import pytest
|
||||
from voluptuous.error import MultipleInvalid
|
||||
|
||||
from homeassistant.components import fan, mqtt
|
||||
from homeassistant.components import fan
|
||||
from homeassistant.components.fan import (
|
||||
ATTR_DIRECTION,
|
||||
ATTR_OSCILLATING,
|
||||
@@ -16,6 +16,7 @@ from homeassistant.components.fan import (
|
||||
ATTR_PRESET_MODES,
|
||||
NotValidPresetModeError,
|
||||
)
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.mqtt.fan import (
|
||||
CONF_DIRECTION_COMMAND_TOPIC,
|
||||
CONF_DIRECTION_STATE_TOPIC,
|
||||
@@ -72,7 +73,7 @@ from tests.components.fan import common
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -82,7 +83,7 @@ DEFAULT_CONFIG = {
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("hass_config", [{mqtt.DOMAIN: {fan.DOMAIN: {"name": "test"}}}])
|
||||
@pytest.mark.parametrize("hass_config", [{DOMAIN: {fan.DOMAIN: {"name": "test"}}}])
|
||||
@pytest.mark.usefixtures("hass")
|
||||
async def test_fail_setup_if_no_command_topic(
|
||||
caplog: pytest.LogCaptureFixture, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
@@ -96,7 +97,7 @@ async def test_fail_setup_if_no_command_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -232,7 +233,7 @@ async def test_controlling_state_via_topic(
|
||||
help_custom_config(
|
||||
fan.DOMAIN,
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"command_topic": "command-topic",
|
||||
"percentage_command_topic": "percentage-command-topic",
|
||||
@@ -295,7 +296,7 @@ async def test_controlling_state_via_topic_with_different_speed_range(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -354,7 +355,7 @@ async def test_controlling_state_via_topic_no_percentage_topics(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -472,7 +473,7 @@ async def test_controlling_state_via_topic_and_json_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "shared-state-topic",
|
||||
@@ -587,7 +588,7 @@ async def test_controlling_state_via_topic_and_json_message_shared_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -734,7 +735,7 @@ async def test_sending_mqtt_commands_and_optimistic(
|
||||
help_custom_config(
|
||||
fan.DOMAIN,
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test1",
|
||||
"command_topic": "command-topic",
|
||||
@@ -842,7 +843,7 @@ async def test_sending_mqtt_commands_with_alternate_speed_range(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -989,7 +990,7 @@ async def test_sending_mqtt_commands_and_optimistic_no_legacy(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1197,7 +1198,7 @@ async def test_sending_mqtt_command_templates_(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1260,7 +1261,7 @@ async def test_sending_mqtt_commands_and_optimistic_no_percentage_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -1576,7 +1577,7 @@ async def test_encoding_subscribable_topics(
|
||||
attribute_value: Any,
|
||||
) -> None:
|
||||
"""Test handling of incoming encoded payload."""
|
||||
config: dict[str, Any] = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][fan.DOMAIN])
|
||||
config: dict[str, Any] = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][fan.DOMAIN])
|
||||
config[ATTR_PRESET_MODES] = ["eco", "auto"]
|
||||
config[CONF_PRESET_MODE_COMMAND_TOPIC] = "fan/some_preset_mode_command_topic"
|
||||
config[CONF_PERCENTAGE_COMMAND_TOPIC] = "fan/some_percentage_command_topic"
|
||||
@@ -1598,7 +1599,7 @@ async def test_encoding_subscribable_topics(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1672,7 +1673,7 @@ async def test_attributes(
|
||||
(
|
||||
"test1",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test1",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1686,7 +1687,7 @@ async def test_attributes(
|
||||
(
|
||||
"test2",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test2",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1703,7 +1704,7 @@ async def test_attributes(
|
||||
(
|
||||
"test3",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test3",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1720,7 +1721,7 @@ async def test_attributes(
|
||||
(
|
||||
"test4",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test4",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1735,7 +1736,7 @@ async def test_attributes(
|
||||
(
|
||||
"test5",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test5",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1753,7 +1754,7 @@ async def test_attributes(
|
||||
(
|
||||
"test6",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test6",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1771,7 +1772,7 @@ async def test_attributes(
|
||||
(
|
||||
"test7",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test7",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1788,7 +1789,7 @@ async def test_attributes(
|
||||
(
|
||||
"test8",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test8",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1807,7 +1808,7 @@ async def test_attributes(
|
||||
(
|
||||
"test9",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test9",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1825,7 +1826,7 @@ async def test_attributes(
|
||||
(
|
||||
"test10",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test10",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1843,7 +1844,7 @@ async def test_attributes(
|
||||
(
|
||||
"test11",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test11",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1863,7 +1864,7 @@ async def test_attributes(
|
||||
(
|
||||
"test12",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test12",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1882,7 +1883,7 @@ async def test_attributes(
|
||||
(
|
||||
"test13",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test13",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1899,7 +1900,7 @@ async def test_attributes(
|
||||
(
|
||||
"test14",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test14",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1916,7 +1917,7 @@ async def test_attributes(
|
||||
(
|
||||
"test15",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test15",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1932,7 +1933,7 @@ async def test_attributes(
|
||||
(
|
||||
"test16",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test16",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1951,7 +1952,7 @@ async def test_attributes(
|
||||
(
|
||||
"test17",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: {
|
||||
"name": "test17",
|
||||
"command_topic": "command-topic",
|
||||
@@ -2096,7 +2097,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
fan.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -2293,7 +2294,7 @@ async def test_publishing_with_custom_encoding(
|
||||
domain = fan.DOMAIN
|
||||
config: dict[str, Any] = copy.deepcopy(DEFAULT_CONFIG)
|
||||
if topic == "preset_mode_command_topic":
|
||||
config[mqtt.DOMAIN][domain]["preset_modes"] = ["auto", "eco"]
|
||||
config[DOMAIN][domain]["preset_modes"] = ["auto", "eco"]
|
||||
|
||||
await help_test_publishing_with_custom_encoding(
|
||||
hass,
|
||||
|
||||
@@ -7,7 +7,7 @@ from unittest.mock import patch
|
||||
import pytest
|
||||
from voluptuous.error import MultipleInvalid
|
||||
|
||||
from homeassistant.components import humidifier, mqtt
|
||||
from homeassistant.components import humidifier
|
||||
from homeassistant.components.humidifier import (
|
||||
ATTR_CURRENT_HUMIDITY,
|
||||
ATTR_HUMIDITY,
|
||||
@@ -16,7 +16,7 @@ from homeassistant.components.humidifier import (
|
||||
SERVICE_SET_MODE,
|
||||
HumidifierAction,
|
||||
)
|
||||
from homeassistant.components.mqtt.const import CONF_CURRENT_HUMIDITY_TOPIC
|
||||
from homeassistant.components.mqtt.const import CONF_CURRENT_HUMIDITY_TOPIC, DOMAIN
|
||||
from homeassistant.components.mqtt.humidifier import (
|
||||
CONF_MODE_COMMAND_TOPIC,
|
||||
CONF_MODE_STATE_TOPIC,
|
||||
@@ -71,7 +71,7 @@ from tests.common import async_fire_mqtt_message
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -133,7 +133,7 @@ async def async_set_humidity(
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config", [{mqtt.DOMAIN: {humidifier.DOMAIN: {"name": "test"}}}]
|
||||
"hass_config", [{DOMAIN: {humidifier.DOMAIN: {"name": "test"}}}]
|
||||
)
|
||||
@pytest.mark.usefixtures("hass")
|
||||
async def test_fail_setup_if_no_command_topic(
|
||||
@@ -148,7 +148,7 @@ async def test_fail_setup_if_no_command_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"action_topic": "action-topic",
|
||||
@@ -308,7 +308,7 @@ async def test_controlling_state_via_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"action_topic": "action-topic",
|
||||
@@ -449,7 +449,7 @@ async def test_controlling_state_via_topic_and_json_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "shared-state-topic",
|
||||
@@ -528,7 +528,7 @@ async def test_controlling_state_via_topic_and_json_message_shared_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -627,7 +627,7 @@ async def test_sending_mqtt_commands_and_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -731,7 +731,7 @@ async def test_sending_mqtt_command_templates_(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -870,9 +870,7 @@ async def test_encoding_subscribable_topics(
|
||||
attribute_value: Any,
|
||||
) -> None:
|
||||
"""Test handling of incoming encoded payload."""
|
||||
config: dict[str, Any] = copy.deepcopy(
|
||||
DEFAULT_CONFIG[mqtt.DOMAIN][humidifier.DOMAIN]
|
||||
)
|
||||
config: dict[str, Any] = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][humidifier.DOMAIN])
|
||||
config["modes"] = ["eco", "auto"]
|
||||
config[CONF_MODE_COMMAND_TOPIC] = "humidifier/some_mode_command_topic"
|
||||
await help_test_encoding_subscribable_topics(
|
||||
@@ -891,7 +889,7 @@ async def test_encoding_subscribable_topics(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -941,7 +939,7 @@ async def test_attributes(
|
||||
[
|
||||
( # test valid case 1
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -953,7 +951,7 @@ async def test_attributes(
|
||||
),
|
||||
( # test valid case 2
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -966,7 +964,7 @@ async def test_attributes(
|
||||
),
|
||||
( # test valid case 3
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -979,7 +977,7 @@ async def test_attributes(
|
||||
),
|
||||
( # test valid case 4
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -992,7 +990,7 @@ async def test_attributes(
|
||||
),
|
||||
( # test invalid device_class
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1005,7 +1003,7 @@ async def test_attributes(
|
||||
),
|
||||
( # test mode_command_topic without modes
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1018,7 +1016,7 @@ async def test_attributes(
|
||||
),
|
||||
( # test invalid humidity min max case 1
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1032,7 +1030,7 @@ async def test_attributes(
|
||||
),
|
||||
( # test invalid humidity min max case 2
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1046,7 +1044,7 @@ async def test_attributes(
|
||||
),
|
||||
( # test invalid mode, is reset payload
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1075,7 +1073,7 @@ async def test_validity_configurations(
|
||||
(
|
||||
"test1",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test1",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1089,7 +1087,7 @@ async def test_validity_configurations(
|
||||
(
|
||||
"test2",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test2",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1105,7 +1103,7 @@ async def test_validity_configurations(
|
||||
(
|
||||
"test3",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test3",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1119,7 +1117,7 @@ async def test_validity_configurations(
|
||||
(
|
||||
"test4",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test4",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1135,7 +1133,7 @@ async def test_validity_configurations(
|
||||
(
|
||||
"test5",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test5",
|
||||
"command_topic": "command-topic",
|
||||
@@ -1148,7 +1146,7 @@ async def test_validity_configurations(
|
||||
(
|
||||
"test6",
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test6",
|
||||
"target_humidity_command_topic": "humidity-command-topic",
|
||||
@@ -1291,7 +1289,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
humidifier.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -1494,7 +1492,7 @@ async def test_publishing_with_custom_encoding(
|
||||
domain = humidifier.DOMAIN
|
||||
config: dict[str, Any] = copy.deepcopy(DEFAULT_CONFIG)
|
||||
if topic == "mode_command_topic":
|
||||
config[mqtt.DOMAIN][domain]["modes"] = ["auto", "eco"]
|
||||
config[DOMAIN][domain]["modes"] = ["auto", "eco"]
|
||||
|
||||
await help_test_publishing_with_custom_encoding(
|
||||
hass,
|
||||
|
||||
@@ -10,7 +10,8 @@ import httpx
|
||||
import pytest
|
||||
import respx
|
||||
|
||||
from homeassistant.components import image, mqtt
|
||||
from homeassistant.components import image
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
@@ -49,15 +50,13 @@ from tests.typing import (
|
||||
MqttMockPahoClient,
|
||||
)
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {image.DOMAIN: {"name": "test", "image_topic": "test_topic"}}
|
||||
}
|
||||
DEFAULT_CONFIG = {DOMAIN: {image.DOMAIN: {"name": "test", "image_topic": "test_topic"}}}
|
||||
|
||||
|
||||
@pytest.mark.freeze_time("2023-04-01 00:00:00+00:00")
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config",
|
||||
[{mqtt.DOMAIN: {image.DOMAIN: {"image_topic": "test/image", "name": "Test"}}}],
|
||||
[{DOMAIN: {image.DOMAIN: {"image_topic": "test/image", "name": "Test"}}}],
|
||||
)
|
||||
async def test_run_image_setup(
|
||||
hass: HomeAssistant,
|
||||
@@ -93,7 +92,7 @@ async def test_run_image_setup(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
image.DOMAIN: {
|
||||
"image_topic": "test/image",
|
||||
"name": "Test",
|
||||
@@ -147,7 +146,7 @@ async def test_run_image_b64_encoded(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
"image": {
|
||||
"image_topic": "test/image",
|
||||
"name": "Test",
|
||||
@@ -200,7 +199,7 @@ async def test_image_b64_encoded_with_availability(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
"image": {
|
||||
"url_topic": "test/image",
|
||||
"name": "Test",
|
||||
@@ -281,7 +280,7 @@ async def test_image_from_url(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
"image": {
|
||||
"url_topic": "test/image",
|
||||
"name": "Test",
|
||||
@@ -334,7 +333,7 @@ async def test_image_from_url_with_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
"image": {
|
||||
"url_topic": "test/image",
|
||||
"name": "Test",
|
||||
@@ -402,7 +401,7 @@ async def test_image_from_url_content_type(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
"image": {
|
||||
"url_topic": "test/image",
|
||||
"name": "Test",
|
||||
@@ -462,7 +461,7 @@ async def test_image_from_url_fails(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
"image": {
|
||||
"url_topic": "test/image",
|
||||
"content_type": "image/jpg",
|
||||
@@ -475,7 +474,7 @@ async def test_image_from_url_fails(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
"image": {
|
||||
"url_topic": "test/image",
|
||||
"image_topic": "test/image-data-topic",
|
||||
@@ -488,7 +487,7 @@ async def test_image_from_url_fails(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
"image": {
|
||||
"name": "Test",
|
||||
"encoding": "utf-8",
|
||||
@@ -601,7 +600,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
image.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -629,7 +628,7 @@ async def test_discovery_removal_image(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test removal of discovered image."""
|
||||
data = json.dumps(DEFAULT_CONFIG[mqtt.DOMAIN][image.DOMAIN])
|
||||
data = json.dumps(DEFAULT_CONFIG[DOMAIN][image.DOMAIN])
|
||||
await help_test_discovery_removal(hass, mqtt_mock_entry, image.DOMAIN, data)
|
||||
|
||||
|
||||
@@ -806,7 +805,7 @@ async def test_skipped_async_ha_write_state(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
image.DOMAIN: {
|
||||
"name": "test",
|
||||
"url_topic": "test-topic",
|
||||
|
||||
@@ -18,6 +18,7 @@ import voluptuous as vol
|
||||
from homeassistant import core as ha
|
||||
from homeassistant.components import mqtt
|
||||
from homeassistant.components.mqtt import debug_info
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.mqtt.models import (
|
||||
MessageCallbackType,
|
||||
MqttCommandTemplateException,
|
||||
@@ -272,7 +273,7 @@ async def test_service_call_without_topic_does_not_publish(
|
||||
mqtt_mock = await mqtt_mock_entry()
|
||||
with pytest.raises(vol.Invalid):
|
||||
await hass.services.async_call(
|
||||
mqtt.DOMAIN,
|
||||
DOMAIN,
|
||||
mqtt.SERVICE_PUBLISH,
|
||||
{},
|
||||
blocking=True,
|
||||
@@ -284,7 +285,7 @@ async def test_service_call_mqtt_entry_does_not_publish(
|
||||
hass: HomeAssistant, mqtt_client_mock: MqttMockPahoClient
|
||||
) -> None:
|
||||
"""Test the service call if topic is missing."""
|
||||
assert await async_setup_component(hass, mqtt.DOMAIN, {})
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
with pytest.raises(
|
||||
ServiceValidationError,
|
||||
match=(
|
||||
@@ -292,7 +293,7 @@ async def test_service_call_mqtt_entry_does_not_publish(
|
||||
),
|
||||
):
|
||||
await hass.services.async_call(
|
||||
mqtt.DOMAIN,
|
||||
DOMAIN,
|
||||
mqtt.SERVICE_PUBLISH,
|
||||
{
|
||||
mqtt.ATTR_TOPIC: "test_topic",
|
||||
@@ -312,7 +313,7 @@ async def test_service_call_with_template_topic_renders_invalid_topic(
|
||||
mqtt_mock = await mqtt_mock_entry()
|
||||
with pytest.raises(vol.Invalid) as exc:
|
||||
await hass.services.async_call(
|
||||
mqtt.DOMAIN,
|
||||
DOMAIN,
|
||||
mqtt.SERVICE_PUBLISH,
|
||||
{
|
||||
mqtt.ATTR_TOPIC: "test/{{ '+' if True else 'topic' }}/topic",
|
||||
@@ -356,7 +357,7 @@ async def test_mqtt_publish_action_call_with_raw_data(
|
||||
"""
|
||||
mqtt_mock = await mqtt_mock_entry()
|
||||
await hass.services.async_call(
|
||||
mqtt.DOMAIN,
|
||||
DOMAIN,
|
||||
mqtt.SERVICE_PUBLISH,
|
||||
{
|
||||
mqtt.ATTR_TOPIC: "test/topic",
|
||||
@@ -372,7 +373,7 @@ async def test_mqtt_publish_action_call_with_raw_data(
|
||||
"homeassistant.components.mqtt.models.literal_eval"
|
||||
) as literal_eval_mock:
|
||||
await hass.services.async_call(
|
||||
mqtt.DOMAIN,
|
||||
DOMAIN,
|
||||
mqtt.SERVICE_PUBLISH,
|
||||
{
|
||||
mqtt.ATTR_TOPIC: "test/topic",
|
||||
@@ -383,7 +384,7 @@ async def test_mqtt_publish_action_call_with_raw_data(
|
||||
literal_eval_mock.assert_not_called()
|
||||
|
||||
await hass.services.async_call(
|
||||
mqtt.DOMAIN,
|
||||
DOMAIN,
|
||||
mqtt.SERVICE_PUBLISH,
|
||||
{
|
||||
mqtt.ATTR_TOPIC: "test/topic",
|
||||
@@ -404,7 +405,7 @@ async def test_service_call_with_ascii_qos_retain_flags(
|
||||
"""
|
||||
mqtt_mock = await mqtt_mock_entry()
|
||||
await hass.services.async_call(
|
||||
mqtt.DOMAIN,
|
||||
DOMAIN,
|
||||
mqtt.SERVICE_PUBLISH,
|
||||
{
|
||||
mqtt.ATTR_TOPIC: "test/topic",
|
||||
@@ -423,7 +424,7 @@ async def test_service_call_with_ascii_qos_retain_flags(
|
||||
|
||||
# Test service call without payload
|
||||
await hass.services.async_call(
|
||||
mqtt.DOMAIN,
|
||||
DOMAIN,
|
||||
mqtt.SERVICE_PUBLISH,
|
||||
{
|
||||
mqtt.ATTR_TOPIC: "test/topic",
|
||||
@@ -485,7 +486,7 @@ async def test_publish_action_with_message_expiry_interval(
|
||||
"""Test the publish action message expiry interval option."""
|
||||
mqtt_mock = await mqtt_mock_entry()
|
||||
await hass.services.async_call(
|
||||
mqtt.DOMAIN,
|
||||
DOMAIN,
|
||||
mqtt.SERVICE_PUBLISH,
|
||||
{
|
||||
mqtt.ATTR_TOPIC: "test/topic",
|
||||
@@ -708,7 +709,7 @@ def test_entity_device_info_schema() -> None:
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
"sensor": [
|
||||
{
|
||||
"name": "test-sensor",
|
||||
@@ -807,13 +808,13 @@ async def test_reload_entry_with_restored_subscriptions(
|
||||
"""Test reloading the config entry with with subscriptions restored."""
|
||||
# Setup the MQTT entry
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={mqtt.CONF_BROKER: "test-broker"},
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
hass.config.components.add(mqtt.DOMAIN)
|
||||
hass.config.components.add(DOMAIN)
|
||||
with patch("homeassistant.config.load_yaml_config_file", return_value={}):
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
|
||||
@@ -869,11 +870,27 @@ async def test_reload_entry_with_restored_subscriptions(
|
||||
assert recorded_calls[1].payload == "wild-card-payload3"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mqtt_client_mock")
|
||||
async def test_reload_without_entry(
|
||||
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""Test reloading without a valid config entry set up."""
|
||||
# Setup the MQTT integration without entry
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
await hass.async_block_till_done()
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
await hass.services.async_call(DOMAIN, SERVICE_RELOAD, {}, blocking=True)
|
||||
assert (
|
||||
"Skipped reloading MQTT integration, the MQTT config entry is not enabled"
|
||||
in caplog.text
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
"light": {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
@@ -894,7 +911,7 @@ async def test_setup_manual_mqtt_with_platform_key(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("hass_config", [{mqtt.DOMAIN: {"light": {"name": "test"}}}])
|
||||
@pytest.mark.parametrize("hass_config", [{DOMAIN: {"light": {"name": "test"}}}])
|
||||
async def test_setup_manual_mqtt_with_invalid_config(
|
||||
mqtt_mock_entry: MqttMockHAClientGenerator, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
@@ -916,13 +933,13 @@ async def test_default_entry_setting_are_applied(
|
||||
|
||||
# Config entry data is incomplete but valid according the schema
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={"broker": "test-broker", "port": 1234},
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
hass.config.components.add(mqtt.DOMAIN)
|
||||
hass.config.components.add(DOMAIN)
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
@@ -1122,7 +1139,7 @@ async def test_mqtt_ws_remove_discovered_device(
|
||||
assert device_entry is not None
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
mqtt_config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
mqtt_config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
response = await client.remove_device(device_entry.id, mqtt_config_entry.entry_id)
|
||||
assert response["success"]
|
||||
|
||||
@@ -1460,7 +1477,7 @@ async def test_debug_info_non_mqtt(
|
||||
)
|
||||
|
||||
assert await async_setup_component(
|
||||
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {domain: {"platform": "test"}}}
|
||||
hass, DOMAIN, {DOMAIN: {domain: {"platform": "test"}}}
|
||||
)
|
||||
|
||||
debug_info_data = debug_info.info_for_device(hass, device_entry.id)
|
||||
@@ -1759,20 +1776,20 @@ async def test_unload_config_entry(
|
||||
) -> None:
|
||||
"""Test unloading the MQTT entry."""
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={mqtt.CONF_BROKER: "test-broker", CONF_PROTOCOL: "5"},
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
assert await async_setup_component(hass, mqtt.DOMAIN, {})
|
||||
assert hass.services.has_service(mqtt.DOMAIN, "dump")
|
||||
assert hass.services.has_service(mqtt.DOMAIN, "publish")
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
assert hass.services.has_service(DOMAIN, "dump")
|
||||
assert hass.services.has_service(DOMAIN, "publish")
|
||||
# Make sure the debouncer finishes
|
||||
await mock_debouncer.wait()
|
||||
|
||||
mqtt_config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
mqtt_config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
assert mqtt_config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
# Publish just before unloading to test await cleanup
|
||||
@@ -1802,8 +1819,8 @@ async def test_unload_config_entry(
|
||||
|
||||
assert new_mqtt_config_entry.state is ConfigEntryState.NOT_LOADED
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
assert hass.services.has_service(mqtt.DOMAIN, "dump")
|
||||
assert hass.services.has_service(mqtt.DOMAIN, "publish")
|
||||
assert hass.services.has_service(DOMAIN, "dump")
|
||||
assert hass.services.has_service(DOMAIN, "publish")
|
||||
assert "No ACK from MQTT server" not in caplog.text
|
||||
|
||||
|
||||
@@ -1811,9 +1828,9 @@ async def test_publish_or_subscribe_without_valid_config_entry(
|
||||
hass: HomeAssistant, record_calls: MessageCallbackType
|
||||
) -> None:
|
||||
"""Test internal publish function with bad use cases."""
|
||||
assert await async_setup_component(hass, mqtt.DOMAIN, {})
|
||||
assert hass.services.has_service(mqtt.DOMAIN, "dump")
|
||||
assert hass.services.has_service(mqtt.DOMAIN, "publish")
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
assert hass.services.has_service(DOMAIN, "dump")
|
||||
assert hass.services.has_service(DOMAIN, "publish")
|
||||
with pytest.raises(HomeAssistantError):
|
||||
await mqtt.async_publish(
|
||||
hass, "some-topic", "test-payload", qos=0, retain=False, encoding=None
|
||||
@@ -1846,7 +1863,7 @@ async def test_disabling_and_enabling_entry(
|
||||
) -> None:
|
||||
"""Test disabling and enabling the config entry."""
|
||||
await mqtt_mock_entry()
|
||||
entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
# Late discovery of a mqtt entity
|
||||
config_tag = (
|
||||
@@ -1913,7 +1930,7 @@ async def test_disabling_and_enabling_entry(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
"light": [
|
||||
{
|
||||
"name": "test1",
|
||||
@@ -1932,7 +1949,7 @@ async def test_disabling_and_enabling_entry(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
"light": [
|
||||
{
|
||||
"name": "test1",
|
||||
@@ -2019,8 +2036,8 @@ async def test_link_config_entry(
|
||||
entity_names = ["test_manual", "test_discovery"]
|
||||
|
||||
# Check if both entities were linked to the MQTT config entry
|
||||
mqtt_config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
mqtt_platforms = async_get_platforms(hass, mqtt.DOMAIN)
|
||||
mqtt_config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
mqtt_platforms = async_get_platforms(hass, DOMAIN)
|
||||
|
||||
@callback
|
||||
def _check_entities() -> int:
|
||||
@@ -2100,12 +2117,12 @@ async def test_reload_config_entry(
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get("sensor.test_discovery") is not None
|
||||
|
||||
entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
|
||||
@callback
|
||||
def _check_entities() -> int:
|
||||
entities: list[Entity] = []
|
||||
mqtt_platforms = async_get_platforms(hass, mqtt.DOMAIN)
|
||||
mqtt_platforms = async_get_platforms(hass, DOMAIN)
|
||||
for mqtt_platform in mqtt_platforms:
|
||||
assert mqtt_platform.config_entry is entry
|
||||
entities += (entity for entity in mqtt_platform.entities.values())
|
||||
@@ -2439,16 +2456,14 @@ async def test_mqtt_integration_level_imports(attr: str) -> None:
|
||||
|
||||
@pytest.mark.usefixtures("mqtt_client_mock")
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config", [{mqtt.DOMAIN: {"sensor": {"state_topic": "test-topic"}}}]
|
||||
"hass_config", [{DOMAIN: {"sensor": {"state_topic": "test-topic"}}}]
|
||||
)
|
||||
async def test_yaml_config_without_entry(
|
||||
hass: HomeAssistant, hass_config: ConfigType, issue_registry: ir.IssueRegistry
|
||||
) -> None:
|
||||
"""Test a repair issue is created for YAML setup without an active config entry."""
|
||||
await async_setup_component(hass, mqtt.DOMAIN, hass_config)
|
||||
issue = issue_registry.async_get_issue(
|
||||
mqtt.DOMAIN, "yaml_setup_without_active_setup"
|
||||
)
|
||||
await async_setup_component(hass, DOMAIN, hass_config)
|
||||
issue = issue_registry.async_get_issue(DOMAIN, "yaml_setup_without_active_setup")
|
||||
assert issue is not None
|
||||
assert (
|
||||
issue.learn_more_url == "https://www.home-assistant.io/integrations/mqtt/"
|
||||
@@ -2457,7 +2472,7 @@ async def test_yaml_config_without_entry(
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config", [{mqtt.DOMAIN: {"sensor": {"state_topic": "test-topic"}}}]
|
||||
"hass_config", [{DOMAIN: {"sensor": {"state_topic": "test-topic"}}}]
|
||||
)
|
||||
async def test_yaml_config_with_active_mqtt_config_entry(
|
||||
hass: HomeAssistant,
|
||||
@@ -2467,9 +2482,7 @@ async def test_yaml_config_with_active_mqtt_config_entry(
|
||||
) -> None:
|
||||
"""Test no repair issue is created for YAML setup with an active config entry."""
|
||||
await mqtt_mock_entry()
|
||||
issue = issue_registry.async_get_issue(
|
||||
mqtt.DOMAIN, "yaml_setup_without_active_setup"
|
||||
)
|
||||
issue = issue_registry.async_get_issue(DOMAIN, "yaml_setup_without_active_setup")
|
||||
state = hass.states.get("sensor.mqtt_sensor")
|
||||
assert state is not None
|
||||
assert issue is None
|
||||
@@ -2520,7 +2533,7 @@ async def test_mqtt_protocol_successful_migration_to_v5(
|
||||
"The MQTT protocol version was successfully updated to version 5"
|
||||
in caplog.text
|
||||
)
|
||||
entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
assert entry.data[mqtt.CONF_PROTOCOL] == mqtt.PROTOCOL_5
|
||||
|
||||
|
||||
@@ -2582,7 +2595,7 @@ async def test_mqtt_protocol_failed_migration_to_v5(
|
||||
|
||||
issue_registry = ir.async_get(hass)
|
||||
assert len(issue_registry.issues) == 1
|
||||
issue = issue_registry.async_get_issue(mqtt.DOMAIN, "protocol_5_migration")
|
||||
issue = issue_registry.async_get_issue(DOMAIN, "protocol_5_migration")
|
||||
assert issue is not None
|
||||
assert issue.translation_key == "protocol_5_migration"
|
||||
assert issue.translation_placeholders == {
|
||||
@@ -2593,5 +2606,5 @@ async def test_mqtt_protocol_failed_migration_to_v5(
|
||||
"The MQTT protocol version was successfully updated to version 5"
|
||||
not in caplog.text
|
||||
)
|
||||
entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
assert entry.data.get(mqtt.CONF_PROTOCOL, mqtt.PROTOCOL_311) == current_protocol
|
||||
|
||||
@@ -7,7 +7,7 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import lawn_mower, mqtt
|
||||
from homeassistant.components import lawn_mower
|
||||
from homeassistant.components.lawn_mower import (
|
||||
DOMAIN as LAWN_MOWER_DOMAIN,
|
||||
SERVICE_DOCK,
|
||||
@@ -15,6 +15,7 @@ from homeassistant.components.lawn_mower import (
|
||||
SERVICE_START_MOWING,
|
||||
LawnMowerEntityFeature,
|
||||
)
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.mqtt.lawn_mower import MQTT_LAWN_MOWER_ATTRIBUTES_BLOCKED
|
||||
from homeassistant.const import ATTR_ASSUMED_STATE, ATTR_ENTITY_ID, STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant, State
|
||||
@@ -63,7 +64,7 @@ DEFAULT_FEATURES = (
|
||||
)
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lawn_mower.DOMAIN: {
|
||||
"name": "test",
|
||||
"dock_command_topic": "dock-test-topic",
|
||||
@@ -78,7 +79,7 @@ DEFAULT_CONFIG = {
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lawn_mower.DOMAIN: {
|
||||
"activity_state_topic": "test/lawn_mower_stat",
|
||||
"dock_command_topic": "dock-test-topic",
|
||||
@@ -135,7 +136,7 @@ async def test_run_lawn_mower_setup_and_state_updates(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lawn_mower.DOMAIN: {
|
||||
"pause_command_topic": "pause-test-topic",
|
||||
"name": "test",
|
||||
@@ -146,7 +147,7 @@ async def test_run_lawn_mower_setup_and_state_updates(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lawn_mower.DOMAIN: {
|
||||
"dock_command_topic": "dock-test-topic",
|
||||
"start_mowing_command_topic": "start_mowing-test-topic",
|
||||
@@ -175,7 +176,7 @@ async def test_supported_features(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lawn_mower.DOMAIN: {
|
||||
"activity_state_topic": "test/lawn_mower_stat",
|
||||
"name": "Test Lawn Mower",
|
||||
@@ -289,7 +290,7 @@ async def test_run_lawn_mower_service_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lawn_mower.DOMAIN: {
|
||||
"pause_command_topic": "test/lawn_mower_pause_cmd",
|
||||
"name": "Test Lawn Mower",
|
||||
@@ -315,7 +316,7 @@ async def test_restore_lawn_mower_from_invalid_state(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lawn_mower.DOMAIN: {
|
||||
"name": "Test Lawn Mower",
|
||||
"dock_command_topic": "test/lawn_mower_dock_cmd",
|
||||
@@ -501,7 +502,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lawn_mower.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -529,7 +530,7 @@ async def test_discovery_removal_lawn_mower(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test removal of discovered lawn_mower."""
|
||||
data = json.dumps(DEFAULT_CONFIG[mqtt.DOMAIN][lawn_mower.DOMAIN])
|
||||
data = json.dumps(DEFAULT_CONFIG[DOMAIN][lawn_mower.DOMAIN])
|
||||
await help_test_discovery_removal(hass, mqtt_mock_entry, lawn_mower.DOMAIN, data)
|
||||
|
||||
|
||||
@@ -628,7 +629,7 @@ async def test_entity_id_update_subscriptions(
|
||||
) -> None:
|
||||
"""Test MQTT subscriptions are managed when entity_id is updated."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lawn_mower.DOMAIN: {
|
||||
"name": "test",
|
||||
"activity_state_topic": "test-topic",
|
||||
@@ -687,7 +688,7 @@ async def test_entity_debug_info_message(
|
||||
) -> None:
|
||||
"""Test MQTT debug info."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lawn_mower.DOMAIN: {
|
||||
"activity_state_topic": "test/lawn_mower_stat",
|
||||
"dock_command_topic": "dock-test-topic",
|
||||
@@ -714,7 +715,7 @@ async def test_entity_debug_info_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lawn_mower.DOMAIN: {
|
||||
"dock_command_topic": "dock-test-topic",
|
||||
"pause_command_topic": "pause-test-topic",
|
||||
@@ -826,9 +827,7 @@ async def test_encoding_subscribable_topics(
|
||||
attribute_value: Any,
|
||||
) -> None:
|
||||
"""Test handling of incoming encoded payload."""
|
||||
config: dict[str, Any] = copy.deepcopy(
|
||||
DEFAULT_CONFIG[mqtt.DOMAIN][lawn_mower.DOMAIN]
|
||||
)
|
||||
config: dict[str, Any] = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][lawn_mower.DOMAIN])
|
||||
config["actions"] = ["milk", "beer"]
|
||||
await help_test_encoding_subscribable_topics(
|
||||
hass,
|
||||
@@ -935,7 +934,7 @@ async def test_skipped_async_ha_write_state(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lawn_mower.DOMAIN: {
|
||||
"name": "test",
|
||||
"activity_state_topic": "test-topic",
|
||||
|
||||
@@ -192,7 +192,8 @@ from unittest.mock import call, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import light, mqtt
|
||||
from homeassistant.components import light
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.mqtt.light.schema_basic import (
|
||||
CONF_BRIGHTNESS_COMMAND_TOPIC,
|
||||
CONF_COLOR_TEMP_COMMAND_TOPIC,
|
||||
@@ -246,13 +247,11 @@ from tests.components.light import common
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {light.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
DOMAIN: {light.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config", [{mqtt.DOMAIN: {light.DOMAIN: {"name": "test"}}}]
|
||||
)
|
||||
@pytest.mark.parametrize("hass_config", [{DOMAIN: {light.DOMAIN: {"name": "test"}}}])
|
||||
async def test_fail_setup_if_no_command_topic(
|
||||
hass: HomeAssistant,
|
||||
mqtt_mock_entry: MqttMockHAClientGenerator,
|
||||
@@ -267,7 +266,7 @@ async def test_fail_setup_if_no_command_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test_light_rgb/status",
|
||||
@@ -421,7 +420,7 @@ async def test_no_min_max_kelvin(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test_light_rgb/status",
|
||||
@@ -548,7 +547,7 @@ async def test_controlling_state_via_topic(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test_light_color_temp/status",
|
||||
@@ -574,7 +573,7 @@ async def test_controlling_state_via_topic(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test_light_color_temp/status",
|
||||
@@ -803,7 +802,7 @@ async def test_received_rgbx_values_set_state_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test_light_rgb/status",
|
||||
@@ -935,7 +934,7 @@ async def test_invalid_state_via_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test_scale/status",
|
||||
@@ -985,7 +984,7 @@ async def test_brightness_controlling_scale(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test_scale_rgb/status",
|
||||
@@ -1059,7 +1058,7 @@ async def test_brightness_from_rgb_controlling_scale(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test_light_rgb/status",
|
||||
@@ -1179,7 +1178,7 @@ async def test_controlling_state_via_topic_with_templates(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light_rgb/set",
|
||||
@@ -1445,7 +1444,7 @@ async def test_sending_mqtt_commands_and_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light_rgb/set",
|
||||
@@ -1494,7 +1493,7 @@ async def test_sending_mqtt_rgb_command_with_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light_rgb/set",
|
||||
@@ -1543,7 +1542,7 @@ async def test_sending_mqtt_rgbw_command_with_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light_rgb/set",
|
||||
@@ -1593,7 +1592,7 @@ async def test_sending_mqtt_rgbww_command_with_template(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light_color_temp/set",
|
||||
@@ -1614,7 +1613,7 @@ async def test_sending_mqtt_rgbww_command_with_template(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light_color_temp/set",
|
||||
@@ -1674,7 +1673,7 @@ async def test_sending_mqtt_color_temp_command_with_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light/set",
|
||||
@@ -1718,7 +1717,7 @@ async def test_on_command_first(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light/set",
|
||||
@@ -1761,7 +1760,7 @@ async def test_on_command_last(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light/set",
|
||||
@@ -1826,7 +1825,7 @@ async def test_on_command_brightness(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light/set",
|
||||
@@ -1908,7 +1907,7 @@ async def test_on_command_brightness_scaled(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light/set",
|
||||
@@ -2010,7 +2009,7 @@ async def test_on_command_rgb(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light/set",
|
||||
@@ -2126,7 +2125,7 @@ async def test_on_command_rgbw(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light/set",
|
||||
@@ -2246,7 +2245,7 @@ async def test_on_command_rgbww(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light/set",
|
||||
@@ -2293,7 +2292,7 @@ async def test_on_command_rgb_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light/set",
|
||||
@@ -2345,7 +2344,7 @@ async def test_on_command_rgbw_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light/set",
|
||||
@@ -2397,7 +2396,7 @@ async def test_on_command_rgbww_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "tasmota_B94927/cmnd/POWER",
|
||||
@@ -2509,7 +2508,7 @@ async def test_on_command_white(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test_light_rgb/status",
|
||||
@@ -2664,7 +2663,7 @@ async def test_explicit_color_mode(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test_light_rgb/status",
|
||||
@@ -2752,7 +2751,7 @@ async def test_explicit_color_mode_templated(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "tasmota_B94927/tele/STATE",
|
||||
@@ -2825,7 +2824,7 @@ async def test_white_state_update(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light/set",
|
||||
@@ -2976,7 +2975,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -3636,7 +3635,7 @@ async def test_entity_debug_info_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_max_mireds/set",
|
||||
@@ -3760,9 +3759,9 @@ async def test_publishing_with_custom_encoding(
|
||||
domain = light.DOMAIN
|
||||
config: dict[str, Any] = copy.deepcopy(DEFAULT_CONFIG)
|
||||
if topic == "effect_command_topic":
|
||||
config[mqtt.DOMAIN][domain]["effect_list"] = ["random", "color_loop"]
|
||||
config[DOMAIN][domain]["effect_list"] = ["random", "color_loop"]
|
||||
elif topic == "white_command_topic":
|
||||
config[mqtt.DOMAIN][domain]["rgb_command_topic"] = "some-cmd-topic"
|
||||
config[DOMAIN][domain]["rgb_command_topic"] = "some-cmd-topic"
|
||||
|
||||
await help_test_publishing_with_custom_encoding(
|
||||
hass,
|
||||
@@ -3847,7 +3846,7 @@ async def test_encoding_subscribable_topics(
|
||||
init_payload: tuple[str, str] | None,
|
||||
) -> None:
|
||||
"""Test handling of incoming encoded payload."""
|
||||
config: dict[str, Any] = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][light.DOMAIN])
|
||||
config: dict[str, Any] = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][light.DOMAIN])
|
||||
config[CONF_EFFECT_COMMAND_TOPIC] = "light/CONF_EFFECT_COMMAND_TOPIC"
|
||||
config[CONF_RGB_COMMAND_TOPIC] = "light/CONF_RGB_COMMAND_TOPIC"
|
||||
config[CONF_BRIGHTNESS_COMMAND_TOPIC] = "light/CONF_BRIGHTNESS_COMMAND_TOPIC"
|
||||
@@ -3888,7 +3887,7 @@ async def test_encoding_subscribable_topics_brightness(
|
||||
init_payload: tuple[str, str] | None,
|
||||
) -> None:
|
||||
"""Test handling of incoming encoded payload for a brightness only light."""
|
||||
config = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][light.DOMAIN])
|
||||
config = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][light.DOMAIN])
|
||||
config[CONF_BRIGHTNESS_COMMAND_TOPIC] = "light/CONF_BRIGHTNESS_COMMAND_TOPIC"
|
||||
|
||||
await help_test_encoding_subscribable_topics(
|
||||
@@ -3908,7 +3907,7 @@ async def test_encoding_subscribable_topics_brightness(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light_brightness/set",
|
||||
@@ -3962,7 +3961,7 @@ async def test_sending_mqtt_brightness_command_with_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light_brightness/set",
|
||||
@@ -4017,7 +4016,7 @@ async def test_sending_mqtt_effect_command_with_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light_hs/set",
|
||||
@@ -4065,7 +4064,7 @@ async def test_sending_mqtt_hs_command_with_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test_light_xy/set",
|
||||
|
||||
@@ -88,7 +88,8 @@ from unittest.mock import call, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import light, mqtt
|
||||
from homeassistant.components import light
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.mqtt.light.schema_basic import (
|
||||
MQTT_LIGHT_ATTRIBUTES_BLOCKED,
|
||||
)
|
||||
@@ -139,7 +140,7 @@ from tests.components.light import common
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -150,7 +151,7 @@ DEFAULT_CONFIG = {
|
||||
|
||||
|
||||
COLOR_MODES_CONFIG = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"brightness": True,
|
||||
"effect": True,
|
||||
@@ -262,7 +263,7 @@ async def test_simple_on_off_light(
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config", [{mqtt.DOMAIN: {light.DOMAIN: {"schema": "json", "name": "test"}}}]
|
||||
"hass_config", [{DOMAIN: {light.DOMAIN: {"schema": "json", "name": "test"}}}]
|
||||
)
|
||||
async def test_fail_setup_if_no_command_topic(
|
||||
mqtt_mock_entry: MqttMockHAClientGenerator,
|
||||
@@ -391,7 +392,7 @@ async def test_controlling_state_with_unknown_color_mode(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -447,7 +448,7 @@ async def test_no_color_brightness_color_temp_if_no_topics(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -458,7 +459,7 @@ async def test_no_color_brightness_color_temp_if_no_topics(
|
||||
}
|
||||
},
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -518,7 +519,7 @@ async def test_brightness_only(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -529,7 +530,7 @@ async def test_brightness_only(
|
||||
}
|
||||
},
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -570,7 +571,7 @@ async def test_single_color_mode_turn_on(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -580,7 +581,7 @@ async def test_single_color_mode_turn_on(
|
||||
}
|
||||
},
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -627,7 +628,7 @@ async def test_restore_state_with_none_color_mode(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -687,7 +688,7 @@ async def test_color_temp_only(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -778,7 +779,7 @@ async def test_controlling_state_color_temp_kelvin(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -791,7 +792,7 @@ async def test_controlling_state_color_temp_kelvin(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -806,7 +807,7 @@ async def test_controlling_state_color_temp_kelvin(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -821,7 +822,7 @@ async def test_controlling_state_color_temp_kelvin(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -836,7 +837,7 @@ async def test_controlling_state_color_temp_kelvin(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -1048,7 +1049,7 @@ async def test_controlling_state_via_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"command_topic": "test_light_rgb/set",
|
||||
"effect": True,
|
||||
@@ -1296,7 +1297,7 @@ async def test_sending_mqtt_commands_and_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -1361,7 +1362,7 @@ async def test_sending_hs_color(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -1422,7 +1423,7 @@ async def test_sending_rgb_color_no_brightness(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"command_topic": "test_light_rgb/set",
|
||||
"name": "test",
|
||||
@@ -1507,7 +1508,7 @@ async def test_sending_rgb_color_no_brightness2(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -1579,7 +1580,7 @@ async def test_sending_rgb_color_with_brightness(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -1653,7 +1654,7 @@ async def test_sending_rgb_color_with_scaled_brightness(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -1710,7 +1711,7 @@ async def test_sending_scaled_white(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -1774,7 +1775,7 @@ async def test_sending_xy_color(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -1848,7 +1849,7 @@ async def test_effect(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -1931,7 +1932,7 @@ async def test_flash_short_and_long(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -1985,7 +1986,7 @@ async def test_transition(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -2048,7 +2049,7 @@ async def test_brightness_scale(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -2246,7 +2247,7 @@ async def test_update_discovery_with_members_without_init(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -2537,7 +2538,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -2713,7 +2714,7 @@ async def test_entity_debug_info_message(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -2728,7 +2729,7 @@ async def test_entity_debug_info_message(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -2743,7 +2744,7 @@ async def test_entity_debug_info_message(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -2758,7 +2759,7 @@ async def test_entity_debug_info_message(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
@@ -2826,7 +2827,7 @@ async def test_publishing_with_custom_encoding(
|
||||
domain = light.DOMAIN
|
||||
config: dict[str, Any] = copy.deepcopy(DEFAULT_CONFIG)
|
||||
if topic == "effect_command_topic":
|
||||
config[mqtt.DOMAIN][domain]["effect_list"] = ["random", "color_loop"]
|
||||
config[DOMAIN][domain]["effect_list"] = ["random", "color_loop"]
|
||||
|
||||
await help_test_publishing_with_custom_encoding(
|
||||
hass,
|
||||
@@ -2878,7 +2879,7 @@ async def test_encoding_subscribable_topics(
|
||||
init_payload: tuple[str, str] | None,
|
||||
) -> None:
|
||||
"""Test handling of incoming encoded payload."""
|
||||
config: dict[str, Any] = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][light.DOMAIN])
|
||||
config: dict[str, Any] = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][light.DOMAIN])
|
||||
config["color_mode"] = True
|
||||
config["supported_color_modes"] = [
|
||||
"color_temp",
|
||||
|
||||
@@ -31,7 +31,8 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import light, mqtt
|
||||
from homeassistant.components import light
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.mqtt.light.schema_basic import (
|
||||
MQTT_LIGHT_ATTRIBUTES_BLOCKED,
|
||||
)
|
||||
@@ -81,7 +82,7 @@ from tests.components.light import common
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -96,10 +97,10 @@ DEFAULT_CONFIG = {
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config",
|
||||
[
|
||||
({mqtt.DOMAIN: {light.DOMAIN: {"schema": "template", "name": "test"}}},),
|
||||
({DOMAIN: {light.DOMAIN: {"schema": "template", "name": "test"}}},),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -110,7 +111,7 @@ DEFAULT_CONFIG = {
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -122,7 +123,7 @@ DEFAULT_CONFIG = {
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -149,7 +150,7 @@ async def test_setup_fails(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -185,7 +186,7 @@ async def test_rgb_light(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -204,7 +205,7 @@ async def test_rgb_light(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -254,7 +255,7 @@ async def test_single_color_mode(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -309,7 +310,7 @@ async def test_state_change_via_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -427,7 +428,7 @@ async def test_state_brightness_color_effect_temp_change_via_topic(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -459,7 +460,7 @@ async def test_state_brightness_color_effect_temp_change_via_topic(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -626,7 +627,7 @@ async def test_sending_mqtt_commands_and_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -765,7 +766,7 @@ async def test_sending_mqtt_commands_non_optimistic_brightness_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"effect_list": ["rainbow", "colorloop"],
|
||||
@@ -820,7 +821,7 @@ async def test_effect(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -871,7 +872,7 @@ async def test_flash(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -915,7 +916,7 @@ async def test_transition(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -1113,7 +1114,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -1280,7 +1281,7 @@ async def test_entity_debug_info_message(
|
||||
) -> None:
|
||||
"""Test MQTT debug info."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -1304,7 +1305,7 @@ async def test_entity_debug_info_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
light.DOMAIN: {
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
@@ -1368,7 +1369,7 @@ async def test_publishing_with_custom_encoding(
|
||||
domain = light.DOMAIN
|
||||
config: dict[str, Any] = copy.deepcopy(DEFAULT_CONFIG)
|
||||
if topic == "effect_command_topic":
|
||||
config[mqtt.DOMAIN][domain]["effect_list"] = ["random", "color_loop"]
|
||||
config[DOMAIN][domain]["effect_list"] = ["random", "color_loop"]
|
||||
|
||||
await help_test_publishing_with_custom_encoding(
|
||||
hass,
|
||||
@@ -1411,7 +1412,7 @@ async def test_encoding_subscribable_topics(
|
||||
init_payload,
|
||||
) -> None:
|
||||
"""Test handling of incoming encoded payload."""
|
||||
config = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][light.DOMAIN])
|
||||
config = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][light.DOMAIN])
|
||||
config["state_template"] = "{{ value }}"
|
||||
await help_test_encoding_subscribable_topics(
|
||||
hass,
|
||||
|
||||
@@ -5,7 +5,7 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import lock, mqtt
|
||||
from homeassistant.components import lock
|
||||
from homeassistant.components.lock import (
|
||||
SERVICE_LOCK,
|
||||
SERVICE_OPEN,
|
||||
@@ -13,6 +13,7 @@ from homeassistant.components.lock import (
|
||||
LockEntityFeature,
|
||||
LockState,
|
||||
)
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.mqtt.lock import MQTT_LOCK_ATTRIBUTES_BLOCKED
|
||||
from homeassistant.const import (
|
||||
ATTR_ASSUMED_STATE,
|
||||
@@ -58,11 +59,11 @@ from tests.common import async_fire_mqtt_message
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {lock.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
DOMAIN: {lock.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
}
|
||||
|
||||
CONFIG_WITH_STATES = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lock.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -324,7 +325,7 @@ async def test_controlling_non_default_state_via_topic_and_json_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lock.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -376,7 +377,7 @@ async def test_sending_mqtt_commands_and_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lock.DOMAIN: {
|
||||
"name": "test",
|
||||
"code_format": "^\\d{4}$",
|
||||
@@ -437,7 +438,7 @@ async def test_sending_mqtt_commands_with_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lock.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -491,7 +492,7 @@ async def test_sending_mqtt_commands_and_explicit_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lock.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -557,7 +558,7 @@ async def test_sending_mqtt_commands_support_open_and_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lock.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -625,7 +626,7 @@ async def test_sending_mqtt_commands_support_open_and_explicit_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lock.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -835,7 +836,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
lock.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -1053,7 +1054,7 @@ async def test_encoding_subscribable_topics(
|
||||
hass,
|
||||
mqtt_mock_entry,
|
||||
lock.DOMAIN,
|
||||
DEFAULT_CONFIG[mqtt.DOMAIN][lock.DOMAIN],
|
||||
DEFAULT_CONFIG[DOMAIN][lock.DOMAIN],
|
||||
topic,
|
||||
value,
|
||||
attribute,
|
||||
|
||||
@@ -6,6 +6,7 @@ from unittest.mock import call, patch
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt, sensor
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.mqtt.sensor import DEFAULT_NAME as DEFAULT_SENSOR_NAME
|
||||
from homeassistant.config_entries import ConfigSubentryData
|
||||
from homeassistant.const import (
|
||||
@@ -36,7 +37,7 @@ from tests.typing import MqttMockHAClientGenerator
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -104,7 +105,7 @@ async def test_availability_with_shared_state_topic(
|
||||
[
|
||||
( # default_entity_name_without_device_name
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"state_topic": "test-topic",
|
||||
"unique_id": "veryunique",
|
||||
@@ -119,7 +120,7 @@ async def test_availability_with_shared_state_topic(
|
||||
),
|
||||
( # default_entity_name_with_device_name
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"state_topic": "test-topic",
|
||||
"unique_id": "veryunique",
|
||||
@@ -134,7 +135,7 @@ async def test_availability_with_shared_state_topic(
|
||||
),
|
||||
( # name_follows_device_class
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"state_topic": "test-topic",
|
||||
"unique_id": "veryunique",
|
||||
@@ -150,7 +151,7 @@ async def test_availability_with_shared_state_topic(
|
||||
),
|
||||
( # name_follows_device_class_without_device_name
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"state_topic": "test-topic",
|
||||
"unique_id": "veryunique",
|
||||
@@ -166,7 +167,7 @@ async def test_availability_with_shared_state_topic(
|
||||
),
|
||||
( # name_overrides_device_class
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "MySensor",
|
||||
"state_topic": "test-topic",
|
||||
@@ -183,7 +184,7 @@ async def test_availability_with_shared_state_topic(
|
||||
),
|
||||
( # name_set_no_device_name_set
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "MySensor",
|
||||
"state_topic": "test-topic",
|
||||
@@ -200,7 +201,7 @@ async def test_availability_with_shared_state_topic(
|
||||
),
|
||||
( # none_entity_name_with_device_name
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": None,
|
||||
"state_topic": "test-topic",
|
||||
@@ -217,7 +218,7 @@ async def test_availability_with_shared_state_topic(
|
||||
),
|
||||
( # none_entity_name_without_device_name
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": None,
|
||||
"state_topic": "test-topic",
|
||||
@@ -234,7 +235,7 @@ async def test_availability_with_shared_state_topic(
|
||||
),
|
||||
( # entity_name_and_device_name_the_same
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "Hello world",
|
||||
"state_topic": "test-topic",
|
||||
@@ -254,7 +255,7 @@ async def test_availability_with_shared_state_topic(
|
||||
),
|
||||
( # entity_name_startswith_device_name1
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "World automation",
|
||||
"state_topic": "test-topic",
|
||||
@@ -274,7 +275,7 @@ async def test_availability_with_shared_state_topic(
|
||||
),
|
||||
( # entity_name_startswith_device_name2
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "world automation",
|
||||
"state_topic": "test-topic",
|
||||
@@ -328,7 +329,7 @@ async def test_default_entity_and_device_name(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={mqtt.CONF_BROKER: "mock-broker", mqtt.CONF_PROTOCOL: "5"},
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
minor_version=mqtt.CONFIG_ENTRY_MINOR_VERSION,
|
||||
@@ -417,7 +418,7 @@ async def test_name_attribute_is_set_or_not(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -427,7 +428,7 @@ async def test_name_attribute_is_set_or_not(
|
||||
}
|
||||
},
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -439,7 +440,7 @@ async def test_name_attribute_is_set_or_not(
|
||||
}
|
||||
},
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -473,7 +474,7 @@ async def test_value_template_fails(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -501,7 +502,7 @@ async def test_registry_enabled_by_default(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -647,7 +648,7 @@ async def test_loading_subentries(
|
||||
) -> None:
|
||||
"""Test loading subentries."""
|
||||
await mqtt_mock_entry()
|
||||
entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
subentry_id = next(iter(entry.subentries))
|
||||
# Each subentry has one device
|
||||
device = device_registry.async_get_device({("mqtt", subentry_id)})
|
||||
@@ -658,7 +659,7 @@ async def test_loading_subentries(
|
||||
platform = component["platform"]
|
||||
entity_id = f"{platform}.{slugify(device.name)}_{slugify(component['name'])}"
|
||||
entity_entry_entity_id = entity_registry.async_get_entity_id(
|
||||
platform, mqtt.DOMAIN, f"{subentry_id}_{object_id}"
|
||||
platform, DOMAIN, f"{subentry_id}_{object_id}"
|
||||
)
|
||||
assert entity_entry_entity_id == entity_id
|
||||
state = hass.states.get(entity_id)
|
||||
@@ -699,7 +700,7 @@ async def test_loading_subentry_with_bad_component_schema(
|
||||
) -> None:
|
||||
"""Test loading subentries."""
|
||||
await mqtt_mock_entry()
|
||||
entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
subentry_id = next(iter(entry.subentries))
|
||||
# Each subentry has one device
|
||||
device = device_registry.async_get_device({("mqtt", subentry_id)})
|
||||
@@ -729,7 +730,7 @@ async def test_qos_on_mqtt_device_from_subentry(
|
||||
) -> None:
|
||||
"""Test QoS is set correctly on entities from MQTT device."""
|
||||
mqtt_mock = await mqtt_mock_entry()
|
||||
entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
subentry_id = next(iter(entry.subentries))
|
||||
# Each subentry has one device
|
||||
device = device_registry.async_get_device({("mqtt", subentry_id)})
|
||||
|
||||
@@ -6,7 +6,8 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt, notify
|
||||
from homeassistant.components import notify
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.notify import ATTR_MESSAGE
|
||||
from homeassistant.const import ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME, STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
@@ -41,7 +42,7 @@ from .common import (
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {notify.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
DOMAIN: {notify.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +51,7 @@ DEFAULT_CONFIG = {
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
notify.DOMAIN: {
|
||||
"command_topic": "command-topic",
|
||||
"name": "test",
|
||||
@@ -90,7 +91,7 @@ async def test_sending_mqtt_commands(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
notify.DOMAIN: {
|
||||
"command_topic": "command-topic",
|
||||
"command_template": '{ "{{ entity_id }}": "{{ value }}" }',
|
||||
@@ -231,7 +232,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
notify.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -267,8 +268,8 @@ async def test_discovery_update_notify(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test update of discovered notify."""
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][notify.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][notify.DOMAIN])
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][notify.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][notify.DOMAIN])
|
||||
config1["name"] = "Beer"
|
||||
config2["name"] = "Milk"
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt, number
|
||||
from homeassistant.components import number
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.mqtt.number import (
|
||||
CONF_MAX,
|
||||
CONF_MIN,
|
||||
@@ -69,7 +70,7 @@ from tests.common import async_fire_mqtt_message, mock_restore_cache_with_extra_
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {number.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
DOMAIN: {number.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +79,7 @@ DEFAULT_CONFIG = {
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
@@ -95,7 +96,7 @@ DEFAULT_CONFIG = {
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
@@ -112,7 +113,7 @@ DEFAULT_CONFIG = {
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
@@ -163,7 +164,7 @@ async def test_run_number_setup(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
@@ -260,7 +261,7 @@ async def test_native_value_validation(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test-topic-cmd",
|
||||
@@ -316,7 +317,7 @@ async def test_equivalent_unit_of_measurement(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
@@ -368,7 +369,7 @@ async def test_value_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"command_topic": "test/number",
|
||||
"device_class": "temperature",
|
||||
@@ -406,7 +407,7 @@ async def test_restore_native_value(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"command_topic": "test/number",
|
||||
"name": "Test Number",
|
||||
@@ -489,7 +490,7 @@ async def test_run_number_service_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"command_topic": "test/number",
|
||||
"name": "Test Number",
|
||||
@@ -572,7 +573,7 @@ async def test_run_number_service_optimistic_with_command_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"command_topic": "test/number/set",
|
||||
"state_topic": "test/number",
|
||||
@@ -612,7 +613,7 @@ async def test_run_number_service(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"command_topic": "test/number/set",
|
||||
"state_topic": "test/number",
|
||||
@@ -753,7 +754,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -783,7 +784,7 @@ async def test_discovery_removal_number(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test removal of discovered number."""
|
||||
data = json.dumps(DEFAULT_CONFIG[mqtt.DOMAIN][number.DOMAIN])
|
||||
data = json.dumps(DEFAULT_CONFIG[DOMAIN][number.DOMAIN])
|
||||
await help_test_discovery_removal(hass, mqtt_mock_entry, number.DOMAIN, data)
|
||||
|
||||
|
||||
@@ -910,7 +911,7 @@ async def test_entity_debug_info_message(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
@@ -927,7 +928,7 @@ async def test_entity_debug_info_message(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
@@ -963,7 +964,7 @@ async def test_min_max_step_attributes(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
@@ -988,7 +989,7 @@ async def test_invalid_min_max_attributes(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
@@ -1013,7 +1014,7 @@ async def test_default_mode(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
@@ -1026,7 +1027,7 @@ async def test_default_mode(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
@@ -1039,7 +1040,7 @@ async def test_default_mode(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
@@ -1069,7 +1070,7 @@ async def test_mode(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
@@ -1082,7 +1083,7 @@ async def test_mode(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
@@ -1110,7 +1111,7 @@ async def test_invalid_mode(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
@@ -1141,7 +1142,7 @@ async def test_mqtt_payload_not_a_number_warning(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
@@ -1242,7 +1243,7 @@ async def test_encoding_subscribable_topics(
|
||||
hass,
|
||||
mqtt_mock_entry,
|
||||
number.DOMAIN,
|
||||
DEFAULT_CONFIG[mqtt.DOMAIN][number.DOMAIN],
|
||||
DEFAULT_CONFIG[DOMAIN][number.DOMAIN],
|
||||
topic,
|
||||
value,
|
||||
attribute,
|
||||
|
||||
@@ -7,7 +7,7 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.config_entries import ConfigSubentry, ConfigSubentryData
|
||||
from homeassistant.const import SERVICE_RELOAD
|
||||
from homeassistant.core import HomeAssistant
|
||||
@@ -34,7 +34,7 @@ async def help_setup_yaml(hass: HomeAssistant, config: dict[str, str]) -> None:
|
||||
return_value=parse_yaml(config["yaml"]),
|
||||
):
|
||||
await hass.services.async_call(
|
||||
mqtt.DOMAIN,
|
||||
DOMAIN,
|
||||
SERVICE_RELOAD,
|
||||
{},
|
||||
blocking=True,
|
||||
@@ -80,7 +80,7 @@ async def test_subentry_reconfigure_export_settings(
|
||||
) -> None:
|
||||
"""Test the subentry ConfigFlow YAML export with migration to YAML."""
|
||||
await mqtt_mock_entry()
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry: MockConfigEntry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
subentry_id: str
|
||||
subentry: ConfigSubentry
|
||||
subentry_id, subentry = next(iter(config_entry.subentries.items()))
|
||||
@@ -89,7 +89,7 @@ async def test_subentry_reconfigure_export_settings(
|
||||
assert result["step_id"] == "summary_menu"
|
||||
|
||||
# assert we have a device for the subentry
|
||||
device = device_registry.async_get_device(identifiers={(mqtt.DOMAIN, subentry_id)})
|
||||
device = device_registry.async_get_device(identifiers={(DOMAIN, subentry_id)})
|
||||
assert device.config_entries_subentries[config_entry.entry_id] == {subentry_id}
|
||||
assert device is not None
|
||||
|
||||
@@ -135,7 +135,7 @@ async def test_subentry_reconfigure_export_settings(
|
||||
await setup_helper(hass, suggested_values_from_schema)
|
||||
|
||||
# Assert the subentry device was not effected by the exported configs
|
||||
device = device_registry.async_get_device(identifiers={(mqtt.DOMAIN, subentry_id)})
|
||||
device = device_registry.async_get_device(identifiers={(DOMAIN, subentry_id)})
|
||||
assert device.config_entries_subentries[config_entry.entry_id] == {subentry_id}
|
||||
assert device is not None
|
||||
|
||||
@@ -145,13 +145,13 @@ async def test_subentry_reconfigure_export_settings(
|
||||
assert len(events) == 1
|
||||
issue_id = events[0].data["issue_id"]
|
||||
issue_registry = ir.async_get(hass)
|
||||
repair_issue = issue_registry.async_get_issue(mqtt.DOMAIN, issue_id)
|
||||
repair_issue = issue_registry.async_get_issue(DOMAIN, issue_id)
|
||||
assert repair_issue.translation_key == translation_key
|
||||
|
||||
await async_process_repairs_platforms(hass)
|
||||
client = await hass_client()
|
||||
|
||||
data = await start_repair_fix_flow(client, mqtt.DOMAIN, issue_id)
|
||||
data = await start_repair_fix_flow(client, DOMAIN, issue_id)
|
||||
|
||||
flow_id = data["flow_id"]
|
||||
assert data["description_placeholders"] == {"name": "Milk notifier"}
|
||||
@@ -161,7 +161,7 @@ async def test_subentry_reconfigure_export_settings(
|
||||
assert data["type"] == "create_entry"
|
||||
|
||||
# Assert the subentry is removed and no other entity has linked the device
|
||||
device = device_registry.async_get_device(identifiers={(mqtt.DOMAIN, subentry_id)})
|
||||
device = device_registry.async_get_device(identifiers={(DOMAIN, subentry_id)})
|
||||
assert device is None
|
||||
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
@@ -174,6 +174,6 @@ async def test_subentry_reconfigure_export_settings(
|
||||
|
||||
# The MQTT device was now set up from the new source
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
device = device_registry.async_get_device(identifiers={(mqtt.DOMAIN, subentry_id)})
|
||||
device = device_registry.async_get_device(identifiers={(DOMAIN, subentry_id)})
|
||||
assert device.config_entries_subentries[config_entry.entry_id] == {None}
|
||||
assert device is not None
|
||||
|
||||
@@ -6,7 +6,8 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt, scene
|
||||
from homeassistant.components import scene
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_ON, STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant, State
|
||||
|
||||
@@ -41,7 +42,7 @@ from tests.common import mock_restore_cache
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
scene.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
@@ -55,7 +56,7 @@ DEFAULT_CONFIG = {
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
scene.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -110,7 +111,7 @@ async def test_default_availability_payload(
|
||||
) -> None:
|
||||
"""Test availability by default payload with defined topic."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
scene.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -134,7 +135,7 @@ async def test_custom_availability_payload(
|
||||
) -> None:
|
||||
"""Test availability by custom payload with defined topic."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
scene.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -158,7 +159,7 @@ async def test_custom_availability_payload(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
scene.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -194,8 +195,8 @@ async def test_discovery_update_payload(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test update of discovered scene."""
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][scene.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][scene.DOMAIN])
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][scene.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][scene.DOMAIN])
|
||||
config1["name"] = "Beer"
|
||||
config2["name"] = "Milk"
|
||||
config1["payload_on"] = "ON"
|
||||
|
||||
@@ -9,7 +9,8 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt, select
|
||||
from homeassistant.components import select
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.mqtt.select import MQTT_SELECT_ATTRIBUTES_BLOCKED
|
||||
from homeassistant.components.select import (
|
||||
ATTR_OPTION,
|
||||
@@ -57,7 +58,7 @@ from tests.common import async_fire_mqtt_message, mock_restore_cache
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
select.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
@@ -70,7 +71,7 @@ DEFAULT_CONFIG = {
|
||||
def _test_run_select_setup_params(topic: str) -> Generator[tuple[ConfigType, str]]:
|
||||
yield (
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
select.DOMAIN: {
|
||||
"state_topic": topic,
|
||||
"command_topic": "test/select_cmd",
|
||||
@@ -127,7 +128,7 @@ async def test_run_select_setup(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
select.DOMAIN: {
|
||||
"state_topic": "test/select_stat",
|
||||
"command_topic": "test/select_cmd",
|
||||
@@ -171,7 +172,7 @@ async def test_value_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
select.DOMAIN: {
|
||||
"command_topic": "test/select_cmd",
|
||||
"name": "Test Select",
|
||||
@@ -213,7 +214,7 @@ async def test_run_select_service_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
select.DOMAIN: {
|
||||
"command_topic": "test/select_cmd",
|
||||
"name": "Test Select",
|
||||
@@ -256,7 +257,7 @@ async def test_run_select_service_optimistic_with_command_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
select.DOMAIN: {
|
||||
"command_topic": "test/select/set",
|
||||
"state_topic": "test/select",
|
||||
@@ -297,7 +298,7 @@ async def test_run_select_service(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
select.DOMAIN: {
|
||||
"command_topic": "test/select/set",
|
||||
"state_topic": "test/select",
|
||||
@@ -441,7 +442,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
select.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -473,7 +474,7 @@ async def test_discovery_removal_select(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test removal of discovered select."""
|
||||
data = json.dumps(DEFAULT_CONFIG[mqtt.DOMAIN][select.DOMAIN])
|
||||
data = json.dumps(DEFAULT_CONFIG[DOMAIN][select.DOMAIN])
|
||||
await help_test_discovery_removal(hass, mqtt_mock_entry, select.DOMAIN, data)
|
||||
|
||||
|
||||
@@ -605,7 +606,7 @@ def _test_options_attributes_options_config(
|
||||
for option in request:
|
||||
yield (
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
select.DOMAIN: {
|
||||
"command_topic": "test/select/set",
|
||||
"state_topic": "test/select",
|
||||
@@ -636,7 +637,7 @@ async def test_options_attributes(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
select.DOMAIN: {
|
||||
"state_topic": "test/select_stat",
|
||||
"command_topic": "test/select_cmd",
|
||||
@@ -690,7 +691,7 @@ async def test_publishing_with_custom_encoding(
|
||||
"""Test publishing MQTT payload with different encoding."""
|
||||
domain = select.DOMAIN
|
||||
config = copy.deepcopy(DEFAULT_CONFIG)
|
||||
config[mqtt.DOMAIN][domain]["options"] = ["milk", "beer"]
|
||||
config[DOMAIN][domain]["options"] = ["milk", "beer"]
|
||||
|
||||
await help_test_publishing_with_custom_encoding(
|
||||
hass,
|
||||
@@ -731,7 +732,7 @@ async def test_encoding_subscribable_topics(
|
||||
attribute_value: Any,
|
||||
) -> None:
|
||||
"""Test handling of incoming encoded payload."""
|
||||
config = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][select.DOMAIN])
|
||||
config = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][select.DOMAIN])
|
||||
config["options"] = ["milk", "beer"]
|
||||
await help_test_encoding_subscribable_topics(
|
||||
hass,
|
||||
|
||||
@@ -13,7 +13,8 @@ from freezegun import freeze_time
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt, sensor
|
||||
from homeassistant.components import sensor
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.mqtt.sensor import MQTT_SENSOR_ATTRIBUTES_BLOCKED
|
||||
from homeassistant.const import (
|
||||
ATTR_UNIT_OF_MEASUREMENT,
|
||||
@@ -84,7 +85,7 @@ from tests.common import (
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {sensor.DOMAIN: {"name": "test", "state_topic": "test-topic"}}
|
||||
DOMAIN: {sensor.DOMAIN: {"name": "test", "state_topic": "test-topic"}}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +93,7 @@ DEFAULT_CONFIG = {
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -122,7 +123,7 @@ async def test_setting_sensor_value_via_mqtt_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -164,7 +165,7 @@ async def test_setting_enum_sensor_value_via_mqtt_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -200,7 +201,7 @@ async def test_handling_undecoded_sensor_value(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -363,7 +364,7 @@ async def test_setting_sensor_native_value_handling_via_mqtt_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -420,7 +421,7 @@ async def test_setting_numeric_sensor_native_value_handling_via_mqtt_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -454,7 +455,7 @@ async def test_setting_sensor_value_expires_availability_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -550,7 +551,7 @@ async def expires_helper(hass: HomeAssistant) -> None:
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -582,7 +583,7 @@ async def test_setting_sensor_value_via_mqtt_json_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -617,7 +618,7 @@ async def test_setting_sensor_value_via_mqtt_json_message_and_default_current_st
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_class": "total",
|
||||
@@ -667,7 +668,7 @@ async def test_setting_sensor_last_reset_via_mqtt_json_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_class": "total",
|
||||
@@ -705,7 +706,7 @@ async def test_setting_sensor_last_reset_via_mqtt_json_message_2(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -742,7 +743,7 @@ async def test_force_update_disabled(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -865,7 +866,7 @@ async def test_discovery_update_availability(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -887,7 +888,7 @@ async def test_invalid_device_class(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -912,7 +913,7 @@ async def test_invalid_unit_of_measurement(
|
||||
)
|
||||
# A repair issue was logged for the failing YAML config
|
||||
assert len(events) == 1
|
||||
assert events[0].data["domain"] == mqtt.DOMAIN
|
||||
assert events[0].data["domain"] == DOMAIN
|
||||
# Assert the sensor is not created
|
||||
state = hass.states.get("sensor.test")
|
||||
assert state is None
|
||||
@@ -923,7 +924,7 @@ async def test_invalid_unit_of_measurement(
|
||||
[
|
||||
pytest.param(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -939,7 +940,7 @@ async def test_invalid_unit_of_measurement(
|
||||
),
|
||||
pytest.param(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -955,7 +956,7 @@ async def test_invalid_unit_of_measurement(
|
||||
),
|
||||
pytest.param(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -971,7 +972,7 @@ async def test_invalid_unit_of_measurement(
|
||||
),
|
||||
pytest.param(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -987,7 +988,7 @@ async def test_invalid_unit_of_measurement(
|
||||
),
|
||||
pytest.param(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -1003,7 +1004,7 @@ async def test_invalid_unit_of_measurement(
|
||||
),
|
||||
pytest.param(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -1061,7 +1062,7 @@ async def test_device_class_with_equivalent_unit_of_measurement_received(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -1115,7 +1116,7 @@ async def test_equivalent_unit_of_measurement_received_without_device_class(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -1191,7 +1192,7 @@ async def test_valid_device_class_and_uom(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -1213,7 +1214,7 @@ async def test_invalid_state_class(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -1240,7 +1241,7 @@ async def test_invalid_state_class_with_unit_of_measurement(
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -1254,7 +1255,7 @@ async def test_invalid_state_class_with_unit_of_measurement(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -1268,7 +1269,7 @@ async def test_invalid_state_class_with_unit_of_measurement(
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -1294,7 +1295,7 @@ async def test_invalid_options_config(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -1402,7 +1403,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -1678,7 +1679,7 @@ async def test_entity_category(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -1838,7 +1839,7 @@ async def test_encoding_subscribable_topics(
|
||||
hass,
|
||||
mqtt_mock_entry,
|
||||
sensor.DOMAIN,
|
||||
DEFAULT_CONFIG[mqtt.DOMAIN][sensor.DOMAIN],
|
||||
DEFAULT_CONFIG[DOMAIN][sensor.DOMAIN],
|
||||
topic,
|
||||
value,
|
||||
attribute,
|
||||
@@ -2023,7 +2024,7 @@ async def test_value_incorrect_state_class_config(
|
||||
)
|
||||
caplog.clear()
|
||||
|
||||
config_payload = hass_config[mqtt.DOMAIN][sensor.DOMAIN][0]
|
||||
config_payload = hass_config[DOMAIN][sensor.DOMAIN][0]
|
||||
async_fire_mqtt_message(
|
||||
hass, "homeassistant/sensor/bla/config", json.dumps(config_payload)
|
||||
)
|
||||
|
||||
@@ -6,7 +6,8 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt, siren
|
||||
from homeassistant.components import siren
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.siren import ATTR_VOLUME_LEVEL
|
||||
from homeassistant.const import (
|
||||
ATTR_ASSUMED_STATE,
|
||||
@@ -55,7 +56,7 @@ from tests.common import async_fire_mqtt_message
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {siren.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
DOMAIN: {siren.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +83,7 @@ async def async_turn_off(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
siren.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -119,7 +120,7 @@ async def test_controlling_state_via_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
siren.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -164,7 +165,7 @@ async def test_sending_mqtt_commands_and_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
siren.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -205,7 +206,7 @@ async def test_controlling_state_via_topic_and_json_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
siren.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -292,7 +293,7 @@ async def test_controlling_state_and_attributes_with_json_message_without_templa
|
||||
help_custom_config(
|
||||
siren.DOMAIN,
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
siren.DOMAIN: {
|
||||
"command_topic": "command-topic",
|
||||
}
|
||||
@@ -387,7 +388,7 @@ async def test_filtering_not_supported_attributes_optimistic(
|
||||
help_custom_config(
|
||||
siren.DOMAIN,
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
siren.DOMAIN: {
|
||||
"command_topic": "command-topic",
|
||||
}
|
||||
@@ -495,7 +496,7 @@ async def test_default_availability_payload(
|
||||
) -> None:
|
||||
"""Test availability by default payload with defined topic."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
siren.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -521,7 +522,7 @@ async def test_custom_availability_payload(
|
||||
) -> None:
|
||||
"""Test availability by custom payload with defined topic."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
siren.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -547,7 +548,7 @@ async def test_custom_availability_payload(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
siren.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -644,7 +645,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
siren.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -686,8 +687,8 @@ async def test_discovery_update_siren_topic_template(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test update of discovered siren."""
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][siren.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][siren.DOMAIN])
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][siren.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][siren.DOMAIN])
|
||||
config1["name"] = "Beer"
|
||||
config2["name"] = "Milk"
|
||||
config1["state_topic"] = "siren/state1"
|
||||
@@ -722,8 +723,8 @@ async def test_discovery_update_siren_template(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test update of discovered siren."""
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][siren.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][siren.DOMAIN])
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][siren.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][siren.DOMAIN])
|
||||
config1["name"] = "Beer"
|
||||
config2["name"] = "Milk"
|
||||
config1["state_topic"] = "siren/state1"
|
||||
@@ -987,7 +988,7 @@ async def test_publishing_with_custom_encoding(
|
||||
"""Test publishing MQTT payload with command templates and different encoding."""
|
||||
domain = siren.DOMAIN
|
||||
config: dict[str, Any] = copy.deepcopy(DEFAULT_CONFIG)
|
||||
config[mqtt.DOMAIN][domain][siren.ATTR_AVAILABLE_TONES] = ["siren", "xylophone"]
|
||||
config[DOMAIN][domain][siren.ATTR_AVAILABLE_TONES] = ["siren", "xylophone"]
|
||||
|
||||
await help_test_publishing_with_custom_encoding(
|
||||
hass,
|
||||
@@ -1029,7 +1030,7 @@ async def test_encoding_subscribable_topics(
|
||||
hass,
|
||||
mqtt_mock_entry,
|
||||
siren.DOMAIN,
|
||||
DEFAULT_CONFIG[mqtt.DOMAIN][siren.DOMAIN],
|
||||
DEFAULT_CONFIG[DOMAIN][siren.DOMAIN],
|
||||
topic,
|
||||
value,
|
||||
attribute,
|
||||
|
||||
@@ -6,7 +6,8 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt, switch
|
||||
from homeassistant.components import switch
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.const import (
|
||||
ATTR_ASSUMED_STATE,
|
||||
ATTR_DEVICE_CLASS,
|
||||
@@ -52,7 +53,7 @@ from tests.components.switch import common
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {switch.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
DOMAIN: {switch.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +62,7 @@ DEFAULT_CONFIG = {
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
switch.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -76,7 +77,7 @@ DEFAULT_CONFIG = {
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
switch.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -124,7 +125,7 @@ async def test_controlling_state_via_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
switch.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -171,7 +172,7 @@ async def test_sending_mqtt_commands_and_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
switch.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -195,7 +196,7 @@ async def test_sending_inital_state_and_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
switch.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -239,7 +240,7 @@ async def test_sending_mqtt_commands_with_command_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
switch.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -302,7 +303,7 @@ async def test_default_availability_payload(
|
||||
) -> None:
|
||||
"""Test availability by default payload with defined topic."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
switch.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -328,7 +329,7 @@ async def test_custom_availability_payload(
|
||||
) -> None:
|
||||
"""Test availability by custom payload with defined topic."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
switch.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -354,7 +355,7 @@ async def test_custom_availability_payload(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
switch.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -451,7 +452,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
switch.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -493,8 +494,8 @@ async def test_discovery_update_switch_topic_template(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test update of discovered switch."""
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][switch.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][switch.DOMAIN])
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][switch.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][switch.DOMAIN])
|
||||
config1["name"] = "Beer"
|
||||
config2["name"] = "Milk"
|
||||
config1["state_topic"] = "switch/state1"
|
||||
@@ -529,8 +530,8 @@ async def test_discovery_update_switch_template(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test update of discovered switch."""
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][switch.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][switch.DOMAIN])
|
||||
config1 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][switch.DOMAIN])
|
||||
config2 = copy.deepcopy(DEFAULT_CONFIG[DOMAIN][switch.DOMAIN])
|
||||
config1["name"] = "Beer"
|
||||
config2["name"] = "Milk"
|
||||
config1["state_topic"] = "switch/state1"
|
||||
@@ -737,7 +738,7 @@ async def test_encoding_subscribable_topics(
|
||||
hass,
|
||||
mqtt_mock_entry,
|
||||
switch.DOMAIN,
|
||||
DEFAULT_CONFIG[mqtt.DOMAIN][switch.DOMAIN],
|
||||
DEFAULT_CONFIG[DOMAIN][switch.DOMAIN],
|
||||
topic,
|
||||
value,
|
||||
attribute,
|
||||
|
||||
@@ -5,7 +5,8 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt, text
|
||||
from homeassistant.components import text
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.const import ATTR_ASSUMED_STATE, ATTR_ENTITY_ID, STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
@@ -44,7 +45,7 @@ from tests.common import async_fire_mqtt_message
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {text.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
DOMAIN: {text.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +65,7 @@ async def async_set_value(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
text.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -106,7 +107,7 @@ async def test_controlling_state_via_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
text.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -163,7 +164,7 @@ async def test_forced_text_length(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
text.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -237,7 +238,7 @@ async def test_controlling_validation_state_via_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
text.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -260,7 +261,7 @@ async def test_attribute_validation_max_greater_then_min(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
text.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -283,7 +284,7 @@ async def test_attribute_validation_max_not_greater_then_max_state_length(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
text.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -313,7 +314,7 @@ async def test_validation_payload_greater_then_max_state_length(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
text.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -356,7 +357,7 @@ async def test_sending_mqtt_commands_and_optimistic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
text.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -421,7 +422,7 @@ async def test_default_availability_payload(
|
||||
) -> None:
|
||||
"""Test availability by default payload with defined topic."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
text.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -439,7 +440,7 @@ async def test_custom_availability_payload(
|
||||
) -> None:
|
||||
"""Test availability by custom payload with defined topic."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
text.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -515,7 +516,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
text.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -758,7 +759,7 @@ async def test_encoding_subscribable_topics(
|
||||
hass,
|
||||
mqtt_mock_entry,
|
||||
text.DOMAIN,
|
||||
DEFAULT_CONFIG[mqtt.DOMAIN][text.DOMAIN],
|
||||
DEFAULT_CONFIG[DOMAIN][text.DOMAIN],
|
||||
topic,
|
||||
value,
|
||||
attribute,
|
||||
|
||||
@@ -6,7 +6,8 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt, time
|
||||
from homeassistant.components import time
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.const import ATTR_ASSUMED_STATE, ATTR_ENTITY_ID, STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
@@ -44,7 +45,7 @@ from tests.common import async_fire_mqtt_message
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {time.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
DOMAIN: {time.DOMAIN: {"name": "test", "command_topic": "test-topic"}}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +65,7 @@ async def async_set_value(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
time.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -116,7 +117,7 @@ async def test_controlling_state_via_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
time.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -155,7 +156,7 @@ async def test_controlling_validation_state_via_topic(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
time.DOMAIN: {
|
||||
"name": "test",
|
||||
"command_topic": "command-topic",
|
||||
@@ -221,7 +222,7 @@ async def test_default_availability_payload(
|
||||
) -> None:
|
||||
"""Test availability by default payload with defined topic."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
time.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -239,7 +240,7 @@ async def test_custom_availability_payload(
|
||||
) -> None:
|
||||
"""Test availability by custom payload with defined topic."""
|
||||
config = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
time.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
@@ -315,7 +316,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
time.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -494,7 +495,7 @@ async def test_encoding_subscribable_topics(
|
||||
hass,
|
||||
mqtt_mock_entry,
|
||||
time.DOMAIN,
|
||||
DEFAULT_CONFIG[mqtt.DOMAIN][time.DOMAIN],
|
||||
DEFAULT_CONFIG[DOMAIN][time.DOMAIN],
|
||||
topic,
|
||||
value,
|
||||
attribute,
|
||||
|
||||
@@ -6,7 +6,8 @@ from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt, update
|
||||
from homeassistant.components import update
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.update import DOMAIN as UPDATE_DOMAIN, SERVICE_INSTALL
|
||||
from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON, STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
@@ -42,7 +43,7 @@ from tests.common import async_fire_mqtt_message
|
||||
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
update.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
@@ -59,7 +60,7 @@ DEFAULT_CONFIG = {
|
||||
[
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
update.DOMAIN: {
|
||||
"state_topic": "test/installed-version",
|
||||
"latest_version_topic": "test/latest-version",
|
||||
@@ -76,7 +77,7 @@ DEFAULT_CONFIG = {
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
update.DOMAIN: {
|
||||
"state_topic": "test/installed-version",
|
||||
"latest_version_topic": "test/latest-version",
|
||||
@@ -132,7 +133,7 @@ async def test_run_update_setup(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
update.DOMAIN: {
|
||||
"state_topic": "test/installed-version",
|
||||
"latest_version_topic": "test/latest-version",
|
||||
@@ -182,7 +183,7 @@ async def test_run_update_setup_float(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
update.DOMAIN: {
|
||||
"state_topic": "test/installed-version",
|
||||
"value_template": "{{ value_json.installed }}",
|
||||
@@ -227,7 +228,7 @@ async def test_value_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
update.DOMAIN: {
|
||||
"state_topic": "test/update",
|
||||
"value_template": (
|
||||
@@ -298,7 +299,7 @@ async def test_errornous_value_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
update.DOMAIN: {
|
||||
"state_topic": "test/installed-version",
|
||||
"value_template": "{{ value_json.installed }}",
|
||||
@@ -343,7 +344,7 @@ async def test_value_template_float(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
update.DOMAIN: {
|
||||
"state_topic": "test/state-topic",
|
||||
"name": "Test Update",
|
||||
@@ -371,7 +372,7 @@ async def test_empty_json_state_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
update.DOMAIN: {
|
||||
"state_topic": "test/state-topic",
|
||||
"name": "Test Update",
|
||||
@@ -424,7 +425,7 @@ async def test_invalid_json_state_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
update.DOMAIN: {
|
||||
"state_topic": "test/state-topic",
|
||||
"name": "Test Update",
|
||||
@@ -520,7 +521,7 @@ async def test_json_state_message(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
update.DOMAIN: {
|
||||
"state_topic": "test/state-topic",
|
||||
"value_template": '{{ {"installed_version": value_json.installed, '
|
||||
@@ -561,7 +562,7 @@ async def test_json_state_message_with_template(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
update.DOMAIN: {
|
||||
"state_topic": "test/installed-version",
|
||||
"latest_version_topic": "test/latest-version",
|
||||
@@ -695,7 +696,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
update.DOMAIN: [
|
||||
{
|
||||
"name": "Bear",
|
||||
@@ -725,7 +726,7 @@ async def test_discovery_removal_update(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test removal of discovered update."""
|
||||
data = json.dumps(DEFAULT_CONFIG[mqtt.DOMAIN][update.DOMAIN])
|
||||
data = json.dumps(DEFAULT_CONFIG[DOMAIN][update.DOMAIN])
|
||||
await help_test_discovery_removal(hass, mqtt_mock_entry, update.DOMAIN, data)
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ from unittest.mock import MagicMock, patch
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt
|
||||
from homeassistant.components.mqtt.const import DOMAIN
|
||||
from homeassistant.components.mqtt.models import MessageCallbackType
|
||||
from homeassistant.components.mqtt.util import EnsureJobAfterCooldown
|
||||
from homeassistant.config_entries import ConfigEntryDisabler, ConfigEntryState
|
||||
@@ -222,7 +223,7 @@ async def test_waiting_for_client_not_loaded(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={"broker": "test-broker"},
|
||||
state=ConfigEntryState.NOT_LOADED,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
@@ -263,7 +264,7 @@ async def test_waiting_for_client_loaded(
|
||||
assert await mqtt.async_wait_for_mqtt_client(hass)
|
||||
unsub = await mqtt.async_subscribe(hass, "test_topic", lambda msg: None)
|
||||
|
||||
entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
|
||||
await _async_just_in_time_subscribe()
|
||||
@@ -281,7 +282,7 @@ async def test_waiting_for_client_entry_fails(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={"broker": "test-broker"},
|
||||
state=ConfigEntryState.NOT_LOADED,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
@@ -311,7 +312,7 @@ async def test_waiting_for_client_setup_fails(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={"broker": "test-broker"},
|
||||
state=ConfigEntryState.NOT_LOADED,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
@@ -340,7 +341,7 @@ async def test_waiting_for_client_timeout(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={"broker": "test-broker"},
|
||||
state=ConfigEntryState.NOT_LOADED,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
@@ -361,7 +362,7 @@ async def test_waiting_for_client_with_disabled_entry(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=mqtt.DOMAIN,
|
||||
domain=DOMAIN,
|
||||
data={"broker": "test-broker"},
|
||||
state=ConfigEntryState.NOT_LOADED,
|
||||
version=mqtt.CONFIG_ENTRY_VERSION,
|
||||
|
||||
@@ -7,9 +7,13 @@ from unittest.mock import call, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt, vacuum
|
||||
from homeassistant.components import vacuum
|
||||
from homeassistant.components.mqtt import vacuum as mqttvacuum
|
||||
from homeassistant.components.mqtt.const import CONF_COMMAND_TOPIC, CONF_STATE_TOPIC
|
||||
from homeassistant.components.mqtt.const import (
|
||||
CONF_COMMAND_TOPIC,
|
||||
CONF_STATE_TOPIC,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.components.mqtt.vacuum import (
|
||||
ALL_SERVICES,
|
||||
MQTT_VACUUM_ATTRIBUTES_BLOCKED,
|
||||
@@ -80,7 +84,7 @@ SEND_COMMAND_TOPIC = "vacuum/send_command"
|
||||
STATE_TOPIC = "vacuum/state"
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
vacuum.DOMAIN: {
|
||||
CONF_NAME: "mqtttest",
|
||||
CONF_COMMAND_TOPIC: COMMAND_TOPIC,
|
||||
@@ -93,7 +97,7 @@ DEFAULT_CONFIG = {
|
||||
}
|
||||
|
||||
CONFIG_CLEAN_SEGMENTS = {
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
vacuum.DOMAIN: {
|
||||
CONF_NAME: "test",
|
||||
CONF_STATE_TOPIC: STATE_TOPIC,
|
||||
@@ -103,7 +107,7 @@ CONFIG_CLEAN_SEGMENTS = {
|
||||
}
|
||||
}
|
||||
|
||||
DEFAULT_CONFIG_2 = {mqtt.DOMAIN: {vacuum.DOMAIN: {"name": "test"}}}
|
||||
DEFAULT_CONFIG_2 = {DOMAIN: {vacuum.DOMAIN: {"name": "test"}}}
|
||||
|
||||
CONFIG_ALL_SERVICES = help_custom_config(
|
||||
vacuum.DOMAIN,
|
||||
@@ -363,10 +367,10 @@ async def test_clean_segments_command(
|
||||
mqtt_mock_entry: MqttMockHAClientGenerator,
|
||||
) -> None:
|
||||
"""Test cleaning segments and repair flow."""
|
||||
config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||
config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
entity_registry.async_get_or_create(
|
||||
vacuum.DOMAIN,
|
||||
mqtt.DOMAIN,
|
||||
DOMAIN,
|
||||
"veryunique",
|
||||
config_entry=config_entry,
|
||||
suggested_object_id="test",
|
||||
@@ -549,7 +553,7 @@ async def test_removing_clean_segments_command_topic_resets_feature(
|
||||
"""
|
||||
await mqtt_mock_entry()
|
||||
|
||||
config_with_clean_segments_command_topic = CONFIG_CLEAN_SEGMENTS[mqtt.DOMAIN][
|
||||
config_with_clean_segments_command_topic = CONFIG_CLEAN_SEGMENTS[DOMAIN][
|
||||
vacuum.DOMAIN
|
||||
]
|
||||
async_fire_mqtt_message(
|
||||
@@ -617,7 +621,7 @@ async def test_clean_area_feature_preserved_on_config_update(
|
||||
"""
|
||||
await mqtt_mock_entry()
|
||||
|
||||
config = CONFIG_CLEAN_SEGMENTS[mqtt.DOMAIN][vacuum.DOMAIN]
|
||||
config = CONFIG_CLEAN_SEGMENTS[DOMAIN][vacuum.DOMAIN]
|
||||
async_fire_mqtt_message(
|
||||
hass,
|
||||
"homeassistant/vacuum/bla/config",
|
||||
@@ -865,7 +869,7 @@ async def test_discovery_update_attr(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
DOMAIN: {
|
||||
vacuum.DOMAIN: [
|
||||
{
|
||||
"name": "Test 1",
|
||||
@@ -1036,7 +1040,7 @@ async def test_publishing_with_custom_encoding(
|
||||
"""Test publishing MQTT payload with different encoding."""
|
||||
domain = vacuum.DOMAIN
|
||||
config = deepcopy(DEFAULT_CONFIG)
|
||||
config[mqtt.DOMAIN][domain]["supported_features"] = [
|
||||
config[DOMAIN][domain]["supported_features"] = [
|
||||
"clean_spot",
|
||||
"fan_speed",
|
||||
"locate",
|
||||
@@ -1101,7 +1105,7 @@ async def test_encoding_subscribable_topics(
|
||||
hass,
|
||||
mqtt_mock_entry,
|
||||
vacuum.DOMAIN,
|
||||
DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN],
|
||||
DEFAULT_CONFIG[DOMAIN][vacuum.DOMAIN],
|
||||
topic,
|
||||
value,
|
||||
attribute,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user