Design your own PC remote control

Couch Potato

© Lead Image © damedeeso,

© Lead Image © damedeeso,

Article from Issue 175/2015

You don't get a remote control with your PC or laptop like the one that came with your television. We'll show you how to create your own remote with an Android tablet or smartphone.

Wouldn't it be great to have a remote control for your PC that let you start and pause YouTube videos, as well as adjust the volume and brightness without leaving your couch? To implement this project, you need a server program on your Linux system that listens on a particular port, accepts instructions, and runs system commands. The device that acts as the remote control needs to run a program that can transmit requests to the Linux system over the network; it also offers a neat interface.

Using Netcat [1], you can implement the server function via the shell, and you also have the option of entering any system commands you need. Before you proceed to the implementation, check whether the following command-line programs are installed on your computer:

  • Xgamma, a program for the controlling your monitor's gamma value,
  • Xdotool, which transfers keyboard shortcuts to the system, and
  • ImageMagick [2], which grabs screenshots of the whole screen, selected areas, or a single window (among other things).

You can install these programs in one fell swoop, if you like, using the package manager. On Debian and its derivatives, become root and run the

apt-get install imagemagick xgamma xdotool

command at the command line.

The Server

After installing these programs, you can implement the server on the Linux system. This is a simple Bash script shown in Listing 1; you can download this from our anonymous FTP server if you prefer [3].

Listing 1

Server Script


In the script, line 2 determines where the script stores screenshots triggered via the remote, and line 3 ensures that this directory is created if it does not exist. Lines 5-43 are responsible for the actual server functionality. A while statement keeps the program running through the loop.

Line 7 shows how to use echo, Netcat, and sed to tell the program to listen on port 2001 and respond to data sent by the client with the word "something." The stream editor sed processes the client request by simply filtering out the last line with the instructions and storing them in the content variable.

If the Linux system has a firewall, you need to open port 2001 explicitly to enable communication with the client. If your router rejects traffic between WiFi-enabled devices for safety reasons (e.g., devices by 1&1 Internet), you must disable this option in the configuration interface of the router; after all, you want to use a WiFi-enabled device such as a tablet or smartphone as the remote control.

In lines 8-42, you will see the main construct for controlling YouTube in the form of an if/elif statement that evaluates the contents of the content variable and executes each instruction branch when it finds a match. Lines 8-17 are used to adjust the volume. To this end, the script determines the current value of the master channel in lines 9 and 14 using the amixer command. Lines 10 and 15 then set the new value; the statement in the following line in each case ensures that the value stays between 0 and 100 percent. A new call to amixer then sets the new volume.

Lines 18-29 change the gamma value on the system; the commands in lines 19 and 25 determine this only once by running the xgamma command. A subsequent grep filters out the three numerical values for red, green, and blue. Clever use of parentheses makes the gammas variable an array that stores the individual values in its fields. The individual array fields in lines 20-22, or the individual values in lines 26-28 are then stored in their own variables so that xgamma can set the three values correctly in the next line (23 or 29).

The screenshot routine in lines 30 and 31 uses the import command from the ImageMagick package to grab the whole screen and stores this in the folder specified in line 2. It relies on the date command to generate a filename; in other words, the screenshot is named after its creation date.

Lines 32-39 use the xdotool command-line tool, which lets keystrokes pass to other programs. YouTube can be controlled by keyboard shortcuts, so the script passes the keyboard shortcuts for individual actions through to the system. The Spacebar pauses playback, the Enter key starts movies, and the Left and Right arrow keys fast forward and rewind.

The last elif block starting in line 40 takes care of the screen resolution. You need to call xrandr with no parameters first to check which resolutions the screen supports. Then, enter your desired variations in line 41.

The Client

Now it's time to implement the remote control. You can develop this on your Linux system and copy it to the device that will serve as the remote control when you're done. The remote control is created as a simple HTML file with a little CSS and JavaScript magic, as shown in Listing 2; you can also download this from our FTP server [3].

Listing 2

Control File


I'll look at the visual component of the remote controller first; this is implemented as an HTML table. An example is shown in lines 35-63. This table is responsible for arranging the buttons on the remote control. To let the layout adapt automatically to each device, you need to define a table with 100 percent height and width (line 35).

This setup only works if you also set the body and the actual HTML document to 100 percent height (line 8). You also need to set the margin of the HTML body to 0 as in line 12. The correct percentages must also occur at the correct places in the table cells themselves so that the percentages in the cells in vertical and horizontal direction (almost) add up to 100 percent. The resulting layout adapts to full width and height in the browser for each device (Figure 1), unless you choose a smaller representation deliberately.

Figure 1: No matter how you hold your device, the remote control always takes up the entire display area of the browser.

The individual cells of the tables then contain the definitions for the buttons, in line with the following example:

<input type="button" value="Quieter" class="bst" onclick='set("quieter")'>

You can see the button from line 41 here; it additionally contains the class tag and the JavaScript statement onclick. The tag tells the browser to follow the CSS instructions in lines 7-24 on displaying. You need to enter the instructions there, which mainly affect the appearance of the remote control. If you want to delve deeper into the subject of HTML and CSS, the Codecademy website [4] is a good place to start.

Inside the onclick statement is the JavaScript function that the browser performs when you press the button. The remote control buttons use a simple function set("<action>") throughout. The associated JavaScript block can be found in lines 25-31. In line 26, it generates an object of the XMLHttpRequest type, which can send HTML requests to a web server.

For this project, I worked with Firefox as well as with the default browser on Android. Other browser for tablets and smartphones are unlikely to have any trouble with this brief JavaScript function if they support both JavaScript in general and the XMLHttpRequest object in particular.

Line 28 defines the HTML request in more detail. You need to enter the IP address of the Linux system to contact, and the port on which the server program is listening. If you have not modified the script in Listing 1, this is port 2001. Line 29 finally sends the request; on the Linux system, the server script evaluates it and runs a matching system command.


This example does not have to be end of development: Both the server on the Linux system and the remote client can be expanded easily. Also, you could easily spice up the look of your remote if you delve deeper into the subject of CSS or HTML.

Also on the server, you have the option of adding more features by creating more elif blocks with corresponding query parameters and inserting the appropriate system commands. However, you always need to extend the remote control to match. It might be a good idea, for example, to add a button to shut down the system; then you don't even have to get up off the couch after watching a movie.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Perl: AJAX

    AJAX technology adds dynamic elements to enhance sluggish websites. All it takes is a server-side Perl program and some client-side JavaScript code.

  • Perl: X10 Module

    My low-budget router has just crashed, and there is no way to reset the beast remotely via a network. Never fear – an X10 module, controlled by a web GUI with an Ajax interface, can actuate the mains switch.

  • Like Qlockwork

    QML makes writing desktop applications a breeze, and you can later compile them into standalone programs that work more or less anywhere.

  • Linux-Controlled Model Train

    Controlling a miniature train empire with concurrent Linux processes.

  • Google Maps

    Google Maps can pinpoint any location on the globe and more. Here’s how to embed the service into any web application.

comments powered by Disqus

Direct Download

Read full article as PDF:

Price $2.95