Saturday, 21 April 2012

Controlling an LG TV via serial from Linux.

I have an LG plasma TV. Like most electronic home entertainment stuff these days, it comes with a port on the back for controlling it. In this case a serial port. LG helpfully put all the commands for controlling it in the back of the manual. 

The commands are along the lines of:

ka 01 00 - Which turns the power off.


kf 01 ff - Which is query, "what is the power status?"

Which will return:

a 01 OK01x     - A string as to whether the TV is On or Off, in this case "ON".

This is useful as it provides a feedback mechanism, rather than shooting commands down the line and hoping that they'll have an effect (a la X10).

So if I want to increase the volume by 1, I can read the current volume and add 1 to it.

So this gives me the opportunity to automate tasks based on external events. Now a lot of my stuff I control from BASH Linux shell scripts and this is no different. 

To control it from BASH is quite easy, you can just "echo" to or "cat" from the serial device. But first I set up the serial connection:

stty time 3 min 0 < $serial
stty -F $serial -icrnl -ixon ignbrk isig -echoctl -echoke -isig -icanon -iexten 
-echo -echoe -echok -opost -onlcr -hupcl

That last line is all one line, i.e. it starts with "stty -F" and continues on to the end of "-hupcl".

The TV will communicate at the seemingly standard 9600 baud, 8N1 bits, parity and stop bits.

So if I want to turn the TV to the HDMI4 input, I can send:

echo "xb 01 93" > $serial

The 93 is derived from a binary representation from the chart on page 121 of my manual. The 9 being the input type (DTV, HDMI etc) and the 3 being the actual input of that type. In this case port 3 (as it counts up from 0).

If I want to read the current input:

echo "xb 01 FF" > $serial
sleep 1
rdserial=`cat $serial`

This would return something like:


Which in this case would mean:

HDMI, represented by the hex number "a" and port number represented by the number 3. The output doesn't seem to be in my manual, but goes as follows:

0 - DTV, 1 - Analogue TV, 3 -AV, 4 - Component, 5 - VGA PC Input and finally "a" - HDMI.

The manual list commands to be able to most of the functions on the TV by the serial port, everything from sending keys to simulate remote presses to changing the aspect ratio etc.

I've found the HDMI link function (SIMPLINK) on the TV not overly useful in my use with my PS3, so the serial control offers something a little more customisable.

Wednesday, 27 April 2011

Getting SNMP info by phone.


I have a small Asterisk VOIP PBX running. It's the PBX in a Flash version from the Nerd Vittles site and I have it running off a USB key plugged into a Acer Revo small PC.

One of the useful things about having your own PBX is that you can play about with things like IVR's (Interactive Voice Response), those annoying voice menu things you get when you ring up the gas board with a billing query. On Asterisk IVR's can also be very useful for technical doing stuff like running Linux command line utilities and getting the output read back to you with a text to speech voice. I have mine reading back my current ADSL connection speed, as my mine gets gradually slower after a few days.

Here's how to do it:

If you have a Centos/Redhat based Asterisk server you need to install SNMP utils.

$> yum install net-snmp-utils

Install any dependencies too.

This will get you the snmpget command line tool.

To get the connection speed out of my router, I would need to issue the command:

snmpget -v 1 -c public .

The long number at the end is the location (MIB) of the connection speed in my router (which is You can change this last bit to get any other SNMP info you might be interested in.

This command will give the output:

IF-MIB::ifSpeed.4 = Gauge32: 5970000

My connection speed being the last number. (Yes, it's slow I know)

To get this in a usable format I stick it in a shell script called "get-net-speed", located in /usr/local/bin:


cmd="snmpget -v 1 -c public ."

speed=`$cmd | cut -f 4 -d :`
echo $speed

(The SNMPGET line is all on one line, the formatting makes it go funny)
Save, exit and make the script executable (chmod 0755 get-net-speed).

This will, when run just give me the speed number.

To get it into asterisk, we need to put it into a phpagi script.

phpagi is a php scripting language for asterisk, it allows you to do more complex programming based things than the built in asterisk system will allow. This includes using SQL databases and complex conditional routines based on external events. Here we are just going to do a simple command line execution:

In the directory: /var/lib/asterisk/agi-bin

We need to put in the following script called getnetspeed.php:

#!/usr/bin/php -q

$agi = new AGI();
$data = shell_exec('/usr/local/bin/get-net-speed');
$agi->exec("Flite","\"The current internet connection speed is: $data\"");

This uses the phpagi class which simplifies phpagi communication.

Flite is the text to speech engine included in PBX in a Flash and does a pretty good job of speaking what you give it.

The last bit is to reference the php script in asterisk.

cd to the asterisk config directory:

$> cd /etc/asterisk

and edit the extensions_custom.conf file, this is the custom extensions file, it isn't wiped by the FreePBX config when that is edited.

$> joe extensions_custom.conf

and locate the area just below the "[from-internal-custom]" block:

find a gap and put in:

exten => 6566,1,Answer
exten => 6566,2,AGI(getnetspeed.php)
exten => 6566,3,Hangup

6566 is the phone extension you dial to get the info.

Finally go into your asterisk console and reload the config:

$> asterisk -rvvv

and type "reload":

buzby*CLI> reload

If your config reloaded OK, you can now test it by dialling 6566 on a phone.

This is quite a powerful thing, as it means that almost any command line tool can be attached to a phone extension or IVR menu. If you want to monitor drive temperatures, you can trim the output of a "smartctl" command, if you want to know how much disk space is free, "du". You can even use it to reboot servers (I'd stick a pin number in for that though". If you have remote dial in to your PBX, then you can do all this remotely.

Monday, 28 June 2010

Linux autofs and Wake on Lan bodge.


Like many people, I have a media server which stores all of my films, music and pictures in all one central place. It's a Centos Linux box with a SATA card and software Raid5, it serves to devices like my Acer Revo running Xbmc and Mythtv frontend. With this configuration it's a little noisy, creates a bit of heat and probably uses a bit of electricity, but turning it on can be a bit of a hassle. Particularly when it's at the other end of the house. My solution autofs and wake on lan.

autofs is a suite of tools that will auto mount devices and NFS shares when you first use them. Wake on LAN on my setup was a small cable that goes between my (dlink) PCI network card and my motherboard and I had to edit the BIOS to allow the machine to be woken. There seems to be a number of different ways to setup WOL on linux. I had to use ethtool to put the network card in a fit state to be woken up when the server was shutdown:

ethtool -s eth1 wol g

I actually put this in a Bash script and then called it from a script called "ifdown-post" located in:


This gets called on shutdown.

To wake the machine up I used the etherwake command. My xbmc machine uses Ubuntu as it's base OS. The package is simply called "etherwake"

So to wake up the remote machine you would use:

etherwake mac address

In my case:

etherwake 00:26:5A:F0:33:0C

The command is located in /usr/sbin on my install. Execute and bingo the machine powers up.

Now, a little used feature on autofs is the executable map. Maps normally are just plain text showing where to and what to mount and with which options. An executable one, is a shell script, in my case Bash, which the mount bits echo'd out at the end.

To use with autofs, you need to have NFS installed running on the machine you want to mount and a filesystem or directory exported in:


which looks something like this on mine:


This allows ws022 on my network to mount that directory as read/write.

On the mounting machine you need autofs running and the maps in /etc looking something like this:


/mnt/mnts/media-server /etc/ --timeout=60

and in:



ping -c 1 -w 1 -q $hostsrv >/dev/null
if [ $status -ne 0 ]
/usr/sbin/etherwake 00:26:5A:F0:33:0C
sleep 60
/bin/echo -n "video"
/bin/echo -n -e "\t"
/bin/echo -n "$opts"
/bin/echo -n -e "\t"
/bin/echo "$hostsrv:/usr1/media-server/video"

Edit the files and make the file executable:

chmod 0750 /etc/

Then create your mount points:

mkdir /mnt/mnts /mnt/mnts/media-server

then give it a:

service autofs restart

What the above script does, is test if the server responds to a ping. If it doesn't, send a wake up call and wait 60 seconds, this is how long my machine takes to bootup. Once booted or if it already is, echo out the mount info.

So with the server shutdown, I can on the client machine:

cd /mnt/mnts/media-server/video

and the server will power up, the client will wait a while and then mount the directory. Magic!

If anyone spots any errors, improvements or indeed a way to get it to auto shutdown when autofs unmounts, let me know.