Input actions is not implemented in Companion
Describe the bug
It's not possible to use any other actions except for SingleTap in the buttons used by Companion. Should be easy enough to fix as support for press down/up action is already implemented, so it's just the matter of using that.
Error log
ERROR [pyatv.scripts.atvremote]: Command 'left' is not supported by device
Traceback (most recent call last):
File "/home/postlund/pyatv_dev/pyatv/pyatv/scripts/atvremote.py", line 699, in _exec_command
value = await tmp(*args)
File "/home/postlund/pyatv_dev/pyatv/pyatv/core/facade.py", line 55, in left
return await self.relay("left")(action=action)
File "/home/postlund/pyatv_dev/pyatv/pyatv/protocols/companion/__init__.py", line 266, in left
await self._press_button(HidCommand.Left, action)
File "/home/postlund/pyatv_dev/pyatv/pyatv/protocols/companion/__init__.py", line 300, in _press_button
raise NotImplementedError(f"{action} not supported for {command} (yet)")
NotImplementedError: InputAction.Hold not supported for HidCommand.Left (yet)
How to reproduce the bug?
$ atvremote --debug -s 10.0.10.81 --companion-credentials `cat creds` --scan-protocols companion,airplay left=2
What is expected behavior?
Should trigger "hold left" button.
Operating System
Any
Python
3.8
pyatv
master
Device
Apple TV 4K
Additional context
Minor issue since no one really use only the Companion protocol. But I want it fixed for completeness. Maybe it will be more important another day.
@postlund Hi there, I've implemented this locally for the Hold action by sending a button down, waiting 2s and then button up.
I tried to fork and submit a PR on this, but I'm having a terrible time trying to set up the linter and testing utilities on Windows. Is there any chance of getting this, or something similar, implemented without going through the formal PR process? It removes a major blocker for an automation project I'm currently working on. This code is the only change made to enable Hold action support for companion.
protocols/companion/init.py line 388:
async def _press_button(
self, command: HidCommand, action: InputAction = InputAction.SingleTap
) -> None:
if action == InputAction.SingleTap:
await self.api.hid_command(True, command)
await self.api.hid_command(False, command)
elif action == InputAction.Hold:
await self.api.hid_command(True, command)
await asyncio.sleep(2)
await self.api.hid_command(False, command)
elif action == InputAction.DoubleTap:
raise NotImplementedError(f"{action} not supported for {command} (yet)")
@dmrgn1991 You can just open a PR and I'll let it run. You will get results from linters directly in the PR so you can fix any issues. A tip is to use gitpod or code spaces here on github, then you get a Linux environment that should just work. I would also like to at tests for this (there are similar ones for other protocols for inspiration).
Also, is two seconds needed? I think iOS generally use about one second. Is one second enough or is it causing problems?
@postlund Thanks, that's helpful. I'll take another run at this over the weekend and try using those tools.
Two seconds was somewhat arbitrary, but was in part because the app I am testing against didn't seem to respond to 1s. I can look further into this on my end and see what is the lowest we can get away with, or if we can shorten it to make 1s work.
I suppose I could parameterize the delay with a default of 1s?
Anyway, thanks again for your time and I'll see what I can do.
@postlund I don't know if I missed a way to link to this ticket in my PR or something, just a reminder that this ticket is here.
@dmrgn1991 Thanks for the reminder!
Fixed by #2516