stupid-remote: a HDMI-cec node.js Web App


A web app to control devices over HDMI-cec, turning tvs on and off, switching inputs adjusting volume. New project, customization requires editing simple HTML and JavaScript.

The Why

I have been using OSMC on a Raspberry Pi 2 for a few months now and have been really happy with it. (OSMC is a Raspbian based distribution that boots into Kodi.)

However, switching my TV input from TiVo to PlayStation to OSMC was a pain in the ass.

Over the years I have tried using different smart remotes (even bought a Logitech Harmony), but they all suffer from line of sight IR, lag and complicated setup.

So after working out the `cec-client` commands (see Using cec-client on a Raspberry Pi) I put together a web app that was light enough to host on the Raspberry Pi that runs OSMC.

It gets rid of the line of sight IR and lag issues, although it is not necessarily any simpler. It is a different kind of complicated.

Two out of three ain’t bad.

Step 1: cec-client commands

First step is to determine the `cec-client` commands to run by listing all the devices, creating TV on/off and testing the input selection commands.

As mentioned, I have covered this in a post Using cec-client on a Raspberry Pi, start there if you have never used `cec-client`.

The commands that stupid-remote come with are the ones that work for me: Tivo, Kodi, PS 4, Tv On and Tv Off. The commands you will use will depend a bit on your setup.

Step 2: Install Dependencies

The following instructions will install `node.js` and `cec-client` on Raspbian (or Ubuntu), to allow you to run `stupid-remote` manually. If you like it and want to run it as a service (recommended, starts and stops with the device), see README Install Raspbian and Ubuntu.

Update, install node.js and npm:

sudo apt-get update
sudo apt-get install nodejs npm

Install cec-client, but first check to see if cec-client is already installed:

cec-client -h

If you see `-bash: cec-client: command not found`, you will need to install the app:

sudo apt-get install cec-client

Alternately, follow the instructions to install from source

Step 3: Customize stupid-remote

At the moment, customizing stupid-remote requires you to edit HTML and JavaScript. It is not hard and there isn’t a lot of if it. Future versions of stupid-remote might provide better configuration options, but right now it is DIY.

Download the latest release of stupid-remote:

Start by editing the JavaScript, `stupid-remote/routes/cec.js`. Copy or edit the existing `router.get()` calls to match your cec-client call, updating the @swagger in the comments as well. For example, the TV on routing handler looks like:

 * handle GET /tvOn request
 *  echo "tx 10:04" | cec-client /dev/ttyACM0 -s -d 4
 * @swagger
 * /cec/tvOn:
 *   get:
 *     tags:
 *       - TV Control
 *     description: Turns on the TV
 *     produces:
 *       - application/json
 *     parameters:
 *     responses:
 *       200:
 *         description: Successfully turned tv on
router.get('/tvOn', function (req, res, next) {
  debug('called tvOn');
  www.cecUsb.sendCommand( 0x10, 0x04 );
  res.writeHead(200, {"Content-Type": "application/json"});
  var html = '{"status":"ok"}';

Next, edit the default html, `stupid-remote/public/index.html`. In the page are two places to edit, the buttons (between ‘BEGIN Buttons’ and ‘END Buttons’) and corresponding button bindings (between ‘BEGIN Button Bindings’ and ‘END Button Bindings’). These edits should match the buttons and button bindings to the changes to `cec.js`. For example, the TV on button and button bindings look like:

TV OnTurn TV on
$("#tvOnButton").click( function( event ) {
  $.get( "./cec/tvOn", function( data ) {
} );

Start stupid-remote

Finally, to start the app, change to the root of the `stupid-remote` directory and run `node ./bin/www`. The `DEBUG=*` will enable logging with can help resolve any issues.

cd stupid-remote
DEBUG=* node ./bin/www

Browse to http://HOSTNAME:8080/ and there is a Swagger UI at http://HOSTNAME:8080/api-docs/

Conclusion and Commentary

This could have been created in any language, but node.js seemed light weight, had the cec-client bindings and Swagger UI (hey why not?).

As for the name, it is a protest of the term ‘smart remote’. They should be called marginally-above-average-remote, but that doesn’t sell well I guess.

The UI is geared towards Mobile Safari on iOS, but if there are other header or meta data attributes required to support your favourite browser, please send me a pull request. Similarly, I realize Bootstrap and the minimal UI treatment isn’t for everyone, but it is functional and gives good tap targets on mobile.

Comments are closed.