diff --git a/homeassistant/components/androidtv/__init__.py b/homeassistant/components/androidtv/__init__.py index 34c4212c913dbe..199d1c362dd59e 100644 --- a/homeassistant/components/androidtv/__init__.py +++ b/homeassistant/components/androidtv/__init__.py @@ -135,15 +135,16 @@ async def async_connect_androidtv( ) aftv = await async_androidtv_setup( - config[CONF_HOST], - config[CONF_PORT], - adbkey, - config.get(CONF_ADB_SERVER_IP), - config.get(CONF_ADB_SERVER_PORT, DEFAULT_ADB_SERVER_PORT), - state_detection_rules, - config[CONF_DEVICE_CLASS], - timeout, - signer, + host=config[CONF_HOST], + port=config[CONF_PORT], + adbkey=adbkey, + adb_server_ip=config.get(CONF_ADB_SERVER_IP), + adb_server_port=config.get(CONF_ADB_SERVER_PORT, DEFAULT_ADB_SERVER_PORT), + state_detection_rules=state_detection_rules, + device_class=config[CONF_DEVICE_CLASS], + auth_timeout_s=timeout, + signer=signer, + log_errors=False, ) if not aftv.available: diff --git a/homeassistant/components/aosmith/manifest.json b/homeassistant/components/aosmith/manifest.json index eae7981d5b9b99..a928a6677cb2c6 100644 --- a/homeassistant/components/aosmith/manifest.json +++ b/homeassistant/components/aosmith/manifest.json @@ -5,5 +5,5 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/aosmith", "iot_class": "cloud_polling", - "requirements": ["py-aosmith==1.0.11"] + "requirements": ["py-aosmith==1.0.12"] } diff --git a/homeassistant/components/assist_pipeline/pipeline.py b/homeassistant/components/assist_pipeline/pipeline.py index 9e9e84fb5d6ea1..f8f6be3a40fdad 100644 --- a/homeassistant/components/assist_pipeline/pipeline.py +++ b/homeassistant/components/assist_pipeline/pipeline.py @@ -29,6 +29,7 @@ from homeassistant.components.tts import ( generate_media_source_id as tts_generate_media_source_id, ) +from homeassistant.const import MATCH_ALL from homeassistant.core import Context, HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import intent @@ -1009,12 +1010,19 @@ async def recognize_intent( if self.intent_agent is None: raise RuntimeError("Recognize intent was not prepared") + if self.pipeline.conversation_language == MATCH_ALL: + # LLMs support all languages ('*') so use pipeline language for + # intent fallback. + input_language = self.pipeline.language + else: + input_language = self.pipeline.conversation_language + self.process_event( PipelineEvent( PipelineEventType.INTENT_START, { "engine": self.intent_agent, - "language": self.pipeline.conversation_language, + "language": input_language, "intent_input": intent_input, "conversation_id": conversation_id, "device_id": device_id, @@ -1029,7 +1037,7 @@ async def recognize_intent( context=self.context, conversation_id=conversation_id, device_id=device_id, - language=self.pipeline.language, + language=input_language, agent_id=self.intent_agent, ) processed_locally = self.intent_agent == conversation.HOME_ASSISTANT_AGENT diff --git a/homeassistant/components/assist_pipeline/vad.py b/homeassistant/components/assist_pipeline/vad.py index deae5b9b7b3876..c7fe1bc10c78e2 100644 --- a/homeassistant/components/assist_pipeline/vad.py +++ b/homeassistant/components/assist_pipeline/vad.py @@ -140,7 +140,7 @@ def process(self, chunk_seconds: float, speech_probability: float | None) -> boo self._timeout_seconds_left -= chunk_seconds if self._timeout_seconds_left <= 0: - _LOGGER.warning( + _LOGGER.debug( "VAD end of speech detection timed out after %s seconds", self.timeout_seconds, ) diff --git a/homeassistant/components/daikin/manifest.json b/homeassistant/components/daikin/manifest.json index f6e9cb78efbccb..f794d97a9ba468 100644 --- a/homeassistant/components/daikin/manifest.json +++ b/homeassistant/components/daikin/manifest.json @@ -6,6 +6,6 @@ "documentation": "https://www.home-assistant.io/integrations/daikin", "iot_class": "local_polling", "loggers": ["pydaikin"], - "requirements": ["pydaikin==2.13.7"], + "requirements": ["pydaikin==2.13.8"], "zeroconf": ["_dkapi._tcp.local."] } diff --git a/homeassistant/components/ecovacs/manifest.json b/homeassistant/components/ecovacs/manifest.json index b9315e0c1c65ac..271f9ee8dcd9b1 100644 --- a/homeassistant/components/ecovacs/manifest.json +++ b/homeassistant/components/ecovacs/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/ecovacs", "iot_class": "cloud_push", "loggers": ["sleekxmppfs", "sucks", "deebot_client"], - "requirements": ["py-sucks==0.9.10", "deebot-client==9.3.0"] + "requirements": ["py-sucks==0.9.10", "deebot-client==9.4.0"] } diff --git a/homeassistant/components/evohome/manifest.json b/homeassistant/components/evohome/manifest.json index da3d197f6aa324..22edadad7f45fe 100644 --- a/homeassistant/components/evohome/manifest.json +++ b/homeassistant/components/evohome/manifest.json @@ -6,5 +6,5 @@ "iot_class": "cloud_polling", "loggers": ["evohomeasync", "evohomeasync2"], "quality_scale": "legacy", - "requirements": ["evohome-async==0.4.20"] + "requirements": ["evohome-async==0.4.21"] } diff --git a/homeassistant/components/frontend/manifest.json b/homeassistant/components/frontend/manifest.json index bfc08c6e11edf6..1f9988dff38019 100644 --- a/homeassistant/components/frontend/manifest.json +++ b/homeassistant/components/frontend/manifest.json @@ -20,5 +20,5 @@ "documentation": "https://www.home-assistant.io/integrations/frontend", "integration_type": "system", "quality_scale": "internal", - "requirements": ["home-assistant-frontend==20241127.7"] + "requirements": ["home-assistant-frontend==20241127.8"] } diff --git a/homeassistant/components/lametric/config_flow.py b/homeassistant/components/lametric/config_flow.py index 36dcdf26ed6368..05c5dea77d1ae9 100644 --- a/homeassistant/components/lametric/config_flow.py +++ b/homeassistant/components/lametric/config_flow.py @@ -249,7 +249,10 @@ async def _async_step_create_entry( device = await lametric.device() if self.source != SOURCE_REAUTH: - await self.async_set_unique_id(device.serial_number) + await self.async_set_unique_id( + device.serial_number, + raise_on_progress=False, + ) self._abort_if_unique_id_configured( updates={CONF_HOST: lametric.host, CONF_API_KEY: lametric.api_key} ) diff --git a/homeassistant/components/lametric/strings.json b/homeassistant/components/lametric/strings.json index 87bda01e305151..0fd6f5a12dc1ab 100644 --- a/homeassistant/components/lametric/strings.json +++ b/homeassistant/components/lametric/strings.json @@ -21,8 +21,11 @@ "api_key": "You can find this API key in [devices page in your LaMetric developer account](https://developer.lametric.com/user/devices)." } }, - "user_cloud_select_device": { + "cloud_select_device": { "data": { + "device": "Device" + }, + "data_description": { "device": "Select the LaMetric device to add" } } diff --git a/homeassistant/components/led_ble/manifest.json b/homeassistant/components/led_ble/manifest.json index 1d12e355a0d2a9..4aaaebc0006bb9 100644 --- a/homeassistant/components/led_ble/manifest.json +++ b/homeassistant/components/led_ble/manifest.json @@ -35,5 +35,5 @@ "dependencies": ["bluetooth_adapters"], "documentation": "https://www.home-assistant.io/integrations/led_ble", "iot_class": "local_polling", - "requirements": ["bluetooth-data-tools==1.20.0", "led-ble==1.0.2"] + "requirements": ["bluetooth-data-tools==1.20.0", "led-ble==1.1.1"] } diff --git a/homeassistant/components/linkplay/manifest.json b/homeassistant/components/linkplay/manifest.json index e74d22b8207e88..cc124ceb611f2a 100644 --- a/homeassistant/components/linkplay/manifest.json +++ b/homeassistant/components/linkplay/manifest.json @@ -7,6 +7,6 @@ "integration_type": "hub", "iot_class": "local_polling", "loggers": ["linkplay"], - "requirements": ["python-linkplay==0.0.20"], + "requirements": ["python-linkplay==0.1.1"], "zeroconf": ["_linkplay._tcp.local."] } diff --git a/homeassistant/components/suez_water/manifest.json b/homeassistant/components/suez_water/manifest.json index 240be0f37bd20f..7e720a86afd9b7 100644 --- a/homeassistant/components/suez_water/manifest.json +++ b/homeassistant/components/suez_water/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/suez_water", "iot_class": "cloud_polling", "loggers": ["pysuez", "regex"], - "requirements": ["pysuezV2==1.3.2"] + "requirements": ["pysuezV2==1.3.5"] } diff --git a/homeassistant/components/vodafone_station/coordinator.py b/homeassistant/components/vodafone_station/coordinator.py index d2f408e355bc4b..e95ca2b5976665 100644 --- a/homeassistant/components/vodafone_station/coordinator.py +++ b/homeassistant/components/vodafone_station/coordinator.py @@ -2,6 +2,7 @@ from dataclasses import dataclass from datetime import datetime, timedelta +from json.decoder import JSONDecodeError from typing import Any from aiovodafone import VodafoneStationDevice, VodafoneStationSercommApi, exceptions @@ -107,6 +108,7 @@ async def _async_update_data(self) -> UpdateCoordinatorDataType: exceptions.CannotConnect, exceptions.AlreadyLogged, exceptions.GenericLoginError, + JSONDecodeError, ) as err: raise UpdateFailed(f"Error fetching data: {err!r}") from err except (ConfigEntryAuthFailed, UpdateFailed): diff --git a/homeassistant/components/withings/manifest.json b/homeassistant/components/withings/manifest.json index 57d4bafdc7b091..886eb66f5e0b7b 100644 --- a/homeassistant/components/withings/manifest.json +++ b/homeassistant/components/withings/manifest.json @@ -8,5 +8,5 @@ "documentation": "https://www.home-assistant.io/integrations/withings", "iot_class": "cloud_push", "loggers": ["aiowithings"], - "requirements": ["aiowithings==3.1.3"] + "requirements": ["aiowithings==3.1.4"] } diff --git a/homeassistant/const.py b/homeassistant/const.py index 412b4b2eb1943b..391a02d07b43d2 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -25,7 +25,7 @@ APPLICATION_NAME: Final = "HomeAssistant" MAJOR_VERSION: Final = 2024 MINOR_VERSION: Final = 12 -PATCH_VERSION: Final = "2" +PATCH_VERSION: Final = "3" __short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__: Final = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 12, 0) diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index aef46c0ffc6816..5d7df8a2ff545e 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -34,7 +34,7 @@ habluetooth==3.6.0 hass-nabucasa==0.86.0 hassil==2.0.5 home-assistant-bluetooth==1.13.0 -home-assistant-frontend==20241127.7 +home-assistant-frontend==20241127.8 home-assistant-intents==2024.12.9 httpx==0.27.2 ifaddr==0.2.0 diff --git a/pyproject.toml b/pyproject.toml index 56347fbd31b96d..ef8ce79f8946b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "homeassistant" -version = "2024.12.2" +version = "2024.12.3" license = {text = "Apache-2.0"} description = "Open-source home automation platform running on Python 3." readme = "README.rst" diff --git a/requirements_all.txt b/requirements_all.txt index a8a7185a22a059..38239d22af2e2b 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -420,7 +420,7 @@ aiowatttime==0.1.1 aiowebostv==0.4.2 # homeassistant.components.withings -aiowithings==3.1.3 +aiowithings==3.1.4 # homeassistant.components.yandex_transport aioymaps==1.2.5 @@ -738,7 +738,7 @@ debugpy==1.8.8 # decora==0.6 # homeassistant.components.ecovacs -deebot-client==9.3.0 +deebot-client==9.4.0 # homeassistant.components.ihc # homeassistant.components.namecheapdns @@ -878,7 +878,7 @@ eufylife-ble-client==0.1.8 # evdev==1.6.1 # homeassistant.components.evohome -evohome-async==0.4.20 +evohome-async==0.4.21 # homeassistant.components.bryant_evolution evolutionhttp==0.0.18 @@ -1130,7 +1130,7 @@ hole==0.8.0 holidays==0.62 # homeassistant.components.frontend -home-assistant-frontend==20241127.7 +home-assistant-frontend==20241127.8 # homeassistant.components.conversation home-assistant-intents==2024.12.9 @@ -1280,7 +1280,7 @@ ld2410-ble==0.1.1 leaone-ble==0.1.0 # homeassistant.components.led_ble -led-ble==1.0.2 +led-ble==1.1.1 # homeassistant.components.lektrico lektricowifi==0.0.43 @@ -1672,7 +1672,7 @@ pushover_complete==1.1.1 pvo==2.1.1 # homeassistant.components.aosmith -py-aosmith==1.0.11 +py-aosmith==1.0.12 # homeassistant.components.canary py-canary==0.5.4 @@ -1835,7 +1835,7 @@ pycsspeechtts==1.0.8 # pycups==2.0.4 # homeassistant.components.daikin -pydaikin==2.13.7 +pydaikin==2.13.8 # homeassistant.components.danfoss_air pydanfossair==0.1.0 @@ -2293,7 +2293,7 @@ pysqueezebox==0.10.0 pystiebeleltron==0.0.1.dev2 # homeassistant.components.suez_water -pysuezV2==1.3.2 +pysuezV2==1.3.5 # homeassistant.components.switchbee pyswitchbee==1.8.3 @@ -2365,7 +2365,7 @@ python-juicenet==1.1.0 python-kasa[speedups]==0.8.1 # homeassistant.components.linkplay -python-linkplay==0.0.20 +python-linkplay==0.1.1 # homeassistant.components.lirc # python-lirc==1.2.3 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index adf1c83b2367a9..1c76684a4a1e9a 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -402,7 +402,7 @@ aiowatttime==0.1.1 aiowebostv==0.4.2 # homeassistant.components.withings -aiowithings==3.1.3 +aiowithings==3.1.4 # homeassistant.components.yandex_transport aioymaps==1.2.5 @@ -628,7 +628,7 @@ dbus-fast==2.24.3 debugpy==1.8.8 # homeassistant.components.ecovacs -deebot-client==9.3.0 +deebot-client==9.4.0 # homeassistant.components.ihc # homeassistant.components.namecheapdns @@ -744,7 +744,7 @@ eternalegypt==0.0.16 eufylife-ble-client==0.1.8 # homeassistant.components.evohome -evohome-async==0.4.20 +evohome-async==0.4.21 # homeassistant.components.bryant_evolution evolutionhttp==0.0.18 @@ -956,7 +956,7 @@ hole==0.8.0 holidays==0.62 # homeassistant.components.frontend -home-assistant-frontend==20241127.7 +home-assistant-frontend==20241127.8 # homeassistant.components.conversation home-assistant-intents==2024.12.9 @@ -1076,7 +1076,7 @@ ld2410-ble==0.1.1 leaone-ble==0.1.0 # homeassistant.components.led_ble -led-ble==1.0.2 +led-ble==1.1.1 # homeassistant.components.lektrico lektricowifi==0.0.43 @@ -1367,7 +1367,7 @@ pushover_complete==1.1.1 pvo==2.1.1 # homeassistant.components.aosmith -py-aosmith==1.0.11 +py-aosmith==1.0.12 # homeassistant.components.canary py-canary==0.5.4 @@ -1485,7 +1485,7 @@ pycountry==24.6.1 pycsspeechtts==1.0.8 # homeassistant.components.daikin -pydaikin==2.13.7 +pydaikin==2.13.8 # homeassistant.components.deako pydeako==0.6.0 @@ -1850,7 +1850,7 @@ pyspeex-noise==1.0.2 pysqueezebox==0.10.0 # homeassistant.components.suez_water -pysuezV2==1.3.2 +pysuezV2==1.3.5 # homeassistant.components.switchbee pyswitchbee==1.8.3 @@ -1892,7 +1892,7 @@ python-juicenet==1.1.0 python-kasa[speedups]==0.8.1 # homeassistant.components.linkplay -python-linkplay==0.0.20 +python-linkplay==0.1.1 # homeassistant.components.matter python-matter-server==6.6.0 diff --git a/tests/components/assist_pipeline/snapshots/test_init.ambr b/tests/components/assist_pipeline/snapshots/test_init.ambr index 3b829e0e14a6c5..d3241b8ac1ff69 100644 --- a/tests/components/assist_pipeline/snapshots/test_init.ambr +++ b/tests/components/assist_pipeline/snapshots/test_init.ambr @@ -142,7 +142,7 @@ 'data': dict({ 'code': 'no_intent_match', }), - 'language': 'en', + 'language': 'en-US', 'response_type': 'error', 'speech': dict({ 'plain': dict({ @@ -233,7 +233,7 @@ 'data': dict({ 'code': 'no_intent_match', }), - 'language': 'en', + 'language': 'en-US', 'response_type': 'error', 'speech': dict({ 'plain': dict({ @@ -387,6 +387,57 @@ }), ]) # --- +# name: test_pipeline_language_used_instead_of_conversation_language + list([ + dict({ + 'data': dict({ + 'language': 'en', + 'pipeline': , + }), + 'type': , + }), + dict({ + 'data': dict({ + 'conversation_id': None, + 'device_id': None, + 'engine': 'conversation.home_assistant', + 'intent_input': 'test input', + 'language': 'en', + 'prefer_local_intents': False, + }), + 'type': , + }), + dict({ + 'data': dict({ + 'intent_output': dict({ + 'conversation_id': None, + 'response': dict({ + 'card': dict({ + }), + 'data': dict({ + 'failed': list([ + ]), + 'success': list([ + ]), + 'targets': list([ + ]), + }), + 'language': 'en', + 'response_type': 'action_done', + 'speech': dict({ + }), + }), + }), + 'processed_locally': True, + }), + 'type': , + }), + dict({ + 'data': None, + 'type': , + }), + ]) +# --- # name: test_wake_word_detection_aborted list([ dict({ diff --git a/tests/components/assist_pipeline/test_init.py b/tests/components/assist_pipeline/test_init.py index b177530219e41d..a3e65766c340e9 100644 --- a/tests/components/assist_pipeline/test_init.py +++ b/tests/components/assist_pipeline/test_init.py @@ -23,6 +23,7 @@ CONF_DEBUG_RECORDING_DIR, DOMAIN, ) +from homeassistant.const import MATCH_ALL from homeassistant.core import Context, HomeAssistant from homeassistant.helpers import intent from homeassistant.setup import async_setup_component @@ -1098,3 +1099,77 @@ async def async_handle( ] == "Order confirmed" ) + + +async def test_pipeline_language_used_instead_of_conversation_language( + hass: HomeAssistant, + hass_ws_client: WebSocketGenerator, + init_components, + snapshot: SnapshotAssertion, +) -> None: + """Test that the pipeline language is used when the conversation language is '*' (all languages).""" + client = await hass_ws_client(hass) + + events: list[assist_pipeline.PipelineEvent] = [] + + await client.send_json_auto_id( + { + "type": "assist_pipeline/pipeline/create", + "conversation_engine": "homeassistant", + "conversation_language": MATCH_ALL, + "language": "en", + "name": "test_name", + "stt_engine": "test", + "stt_language": "en-US", + "tts_engine": "test", + "tts_language": "en-US", + "tts_voice": "Arnold Schwarzenegger", + "wake_word_entity": None, + "wake_word_id": None, + } + ) + msg = await client.receive_json() + assert msg["success"] + pipeline_id = msg["result"]["id"] + pipeline = assist_pipeline.async_get_pipeline(hass, pipeline_id) + + pipeline_input = assist_pipeline.pipeline.PipelineInput( + intent_input="test input", + run=assist_pipeline.pipeline.PipelineRun( + hass, + context=Context(), + pipeline=pipeline, + start_stage=assist_pipeline.PipelineStage.INTENT, + end_stage=assist_pipeline.PipelineStage.INTENT, + event_callback=events.append, + ), + ) + await pipeline_input.validate() + + with patch( + "homeassistant.components.assist_pipeline.pipeline.conversation.async_converse", + return_value=conversation.ConversationResult( + intent.IntentResponse(pipeline.language) + ), + ) as mock_async_converse: + await pipeline_input.execute() + + # Check intent start event + assert process_events(events) == snapshot + intent_start: assist_pipeline.PipelineEvent | None = None + for event in events: + if event.type == assist_pipeline.PipelineEventType.INTENT_START: + intent_start = event + break + + assert intent_start is not None + + # Pipeline language (en) should be used instead of '*' + assert intent_start.data.get("language") == pipeline.language + + # Check input to async_converse + mock_async_converse.assert_called_once() + assert ( + mock_async_converse.call_args_list[0].kwargs.get("language") + == pipeline.language + ) diff --git a/tests/components/conversation/test_default_agent.py b/tests/components/conversation/test_default_agent.py index 39ecdb7f42248a..56f25b62f60f68 100644 --- a/tests/components/conversation/test_default_agent.py +++ b/tests/components/conversation/test_default_agent.py @@ -30,6 +30,7 @@ ATTR_DEVICE_CLASS, ATTR_FRIENDLY_NAME, STATE_CLOSED, + STATE_OFF, STATE_ON, STATE_UNKNOWN, EntityCategory, @@ -3049,3 +3050,49 @@ async def test_entities_names_are_not_templates(hass: HomeAssistant) -> None: assert result is not None assert result.response.response_type == intent.IntentResponseType.ERROR + + +@pytest.mark.parametrize( + ("language", "light_name", "on_sentence", "off_sentence"), + [ + ("en", "test light", "turn on test light", "turn off test light"), + ("zh-cn", "卧室灯", "打开卧室灯", "关闭卧室灯"), + ("zh-hk", "睡房燈", "打開睡房燈", "關閉睡房燈"), + ("zh-tw", "臥室檯燈", "打開臥室檯燈", "關臥室檯燈"), + ], +) +@pytest.mark.usefixtures("init_components") +async def test_turn_on_off( + hass: HomeAssistant, + language: str, + light_name: str, + on_sentence: str, + off_sentence: str, +) -> None: + """Test turn on/off in multiple languages.""" + entity_id = "light.light1234" + hass.states.async_set( + entity_id, STATE_OFF, attributes={ATTR_FRIENDLY_NAME: light_name} + ) + + on_calls = async_mock_service(hass, LIGHT_DOMAIN, "turn_on") + await conversation.async_converse( + hass, + on_sentence, + None, + Context(), + language=language, + ) + assert len(on_calls) == 1 + assert on_calls[0].data.get("entity_id") == [entity_id] + + off_calls = async_mock_service(hass, LIGHT_DOMAIN, "turn_off") + await conversation.async_converse( + hass, + off_sentence, + None, + Context(), + language=language, + ) + assert len(off_calls) == 1 + assert off_calls[0].data.get("entity_id") == [entity_id] diff --git a/tests/components/linkplay/test_diagnostics.py b/tests/components/linkplay/test_diagnostics.py index 369142978a341e..de60b7ecb3acfd 100644 --- a/tests/components/linkplay/test_diagnostics.py +++ b/tests/components/linkplay/test_diagnostics.py @@ -31,8 +31,10 @@ async def test_diagnostics( patch.object(LinkPlayMultiroom, "update_status", return_value=None), ): endpoints = [ - LinkPlayApiEndpoint(protocol="https", endpoint=HOST, session=None), - LinkPlayApiEndpoint(protocol="http", endpoint=HOST, session=None), + LinkPlayApiEndpoint( + protocol="https", port=443, endpoint=HOST, session=None + ), + LinkPlayApiEndpoint(protocol="http", port=80, endpoint=HOST, session=None), ] for endpoint in endpoints: mock_session.get(