diff --git a/pyatv/const.py b/pyatv/const.py index bd2c91323..3629d0706 100644 --- a/pyatv/const.py +++ b/pyatv/const.py @@ -450,6 +450,12 @@ class FeatureName(Enum): Click = 65 """Touch click command.""" + Guide = 66 + """Show EPG.""" + + ControlCenter = 68 + """Open the Control Center.""" + class TouchAction(Enum): """Touch action constants.""" diff --git a/pyatv/core/facade.py b/pyatv/core/facade.py index 7bafe33fc..f9193aafc 100644 --- a/pyatv/core/facade.py +++ b/pyatv/core/facade.py @@ -193,6 +193,16 @@ async def screensaver(self) -> None: """Activate screen saver..""" return await self.relay("screensaver")() + @shield.guard + async def guide(self) -> None: + """Show EPG.""" + return await self.relay("guide")() + + @shield.guard + async def control_center(self) -> None: + """Open the control center.""" + return await self.relay("control_center")() + class FacadeMetadata(Relayer, interface.Metadata): """Facade implementation for retrieving metadata from an Apple TV.""" diff --git a/pyatv/interface.py b/pyatv/interface.py index dae282b2e..eeaef8f14 100644 --- a/pyatv/interface.py +++ b/pyatv/interface.py @@ -454,6 +454,16 @@ async def screensaver(self) -> None: """Activate screen saver..""" raise exceptions.NotSupportedError() + @feature(66, "Guide", "Show EPG.") + async def guide(self) -> None: + """Show EPG.""" + raise exceptions.NotSupportedError() + + @feature(68, "ControlCenter", "Control Center.") + async def control_center(self) -> None: + """Open the control center.""" + raise exceptions.NotSupportedError() + # TODO: Should be made into a dataclass when support for 3.6 is dropped class Playing(ABC): diff --git a/pyatv/protocols/companion/__init__.py b/pyatv/protocols/companion/__init__.py index a7e3f6a50..0fd2bcd9b 100644 --- a/pyatv/protocols/companion/__init__.py +++ b/pyatv/protocols/companion/__init__.py @@ -139,6 +139,8 @@ class MediaControlFlags(IntFlag): FeatureName.ChannelUp, FeatureName.ChannelDown, FeatureName.Screensaver, + FeatureName.Guide, + FeatureName.ControlCenter, # Keyboard interface FeatureName.TextFocusState, FeatureName.TextGet, @@ -380,6 +382,14 @@ async def screensaver(self) -> None: """Activate screen saver.""" await self._press_button(HidCommand.Screensaver) + async def guide(self) -> None: + """Show EPG.""" + await self._press_button(HidCommand.Guide) + + async def control_center(self) -> None: + """Open the control center.""" + await self._press_button(HidCommand.PageDown) + async def _press_button( self, command: HidCommand, diff --git a/tests/fake_device/companion.py b/tests/fake_device/companion.py index fe6fda057..fe11e2f96 100644 --- a/tests/fake_device/companion.py +++ b/tests/fake_device/companion.py @@ -48,6 +48,8 @@ HidCommand.ChannelIncrement: "channel_up", HidCommand.ChannelDecrement: "channel_down", HidCommand.Screensaver: "screensaver", + HidCommand.Guide: "guide", + HidCommand.PageDown: "control_center", } MEDIA_CONTROL_MAP = { diff --git a/tests/protocols/companion/test_companion_functional.py b/tests/protocols/companion/test_companion_functional.py index d68fc6804..561db962c 100644 --- a/tests/protocols/companion/test_companion_functional.py +++ b/tests/protocols/companion/test_companion_functional.py @@ -204,6 +204,8 @@ async def test_session_start_and_stop(companion_client, companion_state): "play_pause", "channel_up", "channel_down", + "guide", + "control_center", # Media Control "play", "pause",