Skip to content

Commit fa9e39a

Browse files
committed
Add AVR-X2700H model and handle SVOFF video select
1 parent 7f268e1 commit fa9e39a

File tree

4 files changed

+78
-5
lines changed

4 files changed

+78
-5
lines changed

src/denon_rs232/__init__.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ class InputSource(Enum):
8989
NET = "NET"
9090
BT = "BT"
9191
USB_IPOD = "USB/IPOD"
92+
EIGHT_K = "8K"
9293

9394
# Streaming / online services
9495
PANDORA = "PANDORA"
@@ -538,8 +539,11 @@ async def cancel_video_select(self) -> None:
538539
"""Cancel video select (return to following input source)."""
539540
await self._send_command("SV", "SOURCE")
540541

541-
async def query_video_select(self) -> InputSource:
542-
return InputSource(await self._query("SV"))
542+
async def query_video_select(self) -> InputSource | None:
543+
param = await self._query("SV")
544+
if param in ("SOURCE", "OFF"):
545+
return None
546+
return InputSource(param)
543547

544548
# -- Rec select commands --
545549

@@ -847,7 +851,7 @@ def _process_message(self, message: str) -> None:
847851
_LOGGER.warning("Unknown digital input mode: %s", param)
848852

849853
elif prefix == "SV":
850-
if param == "SOURCE":
854+
if param in ("SOURCE", "OFF"):
851855
self._state.video_select = None
852856
changed = True
853857
else:

src/denon_rs232/models.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ class ReceiverModel:
239239
)
240240

241241

242-
# -- Modern era (~2012-2016) --
242+
# -- Modern era (~2012+) --
243243

244244
AVR_X1000 = ReceiverModel(
245245
name="AVR-X1000 / AVR-E300",
@@ -342,6 +342,34 @@ class ReceiverModel:
342342
zone3_prefix="Z3",
343343
)
344344

345+
AVR_X2700H = ReceiverModel(
346+
name="AVR-X2700H",
347+
input_sources=frozenset({
348+
InputSource.PHONO,
349+
InputSource.CD,
350+
InputSource.TUNER,
351+
InputSource.DVD,
352+
InputSource.BD,
353+
InputSource.TV,
354+
InputSource.SAT_CBL,
355+
InputSource.MPLAY,
356+
InputSource.GAME,
357+
InputSource.AUX1,
358+
InputSource.AUX2,
359+
InputSource.NET,
360+
InputSource.BT,
361+
InputSource.USB_IPOD,
362+
InputSource.EIGHT_K,
363+
}),
364+
digital_inputs=_GEN3_DIGITAL,
365+
surround_modes=(
366+
*_MODERN_SURROUND,
367+
"DOLBY ATMOS",
368+
"DTS:X",
369+
"DTS:X MSTR",
370+
),
371+
)
372+
345373
# -- Other (unknown model) --
346374

347375
OTHER = ReceiverModel(
@@ -390,6 +418,7 @@ class ReceiverModel:
390418
AVR_X1000,
391419
AVR_X4000,
392420
AVR_X4200W,
421+
AVR_X2700H,
393422
)
394423

395424
#: Models keyed by identifier string, for lookup. Includes "other".
@@ -404,5 +433,6 @@ class ReceiverModel:
404433
"avr_x1000": AVR_X1000,
405434
"avr_x4000": AVR_X4000,
406435
"avr_x4200w": AVR_X4200W,
436+
"avr_x2700h": AVR_X2700H,
407437
"other": OTHER,
408438
}

tests/test_denon_rs232.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,17 @@ async def respond():
637637
assert result == InputSource.DVD
638638

639639

640+
async def test_query_video_select_off_returns_none(receiver, mock_serial):
641+
async def respond():
642+
await asyncio.sleep(0.05)
643+
mock_serial.inject_response("SVOFF")
644+
645+
task = asyncio.create_task(respond())
646+
result = await receiver.query_video_select()
647+
await task
648+
assert result is None
649+
650+
640651
async def test_query_rec_select(receiver, mock_serial):
641652
async def respond():
642653
await asyncio.sleep(0.05)
@@ -885,6 +896,18 @@ async def test_video_select_source_event(receiver, mock_serial):
885896
assert states[-1].video_select is None
886897

887898

899+
async def test_video_select_off_event(receiver, mock_serial, caplog):
900+
"""SV OFF should clear video_select to None without warning."""
901+
states: list[DenonState] = []
902+
receiver.subscribe(lambda s: states.append(s))
903+
904+
mock_serial.inject_response("SVOFF")
905+
await asyncio.sleep(0.1)
906+
907+
assert states[-1].video_select is None
908+
assert "Unknown video source: OFF" not in caplog.text
909+
910+
888911
# -- Event tests: rec select --
889912

890913

tests/test_models.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
AVR_4308CI,
1212
AVR_987,
1313
AVR_X1000,
14+
AVR_X2700H,
1415
AVR_X4000,
1516
AVR_X4200W,
1617
)
@@ -157,14 +158,29 @@ def test_avr_x4200w_zone3():
157158
assert AVR_X4200W.zone3_prefix == "Z3"
158159

159160

161+
# -- AVR-X2700H (modern with 8K source) --
162+
163+
164+
def test_avr_x2700h_has_8k_and_modern_core_sources():
165+
assert InputSource.EIGHT_K in AVR_X2700H.input_sources
166+
assert InputSource.BD in AVR_X2700H.input_sources
167+
assert InputSource.MPLAY in AVR_X2700H.input_sources
168+
assert InputSource.NET in AVR_X2700H.input_sources
169+
170+
171+
def test_avr_x2700h_no_zone3():
172+
assert AVR_X2700H.zone3_prefix is None
173+
174+
160175
# -- General model checks --
161176

162177

163178
def test_all_models_tuple():
164179
"""ALL_MODELS should contain all defined models."""
165-
assert len(ALL_MODELS) == 10
180+
assert len(ALL_MODELS) == 11
166181
assert AVR_3805 in ALL_MODELS
167182
assert AVR_X4200W in ALL_MODELS
183+
assert AVR_X2700H in ALL_MODELS
168184

169185

170186
def test_all_models_have_auto_digital():

0 commit comments

Comments
 (0)