Skip to content

Commit

Permalink
Mark UniFi power cycle button as unavailable if PoE is not enabled on…
Browse files Browse the repository at this point in the history
… port (#122035)
  • Loading branch information
Kane610 authored and frenck committed Jul 19, 2024
1 parent 4b93fc6 commit d9e44ba
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
15 changes: 13 additions & 2 deletions homeassistant/components/unifi/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
import secrets
from typing import Any
from typing import TYPE_CHECKING, Any

import aiounifi
from aiounifi.interfaces.api_handlers import ItemEvent
Expand Down Expand Up @@ -44,6 +44,17 @@
async_wlan_device_info_fn,
)

if TYPE_CHECKING:
from .hub import UnifiHub


@callback
def async_port_power_cycle_available_fn(hub: UnifiHub, obj_id: str) -> bool:
"""Check if port allows power cycle action."""
if not async_device_available_fn(hub, obj_id):
return False
return bool(hub.api.ports[obj_id].poe_enable)


async def async_restart_device_control_fn(
api: aiounifi.Controller, obj_id: str
Expand Down Expand Up @@ -96,7 +107,7 @@ class UnifiButtonEntityDescription(
entity_category=EntityCategory.CONFIG,
device_class=ButtonDeviceClass.RESTART,
api_handler_fn=lambda api: api.ports,
available_fn=async_device_available_fn,
available_fn=async_port_power_cycle_available_fn,
control_fn=async_power_cycle_port_control_fn,
device_info_fn=async_device_device_info_fn,
name_fn=lambda port: f"{port.name} Power Cycle",
Expand Down
32 changes: 32 additions & 0 deletions tests/components/unifi/test_button.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
"""UniFi Network button platform tests."""

from copy import deepcopy
from datetime import timedelta
from typing import Any
from unittest.mock import patch

from aiounifi.models.message import MessageKey
import pytest

from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, ButtonDeviceClass
Expand Down Expand Up @@ -319,3 +321,33 @@ async def test_wlan_button_entities(
request_data,
call,
)


@pytest.mark.parametrize("device_payload", [DEVICE_POWER_CYCLE_POE])
@pytest.mark.usefixtures("config_entry_setup")
async def test_power_cycle_availability(
hass: HomeAssistant,
mock_websocket_message,
device_payload: dict[str, Any],
) -> None:
"""Verify that disabling PoE marks entity as unavailable."""
entity_id = "button.switch_port_1_power_cycle"

assert hass.states.get(entity_id).state != STATE_UNAVAILABLE

# PoE disabled

device_1 = deepcopy(device_payload[0])
device_1["port_table"][0]["poe_enable"] = False
mock_websocket_message(message=MessageKey.DEVICE, data=device_1)
await hass.async_block_till_done()

assert hass.states.get(entity_id).state == STATE_UNAVAILABLE

# PoE enabled
device_1 = deepcopy(device_payload[0])
device_1["port_table"][0]["poe_enable"] = True
mock_websocket_message(message=MessageKey.DEVICE, data=device_1)
await hass.async_block_till_done()

assert hass.states.get(entity_id).state != STATE_UNAVAILABLE

0 comments on commit d9e44ba

Please sign in to comment.