Bump infrared-protocols to 8.1.0 (#176625)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Abílio Costa
2026-07-21 10:52:45 +01:00
committed by GitHub
parent e562d7517f
commit c0c31d1323
16 changed files with 203 additions and 85 deletions
@@ -1,9 +1,13 @@
"""Edifier infrared integration for Home Assistant."""
from infrared_protocols.codes.edifier.models import MODEL_TO_COMMAND_SET, EdifierModel
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.const import CONF_MODEL, Platform
from homeassistant.core import HomeAssistant
from .const import CONF_COMMAND_SET, CONF_INFRARED_ENTITY_ID
PLATFORMS = [Platform.BUTTON, Platform.MEDIA_PLAYER]
@@ -13,6 +17,30 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return True
async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Migrate old config entries."""
if entry.version > 2:
return False
if entry.version == 1:
data = {**entry.data}
# The R1700BT model was renamed to R1700BT (pre-2017), and its
# command set was split from the one shared with the R1700BTs
# family, which it was incorrectly grouped with.
if data[CONF_MODEL] == "R1700BT":
data[CONF_MODEL] = EdifierModel.R1700BT_PRE_2017.value
command_set = MODEL_TO_COMMAND_SET[EdifierModel(data[CONF_MODEL])]
data[CONF_COMMAND_SET] = command_set.value
hass.config_entries.async_update_entry(
entry,
data=data,
unique_id=f"{command_set.value}_{data[CONF_INFRARED_ENTITY_ID]}",
version=2,
)
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload an Edifier IR config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
@@ -5,7 +5,8 @@ from typing import override
from infrared_protocols.codes.edifier.models import EdifierCommandSet, EdifierModel
from infrared_protocols.codes.edifier.r1280db import EdifierR1280DBCode
from infrared_protocols.codes.edifier.r1700bt import EdifierR1700BTCode
from infrared_protocols.codes.edifier.r1700bt_pre_2017 import EdifierR1700BTPre2017Code
from infrared_protocols.codes.edifier.r1700bts import EdifierR1700BTsCode
from infrared_protocols.codes.edifier.rc20g import EdifierRC20GCode
from infrared_protocols.codes.edifier.s360db import EdifierS360DBCode
from infrared_protocols.codes.edifier.s3000pro import EdifierS3000ProCode
@@ -34,31 +35,43 @@ COMMAND_SET_BUTTONS: dict[
EdifierCommandSet,
tuple[EdifierIrButtonEntityDescription, ...],
] = {
EdifierCommandSet.R1700BT: (
EdifierCommandSet.R1700BT_PRE_2017: (
EdifierIrButtonEntityDescription(
key="bluetooth",
translation_key="bluetooth",
command_code=EdifierR1700BTCode.BLUETOOTH,
command_code=EdifierR1700BTPre2017Code.BLUETOOTH,
),
EdifierIrButtonEntityDescription(
key="line",
translation_key="line",
command_code=EdifierR1700BTPre2017Code.LINE,
),
),
EdifierCommandSet.R1700BTS: (
EdifierIrButtonEntityDescription(
key="bluetooth",
translation_key="bluetooth",
command_code=EdifierR1700BTsCode.BLUETOOTH,
),
EdifierIrButtonEntityDescription(
key="line_1",
translation_key="line_1",
command_code=EdifierR1700BTCode.LINE_1,
command_code=EdifierR1700BTsCode.LINE_1,
),
EdifierIrButtonEntityDescription(
key="line_2",
translation_key="line_2",
command_code=EdifierR1700BTCode.LINE_2,
command_code=EdifierR1700BTsCode.LINE_2,
),
EdifierIrButtonEntityDescription(
key="fx_on",
translation_key="fx_on",
command_code=EdifierR1700BTCode.FX_ON,
command_code=EdifierR1700BTsCode.FX_ON,
),
EdifierIrButtonEntityDescription(
key="fx_off",
translation_key="fx_off",
command_code=EdifierR1700BTCode.FX_OFF,
command_code=EdifierR1700BTsCode.FX_OFF,
),
),
EdifierCommandSet.R1280DB: (
@@ -25,7 +25,7 @@ from .const import CONF_COMMAND_SET, CONF_INFRARED_ENTITY_ID, DOMAIN
class EdifierIrConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle config flow for Edifier IR."""
VERSION = 1
VERSION = 2
MINOR_VERSION = 1
@override
@@ -2,7 +2,8 @@
from infrared_protocols.codes.edifier.r1280db import EdifierR1280DBCode
from infrared_protocols.codes.edifier.r1280t import EdifierR1280TCode
from infrared_protocols.codes.edifier.r1700bt import EdifierR1700BTCode
from infrared_protocols.codes.edifier.r1700bt_pre_2017 import EdifierR1700BTPre2017Code
from infrared_protocols.codes.edifier.r1700bts import EdifierR1700BTsCode
from infrared_protocols.codes.edifier.rc20g import EdifierRC20GCode
from infrared_protocols.codes.edifier.s360db import EdifierS360DBCode
from infrared_protocols.codes.edifier.s3000pro import EdifierS3000ProCode
@@ -12,7 +13,8 @@ CONF_INFRARED_ENTITY_ID = "infrared_entity_id"
CONF_COMMAND_SET = "command_set"
type EdifierCode = (
EdifierR1700BTCode
EdifierR1700BTPre2017Code
| EdifierR1700BTsCode
| EdifierR1280DBCode
| EdifierR1280TCode
| EdifierS360DBCode
@@ -5,7 +5,8 @@ from typing import override
from infrared_protocols.codes.edifier.models import EdifierCommandSet, EdifierModel
from infrared_protocols.codes.edifier.r1280db import EdifierR1280DBCode
from infrared_protocols.codes.edifier.r1280t import EdifierR1280TCode
from infrared_protocols.codes.edifier.r1700bt import EdifierR1700BTCode
from infrared_protocols.codes.edifier.r1700bt_pre_2017 import EdifierR1700BTPre2017Code
from infrared_protocols.codes.edifier.r1700bts import EdifierR1700BTsCode
from infrared_protocols.codes.edifier.rc20g import EdifierRC20GCode
from infrared_protocols.codes.edifier.s360db import EdifierS360DBCode
from infrared_protocols.codes.edifier.s3000pro import EdifierS3000ProCode
@@ -35,18 +36,25 @@ COMMAND_SET_COMMANDS: dict[
tuple[EdifierCode | tuple[EdifierCode, ...], ...],
],
] = {
EdifierCommandSet.R1700BT: {
MediaPlayerEntityFeature.TURN_ON: (EdifierR1700BTCode.POWER,),
MediaPlayerEntityFeature.TURN_OFF: (EdifierR1700BTCode.POWER,),
EdifierCommandSet.R1700BT_PRE_2017: {
MediaPlayerEntityFeature.VOLUME_STEP: (
(EdifierR1700BTCode.VOLUME_UP,),
(EdifierR1700BTCode.VOLUME_DOWN,),
(EdifierR1700BTPre2017Code.VOLUME_UP,),
(EdifierR1700BTPre2017Code.VOLUME_DOWN,),
),
MediaPlayerEntityFeature.VOLUME_MUTE: (EdifierR1700BTCode.MUTE,),
MediaPlayerEntityFeature.PLAY: (EdifierR1700BTCode.PLAY_PAUSE,),
MediaPlayerEntityFeature.PAUSE: (EdifierR1700BTCode.PLAY_PAUSE,),
MediaPlayerEntityFeature.NEXT_TRACK: (EdifierR1700BTCode.FORWARD,),
MediaPlayerEntityFeature.PREVIOUS_TRACK: (EdifierR1700BTCode.BACK,),
MediaPlayerEntityFeature.VOLUME_MUTE: (EdifierR1700BTPre2017Code.MUTE,),
},
EdifierCommandSet.R1700BTS: {
MediaPlayerEntityFeature.TURN_ON: (EdifierR1700BTsCode.POWER,),
MediaPlayerEntityFeature.TURN_OFF: (EdifierR1700BTsCode.POWER,),
MediaPlayerEntityFeature.VOLUME_STEP: (
(EdifierR1700BTsCode.VOLUME_UP,),
(EdifierR1700BTsCode.VOLUME_DOWN,),
),
MediaPlayerEntityFeature.VOLUME_MUTE: (EdifierR1700BTsCode.MUTE,),
MediaPlayerEntityFeature.PLAY: (EdifierR1700BTsCode.PLAY_PAUSE,),
MediaPlayerEntityFeature.PAUSE: (EdifierR1700BTsCode.PLAY_PAUSE,),
MediaPlayerEntityFeature.NEXT_TRACK: (EdifierR1700BTsCode.FORWARD,),
MediaPlayerEntityFeature.PREVIOUS_TRACK: (EdifierR1700BTsCode.BACK,),
},
EdifierCommandSet.R1280DB: {
MediaPlayerEntityFeature.TURN_ON: (EdifierR1280DBCode.POWER,),
@@ -48,6 +48,9 @@
"fx_on": {
"name": "FX on"
},
"line": {
"name": "Line"
},
"line_1": {
"name": "Line 1"
},
@@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/infrared",
"integration_type": "entity",
"quality_scale": "internal",
"requirements": ["infrared-protocols==7.5.0"]
"requirements": ["infrared-protocols==8.1.0"]
}
+1 -1
View File
@@ -30,7 +30,7 @@ home-assistant-bluetooth==2.0.0
home-assistant-intents==2026.6.24
httpx==0.28.1
ifaddr==0.2.0
infrared-protocols==7.5.0
infrared-protocols==8.1.0
Jinja2==3.1.6
lru-dict==1.4.1
mutagen==1.48.1
+1 -1
View File
@@ -1374,7 +1374,7 @@ influxdb-client==1.50.0
influxdb==5.3.2
# homeassistant.components.infrared
infrared-protocols==7.5.0
infrared-protocols==8.1.0
# homeassistant.components.inkbird
inkbird-ble==1.4.4
+11 -5
View File
@@ -28,13 +28,14 @@ def mock_config_entry() -> MockConfigEntry:
return MockConfigEntry(
domain=DOMAIN,
entry_id="01JTEST0000000000000000000",
title="Edifier R1700BT via Test IR emitter",
title="Edifier R1700BTs via Test IR emitter",
data={
CONF_INFRARED_ENTITY_ID: MOCK_INFRARED_EMITTER_ENTITY_ID,
CONF_MODEL: EdifierModel.R1700BT.value,
CONF_COMMAND_SET: EdifierCommandSet.R1700BT.value,
CONF_MODEL: EdifierModel.R1700BTS.value,
CONF_COMMAND_SET: EdifierCommandSet.R1700BTS.value,
},
unique_id=f"r1700bt_{MOCK_INFRARED_EMITTER_ENTITY_ID}",
unique_id=f"r1700bts_{MOCK_INFRARED_EMITTER_ENTITY_ID}",
version=2,
)
@@ -53,7 +54,12 @@ def mock_edifier_code_to_command() -> Generator[None]:
"""
with (
patch(
"infrared_protocols.codes.edifier.r1700bt.EdifierR1700BTCode.to_command",
"infrared_protocols.codes.edifier.r1700bt_pre_2017.EdifierR1700BTPre2017Code.to_command",
autospec=True,
side_effect=lambda self: self,
),
patch(
"infrared_protocols.codes.edifier.r1700bts.EdifierR1700BTsCode.to_command",
autospec=True,
side_effect=lambda self: self,
),
@@ -1,5 +1,5 @@
# serializer version: 1
# name: test_entities[button.edifier_r1700bt_bluetooth-entry]
# name: test_entities[button.edifier_r1700bts_bluetooth-entry]
EntityRegistryEntrySnapshot({
'aliases': list([
None,
@@ -13,7 +13,7 @@
'disabled_by': None,
'domain': 'button',
'entity_category': None,
'entity_id': 'button.edifier_r1700bt_bluetooth',
'entity_id': 'button.edifier_r1700bts_bluetooth',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
@@ -36,20 +36,20 @@
'unit_of_measurement': None,
})
# ---
# name: test_entities[button.edifier_r1700bt_bluetooth-state]
# name: test_entities[button.edifier_r1700bts_bluetooth-state]
StateSnapshot({
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Edifier R1700BT Bluetooth',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Edifier R1700BTs Bluetooth',
}),
'context': <ANY>,
'entity_id': 'button.edifier_r1700bt_bluetooth',
'entity_id': 'button.edifier_r1700bts_bluetooth',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_entities[button.edifier_r1700bt_fx_off-entry]
# name: test_entities[button.edifier_r1700bts_fx_off-entry]
EntityRegistryEntrySnapshot({
'aliases': list([
None,
@@ -63,7 +63,7 @@
'disabled_by': None,
'domain': 'button',
'entity_category': None,
'entity_id': 'button.edifier_r1700bt_fx_off',
'entity_id': 'button.edifier_r1700bts_fx_off',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
@@ -86,20 +86,20 @@
'unit_of_measurement': None,
})
# ---
# name: test_entities[button.edifier_r1700bt_fx_off-state]
# name: test_entities[button.edifier_r1700bts_fx_off-state]
StateSnapshot({
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Edifier R1700BT FX off',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Edifier R1700BTs FX off',
}),
'context': <ANY>,
'entity_id': 'button.edifier_r1700bt_fx_off',
'entity_id': 'button.edifier_r1700bts_fx_off',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_entities[button.edifier_r1700bt_fx_on-entry]
# name: test_entities[button.edifier_r1700bts_fx_on-entry]
EntityRegistryEntrySnapshot({
'aliases': list([
None,
@@ -113,7 +113,7 @@
'disabled_by': None,
'domain': 'button',
'entity_category': None,
'entity_id': 'button.edifier_r1700bt_fx_on',
'entity_id': 'button.edifier_r1700bts_fx_on',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
@@ -136,20 +136,20 @@
'unit_of_measurement': None,
})
# ---
# name: test_entities[button.edifier_r1700bt_fx_on-state]
# name: test_entities[button.edifier_r1700bts_fx_on-state]
StateSnapshot({
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Edifier R1700BT FX on',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Edifier R1700BTs FX on',
}),
'context': <ANY>,
'entity_id': 'button.edifier_r1700bt_fx_on',
'entity_id': 'button.edifier_r1700bts_fx_on',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_entities[button.edifier_r1700bt_line_1-entry]
# name: test_entities[button.edifier_r1700bts_line_1-entry]
EntityRegistryEntrySnapshot({
'aliases': list([
None,
@@ -163,7 +163,7 @@
'disabled_by': None,
'domain': 'button',
'entity_category': None,
'entity_id': 'button.edifier_r1700bt_line_1',
'entity_id': 'button.edifier_r1700bts_line_1',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
@@ -186,20 +186,20 @@
'unit_of_measurement': None,
})
# ---
# name: test_entities[button.edifier_r1700bt_line_1-state]
# name: test_entities[button.edifier_r1700bts_line_1-state]
StateSnapshot({
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Edifier R1700BT Line 1',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Edifier R1700BTs Line 1',
}),
'context': <ANY>,
'entity_id': 'button.edifier_r1700bt_line_1',
'entity_id': 'button.edifier_r1700bts_line_1',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_entities[button.edifier_r1700bt_line_2-entry]
# name: test_entities[button.edifier_r1700bts_line_2-entry]
EntityRegistryEntrySnapshot({
'aliases': list([
None,
@@ -213,7 +213,7 @@
'disabled_by': None,
'domain': 'button',
'entity_category': None,
'entity_id': 'button.edifier_r1700bt_line_2',
'entity_id': 'button.edifier_r1700bts_line_2',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
@@ -236,13 +236,13 @@
'unit_of_measurement': None,
})
# ---
# name: test_entities[button.edifier_r1700bt_line_2-state]
# name: test_entities[button.edifier_r1700bts_line_2-state]
StateSnapshot({
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Edifier R1700BT Line 2',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Edifier R1700BTs Line 2',
}),
'context': <ANY>,
'entity_id': 'button.edifier_r1700bt_line_2',
'entity_id': 'button.edifier_r1700bts_line_2',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
@@ -1,5 +1,5 @@
# serializer version: 1
# name: test_entities[media_player.edifier_r1700bt-entry]
# name: test_entities[media_player.edifier_r1700bts-entry]
EntityRegistryEntrySnapshot({
'aliases': list([
None,
@@ -14,7 +14,7 @@
'disabled_by': None,
'domain': 'media_player',
'entity_category': None,
'entity_id': 'media_player.edifier_r1700bt',
'entity_id': 'media_player.edifier_r1700bts',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
@@ -37,16 +37,16 @@
'unit_of_measurement': None,
})
# ---
# name: test_entities[media_player.edifier_r1700bt-state]
# name: test_entities[media_player.edifier_r1700bts-state]
StateSnapshot({
'attributes': ReadOnlyDict({
<EntityStateAttribute.ASSUMED_STATE: 'assumed_state'>: True,
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'speaker',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Edifier R1700BT',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Edifier R1700BTs',
<EntityStateAttribute.SUPPORTED_FEATURES: 'supported_features'>: <MediaPlayerEntityFeature: 17849>,
}),
'context': <ANY>,
'entity_id': 'media_player.edifier_r1700bt',
'entity_id': 'media_player.edifier_r1700bts',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
@@ -1,6 +1,6 @@
"""Tests for the Edifier Infrared button platform."""
from infrared_protocols.codes.edifier.r1700bt import EdifierR1700BTCode
from infrared_protocols.codes.edifier.r1700bts import EdifierR1700BTsCode
import pytest
from syrupy.assertion import SnapshotAssertion
@@ -14,7 +14,7 @@ from tests.components.common import assert_availability_follows_source_entity
from tests.components.infrared import EMITTER_ENTITY_ID
from tests.components.infrared.common import MockInfraredEmitterEntity
BLUETOOTH_BUTTON_ENTITY_ID = "button.edifier_r1700bt_bluetooth"
BLUETOOTH_BUTTON_ENTITY_ID = "button.edifier_r1700bts_bluetooth"
@pytest.fixture
@@ -37,11 +37,11 @@ async def test_entities(
@pytest.mark.parametrize(
("entity_id", "expected_code"),
[
("button.edifier_r1700bt_bluetooth", EdifierR1700BTCode.BLUETOOTH),
("button.edifier_r1700bt_line_1", EdifierR1700BTCode.LINE_1),
("button.edifier_r1700bt_line_2", EdifierR1700BTCode.LINE_2),
("button.edifier_r1700bt_fx_on", EdifierR1700BTCode.FX_ON),
("button.edifier_r1700bt_fx_off", EdifierR1700BTCode.FX_OFF),
("button.edifier_r1700bts_bluetooth", EdifierR1700BTsCode.BLUETOOTH),
("button.edifier_r1700bts_line_1", EdifierR1700BTsCode.LINE_1),
("button.edifier_r1700bts_line_2", EdifierR1700BTsCode.LINE_2),
("button.edifier_r1700bts_fx_on", EdifierR1700BTsCode.FX_ON),
("button.edifier_r1700bts_fx_off", EdifierR1700BTsCode.FX_OFF),
],
)
@pytest.mark.usefixtures("init_integration")
@@ -49,7 +49,7 @@ async def test_button_press_sends_correct_code(
hass: HomeAssistant,
mock_infrared_emitter_entity: MockInfraredEmitterEntity,
entity_id: str,
expected_code: EdifierR1700BTCode,
expected_code: EdifierR1700BTsCode,
) -> None:
"""Test each button press sends the correct IR code."""
await hass.services.async_call(
@@ -21,7 +21,8 @@ from tests.components.infrared import EMITTER_ENTITY_ID
@pytest.mark.parametrize(
("model", "expected_command_set"),
[
(EdifierModel.R1700BT, EdifierCommandSet.R1700BT),
(EdifierModel.R1700BT_PRE_2017, EdifierCommandSet.R1700BT_PRE_2017),
(EdifierModel.R1700BTS, EdifierCommandSet.R1700BTS),
(EdifierModel.R1280DB, EdifierCommandSet.R1280DB),
(EdifierModel.R1280T, EdifierCommandSet.R1280T),
(EdifierModel.S360DB, EdifierCommandSet.S360DB),
@@ -81,7 +82,7 @@ async def test_user_flow_already_configured(
result["flow_id"],
user_input={
CONF_INFRARED_ENTITY_ID: EMITTER_ENTITY_ID,
CONF_MODEL: EdifierModel.R1700BT.value,
CONF_MODEL: EdifierModel.R1700BTS.value,
},
)
@@ -104,8 +105,8 @@ async def test_user_flow_no_emitters(hass: HomeAssistant) -> None:
@pytest.mark.parametrize(
("entity_name", "expected_title"),
[
(None, "Edifier R1700BT via Test IR emitter"),
("Living room IR", "Edifier R1700BT via Living room IR"),
(None, "Edifier R1700BTs via Test IR emitter"),
("Living room IR", "Edifier R1700BTs via Living room IR"),
],
)
async def test_user_flow_title_from_entity_name(
@@ -124,7 +125,7 @@ async def test_user_flow_title_from_entity_name(
result["flow_id"],
user_input={
CONF_INFRARED_ENTITY_ID: EMITTER_ENTITY_ID,
CONF_MODEL: EdifierModel.R1700BT.value,
CONF_MODEL: EdifierModel.R1700BTS.value,
},
)
@@ -1,9 +1,18 @@
"""Tests for the Edifier Infrared integration setup."""
import pytest
from homeassistant.components.edifier_infrared.const import (
CONF_COMMAND_SET,
CONF_INFRARED_ENTITY_ID,
DOMAIN,
)
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import CONF_MODEL
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
from tests.components.infrared import EMITTER_ENTITY_ID
async def test_setup_and_unload_entry(
@@ -17,3 +26,51 @@ async def test_setup_and_unload_entry(
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.NOT_LOADED
@pytest.mark.parametrize(
("old_model", "old_command_set", "expected_model", "expected_command_set"),
[
pytest.param(
"R1700BT",
"r1700bt",
"R1700BT (pre-2017)",
"r1700bt_pre_2017",
id="r1700bt-to-pre-2017",
),
pytest.param(
"R1700BTs", "r1700bt", "R1700BTs", "r1700bts", id="r1700bts-family"
),
pytest.param("R1280DB", "r1280db", "R1280DB", "r1280db", id="unchanged-model"),
],
)
@pytest.mark.usefixtures("mock_infrared_emitter_entity", "mock_edifier_code_to_command")
async def test_migrate_entry_v1_to_v2(
hass: HomeAssistant,
old_model: str,
old_command_set: str,
expected_model: str,
expected_command_set: str,
) -> None:
"""Test v1 config entries are migrated to the split R1700BT command sets."""
entry = MockConfigEntry(
domain=DOMAIN,
title=f"Edifier {old_model} via Test IR emitter",
data={
CONF_INFRARED_ENTITY_ID: EMITTER_ENTITY_ID,
CONF_MODEL: old_model,
CONF_COMMAND_SET: old_command_set,
},
unique_id=f"{old_command_set}_{EMITTER_ENTITY_ID}",
version=1,
)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.LOADED
assert entry.version == 2
assert entry.data[CONF_MODEL] == expected_model
assert entry.data[CONF_COMMAND_SET] == expected_command_set
assert entry.unique_id == f"{expected_command_set}_{EMITTER_ENTITY_ID}"
@@ -1,7 +1,7 @@
"""Tests for the Edifier Infrared media player platform."""
from infrared_protocols.codes.edifier.models import EdifierCommandSet, EdifierModel
from infrared_protocols.codes.edifier.r1700bt import EdifierR1700BTCode
from infrared_protocols.codes.edifier.r1700bts import EdifierR1700BTsCode
from infrared_protocols.codes.edifier.rc20g import EdifierRC20GCode
import pytest
from syrupy.assertion import SnapshotAssertion
@@ -32,7 +32,7 @@ from tests.components.common import assert_availability_follows_source_entity
from tests.components.infrared import EMITTER_ENTITY_ID
from tests.components.infrared.common import MockInfraredEmitterEntity
MEDIA_PLAYER_ENTITY_ID = "media_player.edifier_r1700bt"
MEDIA_PLAYER_ENTITY_ID = "media_player.edifier_r1700bts"
@pytest.fixture
@@ -55,15 +55,15 @@ async def test_entities(
@pytest.mark.parametrize(
("service", "service_data", "expected_code"),
[
(SERVICE_TURN_ON, {}, EdifierR1700BTCode.POWER),
(SERVICE_TURN_OFF, {}, EdifierR1700BTCode.POWER),
(SERVICE_VOLUME_UP, {}, EdifierR1700BTCode.VOLUME_UP),
(SERVICE_VOLUME_DOWN, {}, EdifierR1700BTCode.VOLUME_DOWN),
(SERVICE_VOLUME_MUTE, {"is_volume_muted": True}, EdifierR1700BTCode.MUTE),
(SERVICE_MEDIA_PLAY, {}, EdifierR1700BTCode.PLAY_PAUSE),
(SERVICE_MEDIA_PAUSE, {}, EdifierR1700BTCode.PLAY_PAUSE),
(SERVICE_MEDIA_NEXT_TRACK, {}, EdifierR1700BTCode.FORWARD),
(SERVICE_MEDIA_PREVIOUS_TRACK, {}, EdifierR1700BTCode.BACK),
(SERVICE_TURN_ON, {}, EdifierR1700BTsCode.POWER),
(SERVICE_TURN_OFF, {}, EdifierR1700BTsCode.POWER),
(SERVICE_VOLUME_UP, {}, EdifierR1700BTsCode.VOLUME_UP),
(SERVICE_VOLUME_DOWN, {}, EdifierR1700BTsCode.VOLUME_DOWN),
(SERVICE_VOLUME_MUTE, {"is_volume_muted": True}, EdifierR1700BTsCode.MUTE),
(SERVICE_MEDIA_PLAY, {}, EdifierR1700BTsCode.PLAY_PAUSE),
(SERVICE_MEDIA_PAUSE, {}, EdifierR1700BTsCode.PLAY_PAUSE),
(SERVICE_MEDIA_NEXT_TRACK, {}, EdifierR1700BTsCode.FORWARD),
(SERVICE_MEDIA_PREVIOUS_TRACK, {}, EdifierR1700BTsCode.BACK),
],
)
@pytest.mark.usefixtures("init_integration")
@@ -72,7 +72,7 @@ async def test_media_player_action_sends_correct_code(
mock_infrared_emitter_entity: MockInfraredEmitterEntity,
service: str,
service_data: dict[str, bool],
expected_code: EdifierR1700BTCode,
expected_code: EdifierR1700BTsCode,
) -> None:
"""Test each media player action sends the correct IR code."""
await hass.services.async_call(