At the weekend I had the idea that my TV automatically turns on when I come into my living room, as did my Philips Hue lamps, for which I installed a motion detector. Coincidentally, I still had a Raspberry Pi Zero W in the drawer, which was actually planned as an AIS receiver, but did not have enough performance for this task. As a LIRC host, the performance is sufficient and for NodeJS there is both a wrapper for LIRC commands and an API to communicate with the Philips Hue Bridge. To make this project even more useful, i developed a simple app to control volume and multiroom settings with Vue.js

Hardware

First of all, a hardware extension is required to process infrared signals with the Raspberry Pi. The circuit is relatively simple, only a few components are required, which can be purchased at Amazon for little money. A detailed explanation from Austin Stanton for hackster.io of how the circuit is constructed can be found here.

I developed the first circuit on a protoboard to setup the software and record my IR remote control with LIRC.


Breadbord with LIRC Receiver and Transceiver diodes


The IR Receiver can be connected directly to the GPIO Pins of the Rasberry Pi, the Infrared LED needs to be connected with a NPN Transistor so the output current of the GPIO Pin is amplified.

Later, in production so to say, the IR Receiver is no longer needed. The breadboard, however, is unwieldy. For make this project more convenient, i soldered the components onto a small strip grid board and plugged it into the pin header of the Raspberry Pi. The components, except the IR LED, are soldered under the circuit board.

Production version of the circuit


Install the right Raspbian, LIRC and NodeJs

The current version of Raspberry Pi OS (previously called Raspbian) is based on Debian Buster. Unfortunately, some changes have been made in this and the previous version, Stretch, that lead to problems with LIRC and Raspberry Pi. There are a few solutions, but unfortunately more confusion about how to deal with this issue. I ended up installing the latest Raspbian Jessie. Since i only use the board as a LIRC, NodeJS host in a private network, i’m fine with that.

If this requirement is met, the tutorial from Austin Stanton can be followed to install LIRC and record the remote controls.

The disadvantage of an old Rasbian version is that there are no current NodeJs in the repository. However, this can easily be installed from the official node distributions. The latest version, which supports the ARM 6 processor of the Raspberry Pi Zero is v11.9.0 and contains the most important ECMAScript 7 features that you don’t want to do without.

Simple Application to control LIRC with Node

A simple POC app to control LIRC vith an Node App is build around lirc_node lirc_node is an npm module that acts as a very thin shim between LIRC and Node. lirc_node is wrapper the known LIRC commands which can be uses from the command line. This is sufficient for the tasks of this project.

1
2
3
4
5
const lirc_node = require('lirc_node');
lirc_node.init();
lirc_node.irsend.send_once("sony", "KEY_POWER", function () {
console.log("Sent TV power command!");
});

The above example sends the Power command to the TV. Another npm library node-hue-api is the best choosen for connecting with a Philips Hue Bridge. First, the App must be registered with the Bridge. node-hue-api gives a example script how this can be achieved.

Unfortunately there is no way to track state changes with this API, for example with events. The only option is to query the status of a Hue device at an interval. This is not the most beautiful solution, but it has turned out that the bridge can be polled every second without any problems. A complete Script for connecting the state of a HUE lamp with LIRC is a follows.

Import the modules needed and initialize lirc_nodes

1
2
3
const v3 = require('node-hue-api').v3;
const lirc_node = require('lirc_node');
lirc_node.init();

The following function reads the state of a specific hue lamp, which is controlled with a hue motion sensor and a hue switch.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const readState() = async () => {
return new Promise(resolve => {
v3.discovery.nupnpSearch()
.then(searchResults => {
const host = searchResults[0].ipaddress;
return v3.api.createLocal(host).connect(<<HUE_USER>>);
})
.then(api => {
return api.lights.getLightState(10);
})
.then(state => {
resolve(state.on);
})
})
}

sendCommand() is a function, which wraps lirc_node into a async function

1
2
3
4
5
6
7
const sendCommand = async (receiver, command) => {
return new Promise(resolve => {
lirc_node.irsend.send_once(receiver, command, function() {
resolve()
})
})
}

The waitEvent() function calls readState() every second. If the state has changed, sendCommand() is called to toggle the TV power key.

1
2
3
4
5
6
7
8
9
10
11
12
13
let state = false
const waitEvent = async () => {
setTimeout(async () => {
const before = state
state = await readState()

if (state !== before) {
await sendCommand('sony', 'KEY_POWER')
}

await waitevent()
}, 1000)
}

The following lines of code initialize the current state starts the process.

1
2
3
4
5
6
const main = async () => {
state = await readState()
await waitevent()
}

main()

Build a simple Vue.js App to monitor and control more functions

The above example works well for this simple task and can be developed in a couple of hours (far less if Debian did not change the lirc device management). However, a small app that allows you to control other functions of the system is nice to have.

The only functions I need are volume, mute and multiroom. Since I have connected a MacMini to my TV and have not watched any television programs for years, I have no need for further functions. To control these functions directly on the desktop is very convenient.

In contrast to my last project, I used Vue.js with Vuetify this time. Communication with the server takes place with VueSocketIO and the Vuex state management pattern + library. The server is an Express JS application with Socket.io for bidirectional communication and a route for delivering the front end.

Screenshot of the ManCave Remote Control app

Conclusion

I am planning to add a registration for a future version so that the application can also be used from the public network. A calibration function would be useful so that the volume can be adjusted more precisely, as well as a function to suspend the automatic switch-on by Philips Hue.

The early version of this project is published on GitHub.

This project also offers the opportunity to develop a Native Mobile APP for IOS with React Native. One thing I wanted to look at soon. Stay tuned.