Web Remote Control

The words “web” and “remote control” are used together to describe all manner of things, but here I’m talking about a remote control of a PVR, using a web page. In these days of wireless connectivity, and distributed video, it’s almost a natural thing to want to be able to control stationary equipment from a roaming laptop or tablet computer. It seems that this is the sort of thing that many people would have done before, but my searches were fruitless.

It turns out this sort of thing isn’t all that difficult to brew from scratch, although there are a lot of little pieces that need to be properly strung together. Starting from the PVR itself, an infrared emitter is necessary that’s compatible with lirc. (Consult the lirc documentation for a list of compatible emitters, and instructions for rolling your own.)

Lirc itself needs to be installed and working properly; I won’t attempt to duplicate the documentation, which is fairly straightforward, but I ran into two snags. First, lirc on gentoo requires a USE flag to be set in order to transmit at all — Gentoo has some excellent supplemental documentation here. Second, not all the buttons were represented on my remote. This was easy enough to rectify starting with the lircd.conf closest to my equipment using the irrecord tool and some hexidecimal math. (Obviously, this required that I also get lirc working as a receiver, but all I really used it for was adding additional codes.)

My Remote Next, I located a picture of my remote. The basic interface idea is to have a web page where the user can simply poke each button. They’re a little hard to read in this image, so this could be considerably improved, but realistically, after using the physical remote for a while, the positions and functions of the buttons become second nature.  In addition, rolling over each button gives its function (albeit in an ugly way; this can be improved, too, of course.)

A standard image map is used to make each button clickable. To prevent annoying refresh and latency issues, simple AJAX techniques are employed to send each button press to the web server behind the scenes.

Here’s the actual code of the pages:

pushbutton.php —
<?php
echo ‘irsend SEND_ONCE dish2 ‘ . $_GET[‘button’];
system(‘/usr/bin/irsend SEND_ONCE dish2 ‘ . $_GET[‘button’]);
?>

And

dishremote.php –<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd“>
<html>
<head>
<title>PVR Control</title>
<meta http-equiv=”Content-Type” content=”text/html; charset=iso-8859-1″>
</head>

<script type=”text/javascript”>
var xmlhttp
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try {
xmlhttp=new ActiveXObject(“Msxml2.XMLHTTP”);
} catch (e) {
try {
xmlhttp=new ActiveXObject(“Microsoft.XMLHTTP”);
} catch (E) {
xmlhttp=false;
}
}
@else
xmlhttp=false
@end @*/
if (!xmlhttp && typeof XMLHttpRequest!=’undefined’) {
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
xmlhttp=false;
}
}
if (!xmlhttp && window.createRequest) {
try {
xmlhttp = window.createRequest();
} catch (e) {
xmlhttp=false;
}
}
function button(the_button) {
xmlhttp.open(“GET”, “pushbutton.php?button=”+the_button,true);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {
/* alert(xmlhttp.responseText) */
}
}
xmlhttp.send(null)
}
</script>

<body>
<img src=”6.2remote.jpg” width=”136″ height=”416″ border=”0″ usemap=”#Map”>
<map name=”Map”>
<area shape=”circle” coords=”68,30,8″ href=”javascript:button(‘power’)”>
<area shape=”circle” coords=”45,288,7″ href=”javascript:button(‘1’)”>
<area shape=”circle” coords=”68,287,7″ href=”javascript:button(‘2’)”>
<area shape=”circle” coords=”90,287,7″ href=”javascript:button(‘3’)”>
<area shape=”circle” coords=”46,308,7″ href=”javascript:button(‘4’)”>
<area shape=”circle” coords=”68,309,7″ href=”javascript:button(‘5’)”>
<area shape=”circle” coords=”91,308,7″ href=”javascript:button(‘6’)”>
<area shape=”circle” coords=”46,328,7″ href=”javascript:button(‘7’)”>
<area shape=”circle” coords=”67,328,7″ href=”javascript:button(‘8’)”>
<area shape=”circle” coords=”90,329,7″ href=”javascript:button(‘9’)”>
<area shape=”circle” coords=”27,70,6″ href=”javascript:button(‘menu’)”>
<area shape=”circle” coords=”67,121,14″ href=”javascript:button(‘select’)”>
<area shape=”circle” coords=”111,143,9″ href=”javascript:button(‘cancel’)”>
<area shape=”circle” coords=”109,98,8″ href=”javascript:button(‘guide’)”>
<area shape=”circle” coords=”91,162,8″ href=”javascript:button(‘view’)”>
<area shape=”poly” coords=”96,106,84,113,83,130,96,139,103,123″ href=”javascript:button(‘right’)”>
<area shape=”poly” coords=”52,132,52,112,37,105,32,122,37,138″ href=”javascript:button(‘left’)”>
<area shape=”poly” coords=”53,107,80,107,92,97,69,87,45,97″ href=”javascript:button(‘up’)”>
<area shape=”poly” coords=”55,136,80,135,92,146,70,158,44,147″ href=”javascript:button(‘down’)”>
<area shape=”circle” coords=”25,143,7″ href=”javascript:button(‘recall’)”>
<area shape=”circle” coords=”68,237,7″ href=”javascript:button(‘record’)”>
<area shape=”circle” coords=”68,212,11″ href=”javascript:button(‘pause’)”>
<area shape=”circle” coords=”46,228,9″ href=”javascript:button(‘stop’)”>
<area shape=”circle” coords=”107,211,9″ href=”javascript:button(‘fwd’)”>
<area shape=”circle” coords=”46,348,7″ href=”javascript:button(‘asterisk’)”>
<area shape=”circle” coords=”68,349,7″ href=”javascript:button(‘0’)”>
<area shape=”circle” coords=”91,348,7″ href=”javascript:button(‘pound’)”>
<area shape=”circle” coords=”45,162,8″ href=”javascript:button(‘info’)”>
<area shape=”circle” coords=”88,228,8″ href=”javascript:button(‘play’)”>
<area shape=”circle” coords=”27,210,9″ href=”javascript:button(‘back’)”>
<area shape=”circle” coords=”67,182,10″ href=”javascript:button(‘dvr’)”>
<area shape=”circle” coords=”90,58,8″ href=”javascript:button(‘page_up’)”>
<area shape=”circle” coords=”109,71,7″ href=”javascript:button(‘page_down’)”>
<area shape=”circle” coords=”47,194,9″ href=”javascript:button(‘skip_back’)”>
<area shape=”circle” coords=”88,193,9″ href=”javascript:button(‘skip_fwd’)”>
<area shape=”circle” coords=”107,247,8″ href=”javascript:button(‘dish’)”>
</map>
</body>
</html>

Share
Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

By submitting this form, you accept the Mollom privacy policy.

This site uses Akismet to reduce spam. Learn how your comment data is processed.