Building a Roku Remote Part 1

I purchased a Roku 3 in either 2013 or 2014. Originally it didn't have much use for me because my college's WiFi only allowed for auth via Enterprise methods and Rokus do not support this (along with most consume technology). Fast forward a few years, and the same Roku feels like an indispensable part of our lives on some days (generally when the kids are super tired/cranky).

I don't know if it is just my children, but they love remotes. They loved the Roku remote so much that ti fell apart and became unrepairable (the board literally snapped in half). So we have been making due with the Roku apps on our phone to control our Roku 3. It works, but it's annoying and it's hard when guests/babysitters are trying to watch television because then they either need one of our phones or to install the app. I looked into buying a new remote, but it's literally cheaper to just buy a new Roku and that seems like a waste of both money and resources.

I knew from prior research that the Roku remote worked via WiFi. And after I did a little more digging I discovered that someone had created a Python module to control the Roku. If I could keep the cost of building a new remote under that of buying a new Roku/remote than this would be a worthwhile project for me, and potentially even others. So I pip install roku'd the module and began mocking up the programming to get a Roku remote running. My four steps to success for this project are:

  1. Software mock-up
  2. Raspberry Pi mock-up
  3. Convert to an ESP8266
  4. ~Profit~ share

So with a plan and the module installed I got to work...

python-roku has a discovery function, allowing you to find a Roku on your network and connecting to it without having to know the IP of the Roku. I fired up the REPL and:

Python 3.7.2 (default, Jan 10 2019, 23:51:51)
[GCC 8.2.1 20181127] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from roku import Roku
>>> Roku.discover()

No joy :(

I knew from experience that the Roku apps sometimes have trouble discovering the Roku. So, undeterred I tried again:

>>> Roku.discover()
>>> Roku.discover()

Still nothing. No problem! Looking at the docs, discover() can be called with a timeout= to specify how long to look for a Roku before giving up. So I tried yet again:

>>> Roku.discover(timeout=60)

Now we're cooking! discover() returns a list of Roku objects, so once you find a device there is no further work to get the Roku running, which is super handy. I gave it a shot:

>>> roku = Roku.discover()
>>> roku = roku[0]
>>> roku.home()

And sure enough, my Roku went from 'Animal Mechanicals' to the Home screen! It was pretty responsive too, so this could really work as a remote. The module has a number of features beyond what I can/will use on my remote, for example you can `roku.literal('Pokemon') and the Roku will search for Pokemon and display the results. For a remote the bare essentials would be:

We could probably even get away without the Play/Pause since on most apps I use Select will do the same thing. Still, it would be nice to have that there just in case, as well as:

This would bring this DIY remote up to parity with my destroyed one.

Honestly, I had expected there to be a bit more programming than this, but this module is so well done there isn't much left for me to do other than mock-up some hardware on a Pi as a proof of concept (I'd use something else, but I have a RPi3 sitting in my office unused).