diff --git a/homeassistant/components/portainer/button.py b/homeassistant/components/portainer/button.py index 72a193de6bf9..d3ab57f56103 100644 --- a/homeassistant/components/portainer/button.py +++ b/homeassistant/components/portainer/button.py @@ -6,7 +6,7 @@ from dataclasses import dataclass from datetime import timedelta from typing import Any, override -from pyportainer import Portainer +from pyportainer import DockerContainerState, Portainer from pyportainer.exceptions import ( PortainerAuthenticationError, PortainerConnectionError, @@ -54,6 +54,7 @@ class PortainerContainerButtonDescription(ButtonEntityDescription): [Portainer, int, str], Coroutine[Any, Any, DockerContainer | None], ] + available_fn: Callable[[PortainerContainerData], bool] ENDPOINT_BUTTONS: tuple[PortainerEndpointButtonDescription, ...] = ( @@ -89,6 +90,9 @@ CONTAINER_BUTTONS: tuple[PortainerContainerButtonDescription, ...] = ( endpoint_id, container_id ) ), + available_fn=lambda container: ( + container.container.state != DockerContainerState.PAUSED + ), ), PortainerContainerButtonDescription( key="pause", @@ -99,6 +103,9 @@ CONTAINER_BUTTONS: tuple[PortainerContainerButtonDescription, ...] = ( endpoint_id, container_id ) ), + available_fn=lambda container: ( + container.container.state == DockerContainerState.RUNNING + ), ), PortainerContainerButtonDescription( key="resume", @@ -109,6 +116,9 @@ CONTAINER_BUTTONS: tuple[PortainerContainerButtonDescription, ...] = ( endpoint_id, container_id ) ), + available_fn=lambda container: ( + container.container.state == DockerContainerState.PAUSED + ), ), PortainerContainerButtonDescription( key="recreate", @@ -122,6 +132,10 @@ CONTAINER_BUTTONS: tuple[PortainerContainerButtonDescription, ...] = ( pull_image=True, ) ), + available_fn=lambda container: ( + container.container.state + not in (DockerContainerState.REMOVING, DockerContainerState.DEAD) + ), ), PortainerContainerButtonDescription( key="kill", @@ -132,6 +146,10 @@ CONTAINER_BUTTONS: tuple[PortainerContainerButtonDescription, ...] = ( endpoint_id, container_id ) ), + available_fn=lambda container: ( + container.container.state + in (DockerContainerState.RUNNING, DockerContainerState.PAUSED) + ), ), ) @@ -244,6 +262,14 @@ class PortainerContainerButton(PortainerContainerEntity, PortainerBaseButton): entity_description: PortainerContainerButtonDescription + @property + @override + def available(self) -> bool: + """Return if the button is available.""" + return super().available and self.entity_description.available_fn( + self.container_data + ) + @override async def _async_press_call(self) -> None: """Call the container button press action.""" diff --git a/tests/components/portainer/snapshots/test_button.ambr b/tests/components/portainer/snapshots/test_button.ambr index f701ef421163..6fb9e0e40b23 100644 --- a/tests/components/portainer/snapshots/test_button.ambr +++ b/tests/components/portainer/snapshots/test_button.ambr @@ -247,7 +247,7 @@ 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'unknown', + 'state': 'unavailable', }) # --- # name: test_all_button_entities_snapshot[button.focused_einstein_kill_container-entry] @@ -498,7 +498,7 @@ 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'unknown', + 'state': 'unavailable', }) # --- # name: test_all_button_entities_snapshot[button.funny_chatelet_kill_container-entry] @@ -749,7 +749,7 @@ 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'unknown', + 'state': 'unavailable', }) # --- # name: test_all_button_entities_snapshot[button.my_environment_prune_unused_images-entry] @@ -1101,7 +1101,7 @@ 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'unknown', + 'state': 'unavailable', }) # --- # name: test_all_button_entities_snapshot[button.serene_banach_kill_container-entry] @@ -1352,7 +1352,7 @@ 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'unknown', + 'state': 'unavailable', }) # --- # name: test_all_button_entities_snapshot[button.stoic_turing_kill_container-entry] @@ -1603,6 +1603,6 @@ 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'unknown', + 'state': 'unavailable', }) # ---