A web remote control

The hardware

Where the idea comes from

From day to day my TV remote control begun not to work properly. So I decided to create my own remote control with a Raspberry Pi Zero.

The requirements are:

  • accessible by mobile phone
  • no need to install nothing on mobile
  • possibility to control several devices

It follows that should be a web-service accessible with a standard web browser.

I decided to split the original article in two because too big: one is more centered on the hardware/software of the web remote control (this one) and the other one is more centered on the develop of the engineering of the developing process.

Purposes

With the boom of Internet of Thing (IoT) and home automation, it easy to find a remote control usable with smartphone and probably cheaper than mine. So, why did I want to create this remote control?

  • learning Flask: Flask is a framework to create webservices. I think that creating light API when you are working in a distributed environment is useful;
  • learning Python: Python is one of the most versatile coding language;
  • hands on Continuous Integration/Continuous Delivery: I wanted to apply the concepts of CI/CD that I have recently studied on a practical example.

Which hardware?

I had to struggle with the hardware. Initially the Raspberry Pi Zero W + IR shield seemed to be the perfect solution. But it turned out it had problem with the WiFi, I had frequent disruptions and some packets (especially the big ones) were frequently lost.

So I decided to buy a Orange Pi Zero that has an external antenna and an Ethernet socket. Also with a bigger antenna I had a problem with the WiFi, I think because of a noisy neighborhood. Luckily, I had the opportunity to bring an Ethernet cable. But it turned out that it is impossible to use IR shield without implementing a custom program or kernel module with the Orange Pi.

In the end, I decide to buy an external Ethernet adapter for the Raspberry Pi Zero and continue with it. The IR shield is compatible with the gpio-ir-tx/gpio-ir overlays, LIRC and the network connection is perfect.

Simple diagram of the wiring

In my Ansible playbook you can see the step Insert boot configuration that configures the underline system. It simply sets the dtoverlay specifying the the GPIO-PINs according with your ir shield pinout. The dtoverlay is in carge of setting the pull-downs and ports properly.
Moreover, the overlays automatically enables the gpio_ir_recv and gpio_ir_tx kernel modules. So, it is not necessary to touch the /etc/modules file.
Finally, the kernel modules create the /dev/lirc0 and /dev/lirc1 devices. You can find further explanations in /boot/overlays/README of your Raspberry.

Application composition

Subsystem

The reference software for handling Infrared signals is the Linux Infrared Remote Control (LIRC). LIRC is a daemon that allows interfacing with the Infrared emitter/receiver device (i.e. /dev/lirc0 or /dev/lirc1). At the beginning you can use the tool irrecord to create a configuration file that describes the communication protocol of a device (e.g. television).

irrecord -d /dev/lirc1 # In my case /dev/lirc1 is the receiver

Inside the created file there is a list of buttons that you recorded. A piece of file:

begin remote                                                                                                                                                                                                                                                                                                                                      
name television
bits 13
flags RC5|CONST_LENGTH
eps 30
aeps 100
one 869 902
zero 869 902
plead 872
gap 113449
toggle_bit_mask 0x800
frequency 38000
begin codes
KEY_POWER 0x104C
KEY_1 0x1041
KEY_2 0x1042
KEY_3 0x1043

After you have got the configuration file, you can use irsend to “press a button”.

irsend SEND_ONCE television KEY_POWER

From my Ansible playbook you can see that I just had to set the driver as default (Set driver), use the /dev/lirc0 device (Set device) and include the configuration files (Point directory of configuration).

API

Above LIRC I developed the web API to interact with it. The API uses the configuration files to know which devices can be controlled an which keys are available to be pressed. The main objective is to allow the changes of the LIRC configuration without touch the webservice. So the pages/API are dynamically created starting from the LIRC configuration files.

The devices and the keys are exposed in HTML pages.

The index of the available devices

Clicking on the device televisore there is the list of the keys.

The page that displays the list of the keys

When the key is pressed, a POST HTTP call is sent to the API that is exposed by the same application. Then, the POST call is converted in the execution of irsend.

To develop this simple API I used Flask in Python. The choice of Flask depended on its lightweight and easy to use.

The 3 main calls of the webservice

You can have a look at the code if you want a better understanding how I used Flask.

Conclusion

In this article I described what is my web remote control and which technical precautions were taken in order to have a functional product. As said before, a main purpose of this project is to improve the developing and delivering cycle of a webservice. These will be the subjects of another article (coming soon).

--

--

Fabrizio Waldner

Site Reliability Engineer at Google. This is my personal blog, thoughts and opinions belong solely to me and not to my employer.