Puck.js + Television… What could go wrong?

It was a few weeks ago when I first discovered and visited DoES, and I quickly realised that I’ve got to learn a whole lot more about telemetry for the IoT project I’m working on. I’ve been dabbling with LoRaWAN, WiFi and, most recently, BLE (Bluetooth Low Energy).

In particular, I’m really interested in Beacons – what many refer to as “The Physical Web“. Beacons advertise small packets of information to their local vicinity, and anyone with a mobile (or other suitable device) wandering by will get a notification so they can interact with the beacon in some way…

There’s two de facto beacon standards: Apple iBeacon and Google Eddystone. I went hunting for a beacon that could do both and found two – Puck.js and RuuviTag, both of which are open source.  The Ruuvi isn’t widely available yet, so I’m starting with the Puck. It’s a tiny beacon complete with sensors, and it’s programmed via the web browser using simple JavaScript (primarily ES5). It arrived today; I immediately set about the IoT-equivalent of “Hello World” – in other words flashing a LED!

A puck.js beacon with some Javascript code to flash one of the on-board LEDs.

It was really easy – just launch the IDE in a “Web Bluetooth API”-compatible browser, click the connect button and choose which beacon to update. It’s the same workflow as the Arduino IDE, but without the wires – it’s all done over Bluetooth. In less than 30 seconds, I’d created yet another IoT blinkenlight.

So, what can the Puck do? It’s got a bunch of onboard sensors and LEDs, all of which come with associated Javascript APIs that make interacting with them trivial. And, obviously, it can do the beacon stuff too. So, naturally, I set about a small project with the IR (Infrared) transmitter.

I don’t quite remember how or why I ended up messing with the IR stuff, it just sort of happened. I’ll get to the beacon stuff in a future experiment.

So, IR transmitter… what do I have in the house that responds to IR? A television!

Sending an IR sequence on the Puck is trivial:

Puck.IR(command);

To get the command, you can either attach an IR receiver to your Puck and record direct from your remote control, or head over to IRDB (InfraRed DataBase) and see if your target device is listed there. Luckily for me, my TV – a Samsung – was on the IRDB list. Here’s the hexadecimal sequence for power on/off:

0000 006C 0000 0022 00AD 00AD 0016 0041 0016 0041 0016 0041 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0041 0016 0041 0016 0041 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0041 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0041 0016 0016 0016 0041 0016 0041 0016 0041 0016 0041 0016 0041 0016 0041 0016 06FB

The website displays it as a string, so you’ll need to convert it to an array of numbers – luckily, the Puck has a ready made API for that too:

var pronto  = require("pronto");
var command = pronto.decode( long_hex_string_goes_here );

So, now I’ve got the command, I’ve converted it to the correct format, and I can immediately send it to the IR transmitter – but I want an easy way to choose when to send it. The Puck has that covered too – there’s a button on the underside of the PCB which turns the whole device in to a push-button. And there’s an easy way to trigger some code when the button is pushed too:

setWatch(
  function() {
    // your code here
  },
  BTN, // pin to watch
  {edge:"rising", debounce:25, repeat:true} // settings
);

It watches the specified pin (in this case “BTN”) for a rising edge, and when found it runs your code.

Here’s the final script:

var Green   = LED2; // more semantic name for the LED
var pronto  = require("pronto");
var command = pronto.decode( "0000 006C 0000 0022 00AD 00AD 0016 0041 0016 0041 0016 0041 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0041 0016 0041 0016 0041 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0041 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0041 0016 0016 0016 0041 0016 0041 0016 0041 0016 0041 0016 0041 0016 0041 0016 06FB" );

setWatch(
  function() {
    Green.set(); // turn on green LED
    console.log("Power toggle"); // debug message to REPL
    Puck.IR(command); // send the IR command
    Green.reset(); // turn off green LED
  },
  BTN,
  {edge:"rising", debounce:25, repeat:true}
);

All that remains now is to test it on my TV! The IR transmitter on the Puck is really small, so I had to hold the Puck close to the IR receiver on the TV. Anyway, here’s the results…

So, it mostly worked then 🙂