Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 19 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,23 +71,25 @@ HDFuryAPI(host: str, session: aiohttp.ClientSession | None = None)

#### Command Methods

| Method | Description |
|-----------------------------------------------------------|------------------------------------|
| `issue_reboot()` | Reboot the device |
| `issue_hotplug()` | Trigger HDMI hotplug |
| `set_operation_mode(mode)` | Set device operation mode |
| `set_port_selection(tx0, tx1)` | Set HDMI input routing for TX0/TX1 |
| `set_auto_switch_inputs(state)` | Toggle auto input switching |
| `set_htpc_mode_rx0(state)` → `set_htpc_mode_rx3(state)` | Enable/disable HTPC mode per input |
| `set_mute_tx0_audio(state)` → `set_mute_tx1_audio(state)` | Mute/unmute TX audio |
| `set_tx0_force_5v(state)` → `set_tx1_force_5v(state)` | Force +5V output on TX ports |
| `set_oled(state)` | Enable/disable OLED display |
| `set_oled_fade(value)` | Set OLED fade timeout (seconds) |
| `set_ir_active(state)` | Enable/disable IR receiver |
| `set_relay(state)` | Enable/disable relay state |
| `set_cec(state)` | Enable/disable global CEC |
| `set_cec_rx0(state)` → `set_cec_rx3(state)` | Enable/disable CEC per input |
| `set_reboot_timer(value)` | Set reboot timer (hours) |
| Method | Description |
|-----------------------------------------------------------|--------------------------------------------|
| `issue_reboot()` | Reboot the device |
| `issue_hotplug()` | Trigger HDMI hotplug |
| `set_operation_mode(mode)` | Set device operation mode |
| `set_port_selection(tx0, tx1)` | Set HDMI input routing for TX0/TX1 |
| `set_auto_switch_inputs(state)` | Toggle auto input switching |
| `set_htpc_mode_rx0(state)` → `set_htpc_mode_rx3(state)` | Enable/disable HTPC mode per input |
| `set_mute_tx0_audio(state)` → `set_mute_tx1_audio(state)` | Mute/unmute TX audio |
| `set_audio_unmute(value)` | Set SINK audio unmute delay (milliseconds) |
| `set_earc_unmute(value)` | Set eARC audio unmute delay (milliseconds) |
| `set_tx0_force_5v(state)` → `set_tx1_force_5v(state)` | Force +5V output on TX ports |
| `set_oled(state)` | Enable/disable OLED display |
| `set_oled_fade(value)` | Set OLED fade timeout (seconds) |
| `set_ir_active(state)` | Enable/disable IR receiver |
| `set_relay(state)` | Enable/disable relay state |
| `set_cec(state)` | Enable/disable global CEC |
| `set_cec_rx0(state)` → `set_cec_rx3(state)` | Enable/disable CEC per input |
| `set_reboot_timer(value)` | Set reboot timer (hours) |

#### Cleanup

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "hdfury"
version = "1.5.0"
version = "1.6.0"
description = "Asynchronous Python client for HDFury devices"
authors = [
{ name = "Glenn de Haan", email = "glenn@dehaan.cloud" }
Expand Down
8 changes: 8 additions & 0 deletions src/hdfury/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,14 @@ async def set_auto_switch_inputs(self, state: str) -> None:
"""Send auto switch inputs command to the device."""
await self._send_command("autosw", self._normalize_state(state, output="text"))

async def set_audio_unmute(self, state: str) -> None:
"""Send audio unmute (milliseconds) command to the device."""
await self._send_command("unmutecnt", state)

async def set_earc_unmute(self, state: str) -> None:
"""Send earc unmute (milliseconds) command to the device."""
await self._send_command("earcunmutecnt", state)

async def set_htpc_mode_rx0(self, state: str) -> None:
"""Send htpc mode rx0 command to the device."""
await self._send_command("htpcmode0", self._normalize_state(state, output="text"))
Expand Down
78 changes: 78 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,36 @@ async def test_set_auto_switch_inputs(client: HDFuryAPI, endpoint: str, method:

await getattr(client, method)(value)

@pytest.mark.asyncio
@pytest.mark.parametrize(
("endpoint", "method", "value"),
[
("unmutecnt", "set_audio_unmute", "30"),
("unmutecnt", "set_audio_unmute", "60"),
],
)
async def test_set_audio_unmute(client: HDFuryAPI, endpoint: str, method: str, value: str):
"""Verify set_audio_unmute sends the correct command for each Audio Unmute state."""
with aioresponses() as mock:
mock.get(f"http://192.168.1.123/cmd?{endpoint}={value}", status=200)

await getattr(client, method)(value)

@pytest.mark.asyncio
@pytest.mark.parametrize(
("endpoint", "method", "value"),
[
("earcunmutecnt", "set_earc_unmute", "30"),
("earcunmutecnt", "set_earc_unmute", "60"),
],
)
async def test_set_earc_unmute(client: HDFuryAPI, endpoint: str, method: str, value: str):
"""Verify set_earc_unmute sends the correct command for each eARC Unmute state."""
with aioresponses() as mock:
mock.get(f"http://192.168.1.123/cmd?{endpoint}={value}", status=200)

await getattr(client, method)(value)

@pytest.mark.asyncio
@pytest.mark.parametrize(
("endpoint", "method", "value"),
Expand Down Expand Up @@ -287,6 +317,23 @@ async def test_set_mute_tx_audio(client: HDFuryAPI, endpoint: str, method: str,

await getattr(client, method)(value)

@pytest.mark.asyncio
@pytest.mark.parametrize(
("endpoint", "method", "value"),
[
("tx0plus5", "set_tx0_force_5v", "on"),
("tx1plus5", "set_tx1_force_5v", "on"),
("tx0plus5", "set_tx0_force_5v", "off"),
("tx1plus5", "set_tx1_force_5v", "off"),
],
)
async def test_set_tx_force_5v(client: HDFuryAPI, endpoint: str, method: str, value: str):
"""Verify set_tx_force_5v commands are sent correctly for each transmitter and state."""
with aioresponses() as mock:
mock.get(f"http://192.168.1.123/cmd?{endpoint}={value}", status=200)

await getattr(client, method)(value)

@pytest.mark.asyncio
@pytest.mark.parametrize(
("endpoint", "method", "value"),
Expand All @@ -302,6 +349,21 @@ async def test_set_oled(client: HDFuryAPI, endpoint: str, method: str, value: st

await getattr(client, method)(value)

@pytest.mark.asyncio
@pytest.mark.parametrize(
("endpoint", "method", "value"),
[
("oledfade", "set_oled_fade", "30"),
("oledfade", "set_oled_fade", "60"),
],
)
async def test_set_oled_fade(client: HDFuryAPI, endpoint: str, method: str, value: str):
"""Verify set_oled_fade sends the correct command for each OLED fade state."""
with aioresponses() as mock:
mock.get(f"http://192.168.1.123/cmd?{endpoint}={value}", status=200)

await getattr(client, method)(value)

@pytest.mark.asyncio
@pytest.mark.parametrize(
("endpoint", "method", "value"),
Expand Down Expand Up @@ -336,6 +398,7 @@ async def test_set_relay(client: HDFuryAPI, endpoint: str, method: str, value: s
@pytest.mark.parametrize(
("endpoint", "method", "value"),
[
("cec", "set_cec", "off"),
("cec0en", "set_cec_rx0", "1"),
("cec1en", "set_cec_rx1", "1"),
("cec2en", "set_cec_rx2", "0"),
Expand All @@ -349,6 +412,21 @@ async def test_set_cec_rx(client: HDFuryAPI, endpoint: str, method: str, value:

await getattr(client, method)(value)

@pytest.mark.asyncio
@pytest.mark.parametrize(
("endpoint", "method", "value"),
[
("reboottimer", "set_reboot_timer", "30"),
("reboottimer", "set_reboot_timer", "60"),
],
)
async def test_set_reboot_timer(client: HDFuryAPI, endpoint: str, method: str, value: str):
"""Verify set_reboot_timer sends the correct command for each Reboot Timer state."""
with aioresponses() as mock:
mock.get(f"http://192.168.1.123/cmd?{endpoint}={value}", status=200)

await getattr(client, method)(value)

# ---------------------------------------------------------------------------
# Debounce behavior
# ---------------------------------------------------------------------------
Expand Down