IRTrans: CCF on ARM is a no-go

irtransIt’s very easy to forget about certain components of your Home Automation system – especially those that never give any problem.. fire and really forget ūüôā

An example of that is my IRTrans LAN infrared transceiver which I’m using since 2009. The IRTrans needs a so-called irserver¬†program, which is the gateway between your application and the IRTrans hardware. Some time ago I found out that I still have irserver running on my Windows server as a service instead of one of my Cubietrucks. And since I want to get rid of the Windows server (a VM running on Hyper-V) I had to find a way ¬†to move irserver to something Linux based – either a Raspberry Pi, Cubietruck or Odroid.

So I downloaded the Linux source code for irserver and tried to build it – no luck. Hmm, what’s wrong here. It didn’t take long to find out that I was missing a file: ccf.o. The only thing that worked was ‘make irserver_arm_noccf‘, but that didn’t sound very hopeful – no CCF? So I searched the IRTrans forum and found a post in which I read that there is a ccf.o available, although not suitable for all types of ARM processors (I assume). So I posted a question on the IRTrans forum, waited for about 7 weeks, but no (useful) response from the IRTrans support department. Strange …

Conclusion: CCF on ARM is a no-go. So I decided to create my own solution. Irserver without CCF meant I had to convert all my Philips Pronto CCF codes to hex. Luckily I found an easy way to do that with the IRTrans GUI Client:

IRTrans CCF to Hex

By not selecting a command in the Command combobox shown above, all the CCF codes for the selected remote are converted to hex. OK, now we’re getting somewhere… I copied all the output to a text file and repeated this for all the remotes. Now I have a single file with all the remotes, commands and hex codes which looks like this:File with hexcodesThis ¬†file is very easy to parse¬†by my Node.JS¬†IRTrans driver, so with some additional changes in the code this should work.

In the CCF-enabled irserver situation I queried irserver with Agetremotes and Agetcommandlist to find out what commands were available (instead of defining those myself somewhere), but that method is useless with a CCF-disabled irserver in combination with CCF codes. So now that I have to work with a somewhat crippled irserver, I’m gonna use it as a simple hexcode transmitter.

And where I used to send commands to irserver with the Asnd command, I now have to use Asndhex.

My IRTrans now parses the new ‘hex code’ file, saves it in memory and sends the appropriate hex codes based on the commands it receives. So if some UI transmits “upc,yellow”, the driver sends a “Asndhex ¬†H3E01000000…” command to irserver instead of “Asnd upc,yellow”.

No changes needed in the User Interfaces, everything is still working as before and all the hex codes I tested do what they’re supposed to do – I haven’t tested them all yet, but the most important ones are working.

Another reason to keep my Windows server ‘up’ is gone – on to the next one!

Raising the bar with the IRTrans driver

The last few days I’ve been busy developing a driver for my IRTrans LAN IR transmitter/receiver. I chose the IRTrans because it’s not being used that much (anymore), but still enough to detect bugs within a few hours. And another nice thing is that the IRTrans LAN Gateway accepts multiple connections, so testing a new driver is easy – I won’t have to completely shut down my previous (and still actively used) driver developed in Delphi.¬†While working on this driver, I took the time to also improve some other things (which I should have done earlier).

Settings

I didn’t like the way some drivers have IP-addresses of hardware interfaces hard-coded, so I fixed that. Mosquitto (the MQTT broker I’m using) looks like the best place to store settings like the IP-address & port the driver has to connect to, poll intervals and other parameters that influence how a driver behaves. But first, I needed a way to find out where my broker is – for that I created 2 system-wide environment variables by adding the following to the file /etc/environment on the Raspberry Pi:

DDMC_BROKER_HOST=192.168.10.13
DDMC_BROKER_PORT=1883

If you’re using a Windows PC for development, you’ll have to add those environment variables on that machine as well, or add them to the nodevars.bat that starts the Node.js environment on Windows:

@echo off
rem Ensure this Node.js and npm are first in the PATH
set PATH=%APPDATA%npm;%~dp0;%PATH%
rem settings specific to DDMC
set DDMC_BROKER_HOST=192.168.10.13
set DDMC_BROKER_PORT=1883

A simple change in how the Node.js MQTT client connects and this issue was fixed:


var host = process.env.DDMC_BROKER_HOST;
var port = process.env.DDMC_BROKER_PORT;
mqttClient = mqtt.createClient(port, host);

When the connection has been established, the rest of the required settings can be retrieved from the MQTT broker by subscribing to a topic and wait for a message to arrive:


// get required settings
tools.mqttClient.on('connect', function(packet) {
  tools.settings.require('host');
  tools.settings.require('port');
  tools.settings.require('subdelay');
});

Of course, the script has to wait for the required settings to arrive; this is done by keeping track of all the required settings and ‘pause’ execution until all required settings are ‘set’ by the incoming messages. I picked up this idea by browsing the HomA source code which was brought to my attention in a comment recently. Now I can remove all the hard-coded stuff from the driver code and clean them up a bit.

OK, back to the IRTrans driver. During all the years I’ve been working with the IRTrans, I added some ‘features’ which I didn’t want to lose:

Channels.

I’m used to working with TV station names instead of channel numbers for my cable STB. An example: I have a page on my Philips Pronto TSU9600 with icons for all the TV station we’re able to receive. Let’s say that each icon (a button, actually) has on onClick() method which looks like this: SetDevice(‘upc’, ‘EUROSPORT’);

Why? Because I can’t remember that EuroSport is on channel 401, but I can remember the ‘short-codes’ like ‘EUROSPORT’, ‘NED1’, ‘BBC1’, ‘WDR’,’DISCOVERY’…

But the IRTrans doesn’t know what ‘EUROSPORT’ means, so I made a ‘mapping’ table on my SQL Server to translate ‘EUROSPORT’ to ‘401’. But because the Node driver has no way to connect to my SQL Server, I added an extra setting to the IRTrans driver, so I don’t have to change all the UI’s when something changes and I can keep on using these ‘short-codes’ for ever:

{"EUROSPORT":201,
"BBC1":50,
"BBC2":51,
"ANIMAL":21,
"NATGEO":18,
....
"CNN":401}

The JSON formatted data shown above is parsed and used as an associative array.

Delays

Let’s take the example above a little further. Eurosport, channel 401. All the buttons on the remote of the Cable set-top box (STB) were learned with the Philips Pronto (PEP1) and added to a IRTrans .rem file. That means that I have an IR code for the button ‘1’, another one for ‘2’, ‘3’ and so forth. But I don’t have an IR code for ‘401’. So, to mimic selecting channel 401 with the remote, I have to send the IRTrans 3 IR codes: the code for ‘4’,’0′ and ‘1’. And I have to add a delay between those 3 IR codes because if I don’t, the STB doesn’t always recognize what’s being sent!¬†Hmm… delay, event-driven, timeouts… challenge.

Adding a delay is not such a problem, because the Node.js¬†setTimeout() command allows you to add a minimum(!) delay before something’s being executed. But no matter what I tried, instead of sending the ‘4’,’0′,’1′ sequence to the IRTrans, my driver code sent ‘1’,’1′,’1’… Okay, those who are familiar with Javascript will probably know what is causing this, but for me this ‘scope’ problem was new!

After I read this excellent page, I knew what to do… well, that’s the down-side of immediately start coding instead of learning the language first.

Toggle codes.

A more detailed explanation of the problem with our current STB is described here¬†as well as how I handled it, although the issue can also be fixed with newer IRTrans firmware. The new Node.js based IRTrans driver has to automatically handle this toggle problem as well of course, as if toggle codes don’t even exist. That’s because I don’t want to send up#1, up#2, up#1 from my UI’s to go from channel X to X+3, but just up, up, up – it’s ridiculous and it wouldn’t work anyway, with more than 1 UI –¬†capiche?

So the IRTrans driver should keep track of the last-used IR code for ‘up’. ¬†The ‘old’ Delphi driver already retrieved a lot of information from the IRTrans gateway – the identifications of all the remotes (upc, onkyo, hdmax, …) and all the commands (up, down, vol+, poweron,..) of those remotes, so I did the smae thing in my Node driver.

So the physical STB remote has 2 different IR codes for the ‘up’ button, which I named ‘up#1’ and ‘up#2’. I use the ‘#’ in the command name to detect that we’re dealing with a so-called toggle code for the ‘up’ command. So all I had to do was collect all the commands starting with ‘up#’ into a single object instance, add an index counter and all goes automatically…

During startup of the new IRTrans driver I query the IRTrans driver with ‘Agetremotes‘ and ‘Agetcommands‘ and store the information in an array. Here’s the code of the class that ‘hides’ the toggle code issue:

var InfraRedCommand = function(remotecommand) {
  this._command = remotecommand;
  this._index = 0;
  this._toggleCodes = [];
}
InfraRedCommand.prototype.addCode = function(code){
  this._toggleCodes.push(code);
}
InfraRedCommand.prototype.getCode = function(){
  if(this._toggleCodes.length > 0){
    this._index++;
    if(this._index >= this._toggleCodes.length) this._index = 0;
    return this._toggleCodes[this._index];
  } else {
  	parts = this._command.split(",");
    return parts[parts.length-1];
  }
}

module.exports = InfraRedCommand;

Now the toggle codes are hidden, in just a few lines of code ūüôā

From time to time I test this new IRTrans driver by sending an ‘off’ command to the TV or STB, or switching to ‘CNN’. Judging by the amount of uproar coming from the living-room, this new driver is working very well!

 

IR trouble with the Pace DCR7111 (UPC mediabox)

This week we got a new UPC Mediabox; the old Thomson DCI52UPC02 was replaced by a Pace DCR7111(/03). The Thomson was constantly updating itself, went into reboot-loops where only disconnecting power sometimes helped to get it going again. After I finally managed to get in touch with UPC support, 2 days later the new box arrived.

My biggest concern was whether this new Pace box would still work my Pronto/IRTrans combo; would it accept the same Infrared (IR) codes as the Thomson? A quick test revealed that the old Thomson remote could be used to control the new Pace, so at that point I didn’t expect any problems.

Later that evening, when I used the Pronto to control the Pace mediabox, I discovered that the “CH+” and “CH-” buttons of the Pronto didn’t work anymore. To be precise: the first “CH+” did work, but the second time it didn’t…huh? The “CH-” had the same wierd behavior.. first push OK, the second was ignored; and the 3rd, 4th… So selecting a channel with a digit (0..9) did work as before, but zapping through all the channels didn’t? What the ….?

Hmm, time for some investigation. First thing I did was trying to find the Pronto CCF codes for this new model, but that didn’t help. Later I found out that this Pace uses the same IR codes as a Philips DCR-8111 but I couldn’t find any IR codes for that model either.

Well, back to the original symptom then Рwhy do the CH-buttons only work once? After some time I found the cause in a post on the L5 remote forum:

Parity & Toggle Bits
A somewhat common problem is when a device (such as a cable box) will accept a learned code once but not twice in a row. For instance, you can enter the channel “1 – 2”, but not “3 – 3”. This is not a fault with your new remote, but rather a very hard to work with design employed by your equipment.
What happens is your original remote tacks on a “parity bit” (sometimes called a “toggle bit”) to the end of each code. So, the first time it sends the code it follows up with a “0”. The next time it ends with “1”. The problem is that a learning remote can only learn or send the signal one way ‚Äď the way it learned it. Your equipment, unfortunately, will not accept the code again unless it ends with a new parity bit or you send a different code to clear the memory buffer.

The most common example of equipment that uses this system is anything that employs the Philips RC5 or RC6 code format – such as Philips or Marantz products, or even Microsoft Media Center Edition remote controls. As the RC5 and RC6 implementation guidelines make parity bit checking optional, not all RC5/RC6 devices will respond the same way to non-alternating learned codes. Some may require parity bits at all times, some may only require it for certain commands (such as “power”), some may use the parity bit only for closely repeated commands (meaning you could send “3-3-3” quickly with the original remote but only slower using a learned code), while some ignore parity bits completely and show no noticable operational difference with or without.

The Philips Pronto is the only remote that I am aware of that can learn codes with alternating parity bits in the method required for several (not all) brands of equipment. If you have one that is not yet covered you can try tacking on a “do-nothing” code after each real one. So, your button for “3” would send the “3” code followed by another code to clear the buffer. What can that code be? Anything that the equipment senses as a real code but doesn‚Äôt affect operation. It may be next to impossible to find such a code.

Great, this sounds exactly as what I’m experiencing. Parity (toggle) bits… and the new Pace doesn’t ignore them!

Now that I know what is causing my problem and how it works, I should be able to create a workaround; I can stop searching for the correct IR codes for the CH+/CH- buttons, because a single IR code for a CH button will never work. Instead, I will need to get hold of both IR code ‘versions’ for a single CH button and make sure my system will automatically alternate between those 2 versions.

How do I get those 2 codes for a single button? Well, ¬†PEP1 (Pronto Edit Professional v1) and a Pronto Remote (a TSU9600 in my case) enables you to learn a IR code. So that’s what I did; I learned ¬†a couple of CH+ IR codes, copied the resulting CCF codes to a text editor and searched for differences; and found the 2 different versions for CH+:

[up1][CCF]
0000 0072 0024 0000 000F 000A 0006 000A 0006 0016 0006 000A 0006 000A 0006
001C 0006 000A 0006 000A 0006 000A 0006 0016 0006 0016 0006 0010 0006 0016
0006 000A 0006 0016 0006 000A 0006 000A 0006 0CB7 000F 000A 0006 000A 0006
0016 0006 000A 0006 000A 0006 001C 0006 000A 0006 000A 0006 000A 0006 0016
0006 0016 0006 0010 0006 0016 0006 000A 0006 0016 0006 000A 0006 000A 0006
BEA1

[up2][CCF]
0000 0072 0024 0000 000F 000A 0006 000A 0006 0016 0006 000A 0006 000A 0006
001C 0006 000A 0006 000A 0006 000A 0006 000A 0006 0016 0006 0010 0006 0016
0006 000A 0006 0016 0006 000A 0006 000A 0006 0CB7 000F 000A 0006 000A 0006
0016 0006 000A 0006 000A 0006 001C 0006 000A 0006 000A 0006 000A 0006 000A
0006 0016 0006 0010 0006 0016 0006 000A 0006 0016 0006 000A 0006 000A 0006
BEA1

There’s¬†definitely¬†a difference between those 2 codes, marked in red; so far things are looking good. Now it’s time to test these 2 codes by sending a up1, up2, up1, up2 IR sequence to the Pace mediabox. Yep; the channel increased 4 times – it worked!

The rest is simple.¬†My system uses the IRTRans ASCII interface protocol for sending IR with the IRTrans LAN module. The IR commands that can be used are not predefined in my Domotica system however; they are retrieved from the IRTrans by using the Agetremotes and Agetcommands commands. So all I have to do is ‘tag’ the 2 ‘up’ commands in a way that my system can figure out that there are 2 commands for ‘up’. For example, I could name them [up#1] and [up#2] and let the system pick the right ‘up’ version and send the right ‘up’ command (up#1, up#2) to the IRTrans with the Asnd command whenever a UI sends a ‘up’ request..

No need to change anything at UI level and 10 lines of code should suffice. Problem solved!

Update Monday 06-08-2012:

I received an email from IRTrans (Marcus) with some additional information:

The Pace STB uses RCMM Codes with toggle bits. Newer IRTrans Firmware versions have got a flag you can activate.

Then the IRTrans device will recognize and reassemble the toggle bits automatically.

You can find the setting on the IR Codes page of the IRTrans Device settings.

So if you’re using a IRTrans product, it’s as simple as changing the Device settings. Another thing worth knowing is that if you have a firmware version that doesn’t support this setting (like me), you can request a firmware update via Email.

 

IRTrans Ethernet implemented

This evening i finished my IRTrans project.

With the IRTrans i can control all IR controlled devices in the livingroom from wherever i want.
The IRTrans Ethernet is based on a TCP/IP Client/Server architecture and communication is done using port 21000.

There are several ways to integrate the IRTrans in your own software; my personal favorite interface is the TCP/ASCII interface, since it’s easy to do and you’re independant of dll’s, ActiveX and other things like that. The ASCII interface gives you the ability to send and receive IR commands and to retrieve lists of the configured remotes and commands.
All this can be very easily done by opening a Client socket to port 21000 of the machine where you have the IRServer software running.

You can send commands like: Asnd TV,vol_up or Asnd mediaplayer,ch+ .
After the command has been sent, you’ll receive a status message with which you can determine if everything went as expected.

IR commands that are received by the IRTrans Receviver are sent over the socket from IRTrans to your own software as well;
you’ll receive things like **00034 RCV_COM pinnacle,play,0,0 . That way you know someone pressed the play-button on your pinnacle remote.

Learning all IR codes of 4 remotes took me about 2-3 hours. Because i already had a lot of IR codes stored in my Philips Pronto TSU9600,
it was just a matter of copy/paste since IRTrans supports the Pronto CCF IR format. Everything worked perfectly.
With the IRTRans located in the opposite corner of the livingroom, being >10 m away from the equipment it has to control,
there have been no problems of IR commands not being executed by TV/Home Theatre/STB/Media player.

And from now on, with the IRTrans in the livingroom, i don’t have have to use the Pronto IR anymore. Not the Pronto does bad IR, but it was too ‘closed’ in relation the rest of my Home Automation stuff. New setup is that the Pronto sends commands to my Home Automation software, which relays these commands to the IRTrans.

This is the same approach i use for lighting: the Pronto sends a ‘light XY on’ command to my Home Automation software which takes care of the rest.

Benefits of doing IR this way are:
– No more aiming needed;
– Full IR control from everywhere;
– IR is now easier expandable for multiroom control;
– My HA software now knows what buttons are pressed and can automatically trigger events based on them; like closing the curtains at the ‘Play Movie’ button.
– It also knows about all kinds of other events happening: so when there’s an incoming phonecall, i can mute Radio and TV.

The IRTrans certainly is a great addition to my hardware.