I’m always in the lookout for new smart remotes, so when I saw this Turn Touch wooden thing, I thought it might go better with my living room table:
Than the old remote I use to control the stereo (and the lights):
Eh? Eh? Slightly better, huh?
That Targus thing there has worked reliably for me for almost a decade now. I use the pointer thing to control the volume and the other buttons to skip and stuff, so I wondered whether this Turn Touch thing would be as flexible.
The Targus thing appears as a USB HID device in Linux, so it’s very easy to interface with. And it has a nice range: It doesn’t drop that many events. I’m almost always disappointed by the range and reliability of wireless things, but we’ll see…
But first of all, I wondered how the Turn Touch worked. There was no manual included, so I wondered how this thing is even charged and how you open it, because there are absolutely no screws.
But it’s all held together by magnets! How brilliant! Prying it apart was trivial, but it still feels nice and solid when it’s all put back together.
And it’s charged by a normal button battery that’s supposed to last about a year. That’s nicer than having to recharge it, I think.
Anyway! How do you interact with this thing?
Python to the rescue!
# pip3 install TurnTouch # pip3 install typing
and then a script like this:
from turntouch import TurnTouch, DefaultActionHandler class MyHandler(DefaultActionHandler): def action_north(self): print("Up button pressed.") def action_east_double_tap(self): print("Right button double-tapped.") def action_south_hold(self): print("Down button held.") tt = TurnTouch('e5:b6:51:8e:f4:50') tt.handler = MyHandler() tt.listen_forever()
where that address can be detected by saying
# bluetoothctl scan on
and waiting for a line mentioning “Turn Touch” to show up. Apparently you don’t have to pair things explicitly and stuff… These low-powered bluetooth things are a mystery to me…
However, as that this shows, the responsiveness is, what’s the technical term… Oh, yeah: “EEEK! THAT”S HORRIBLE!”
A second after you’ve hit the button, you get an event on the computer?
So, in the /usr/local/lib/python3.4/dist-packages/turntouch/turntouch.py file, there’s a line saying
MAX_DELAY = 0.75
that sounds suspiciously like the one-second delay I’m seeing, and reading through the code, I understand why it’s there: Each key is supposed to be able to give you three actions: Single tap, double tap and hold. You see this in mobile interfaces, too: If you want to support double tap (and mobile UX people thought that was going to be a thing), you have to wait a while to see whether the first tap was all there’s going to be, or whether another tap is to follow.
But I think that’s pretty horrible, and I can live with either single tap and very-quick double taps; I don’t need “hold”. Especially if the holds are going to fuck the UX up this much.
I changed MAX_DELAY to 0.1, and:
Now, that’s almost acceptable. It does mean that I get a tap event before I get a hold event, but I think that’s OK for my use case here… I think…
Hm… no, it’s janky and doesn’t really work properly.
And… I can’t really understand why it’s programmed this way at all. As far as I can tell, the device itself sends over events like “West” and “Off” and “West Double Tap”…
Oh, right! When you hold a button, you get “South”, “South hold” and then “Off”… But… when you tap a button, you get “South” and then “Off”. And on double taps you get “South” and then “South double tap”.
Uhm! No! OK, now I’ve added proper debugging, and I understand why the library is doing what it’s doing. If you double tap, these are the events you get:
North Off North North double tap
So you can’t fire the “North” action on the “Off”, but have to wait and see whether you get a “North double tap”. And the built-in delay in the device is 0.75 (i.e., if you hit the button faster than that, you get a double tap event), so single taps can’t be executed faster than that if you want to have double taps.
The library almost has support for this: There’s a “debounce” parameter that’ll call the action immediately, but that’s also wrong: Then you can’t have a separate “tap” and “hold” action, either.
I think… I can live without double taps. A “hold” gives me these events:
East East hold Off
So I can have immediate for single taps (i.e., on the “Off”), and also support holds without introducing delays. So I’m going to fork and hack the TurnTouch library.
Man! Do I have to learn Python?!
Well, that was trivial enough. The TurnTouch library is written in a clean and nice fashion, so ripping out all the logic was easy.
My version is on Microsoft Github.
So after that slight detour… ahem… Is the Turn Touch any good?
I’ve only been using it for a very short while, but the signal range seems pretty good: From the couch to the stereo (with a bluetooth dongle on the back of the computer; about three meters) it doesn’t lose any events. If I go to the next room, I’m able to send some events through the wall, but then it loses the connection.
But that’s a lot better than I expected.
And! It’s an open platform with good documentation, which is very nice indeed. And, with libraries like the one I forked here, you have pretty good access to the events and can construct your own workflows based on what’s important to you.
So, while I have no idea whether it works well over the long haul, I’m giving it all my thumbs up.