[mythtv-users] Yet another RCA/Sony serial control script (DRD222RD)
William
wmunson at rochester.rr.com
Mon Mar 22 08:05:12 EST 2004
Here is my donation to the community. This is a remote control script I
pulled together from various other control scripts when I could not find one
that would control my RCA DRD222RD satellite receiver. I believe this is the
"old" command set. The script has a couple of bonus features I have not seen
elsewhere. Read the headers for details.
-----------------Snip here -----------------
#!/usr/bin/perl
# channel.pl - Version 1.1 (March 18, 2004)
# Channel changing script for RCA DSS units via the serial port.
# By William Munson [wmunson at rochester.rr.com]
# Based on pieces pulled from various other DSS control scripts.
#
# This script accepts a 1 or more digit channel number on the command line
# or a single key command which must be defined in the keymap. The program
also
# accepts the command 'macro' which is detailed later in the script.
#
# I take no responsibility for any damage this script might cause.
# Feel free to modify and redistribute this as you see fit, but please
retain
# these comments.
#
# Version 1.0 - First working version. Only supports channel change commands
via
# channel number on the command line.
#
# Version 1.1 - Added support for commands other than a simple channel
number.
# Also added support for a macro command. For example this could be used
# to send the keystrokes to buy a ppv if you associate the macro with a
remote key.
$|=1;
use POSIX qw(:termios_h);
use FileHandle;
# Use verbose output mode for debugging.
$verbose=0;
# Time delay between each channel digit when a channel number is entered.
$inter_digit_delay=0.25;
# Enable to clear the on screen display more quickly.
# Warning: This slows down channel scrolling so use browse mode
# for best results or leave it disabled if you want snappier channel
# changes and can put up with the on screen display.
$quick_clear=1;
%pkt_decode=("0xF0" => "START PKT",
"0xF1" => "ERR 1",
"0xF2" => "GOT EXTENDED",
"0xF4" => "END PKT",
"0xF5" => "ERR 2",
"0xFB" => "PROMPT");
%terminal=("0xF1" => -1,
"0xF4" => 1,
"0xF5" => -1);
%keymap=(right => "0x9a",
left => "0x9b",
up => "0x9c",
down => "0x9d",
favorite => "0x9e",
select => "0xc3",
exit => "0xc5",
9 => "0xc6",
8 => "0xc7",
7 => "0xc8",
6 => "0xc9",
5 => "0xca",
4 => "0xcb",
3 => "0xcc",
2 => "0xcd",
1 => "0xce",
0 => "0xcf",
ch_up => "0xd2",
ch_dn => "0xd3",
power => "0xd5",
jump => "0xd8",
guide => "0xe5",
clear => "0xf9",
menu => "0xf7");
# Variables used to process the channel number command line.
$position=0;
$digit="";
# Start of main code.
$cmd_line_input=@ARGV[0];
# Defaults to standard COM1 port, 9600 baud.
my $serial=init_serial("/dev/ttyS0","9600");
# Start of command decoding
if (length($cmd_line_input)) {
# Check to see if a channel number was entered.
if ($cmd_line_input != 0) {
change_channel($cmd_line_input);
exit;
}
if ($cmd_line_input eq "macro") {
# Do macro commands. Use your own key sequence here.
# Change it around as required for your needs.
dss_key("down");
sleep(1.0);
dss_key("up");
sleep(1.0);
dss_key("select");
sleep(1.0);
dss_key("clear");
exit;
}
# No special processing required. Send a single command.
dss_key($cmd_line_input);
} else {
print "You must enter a command for this script to work.\n";
}
# begin subroutines.
sub change_channel {
# Send a serial command for each digit of the channel number
my ($channel_num)=@_;
if ($verbose){
print "Channel number: ";
print $channel_num;
print "\n";
}
while ($position<length($channel_num)){
$digit=substr($channel_num,$position,1);
if ($verbose){
print "Digit: ";
print $digit;
print "\n";
}
dss_key($digit);
$position++;
sleep($inter_digit_delay);
}
#If enabled, clear the display after sleeping one second
if ($quick_clear){
sleep(1.0);
print "Clear Display:\n" if ($verbose);
dss_key("clear");
}
}
sub dss_key {
my ($key)=@_;
return undef unless $keymap{$key};
simple_command("0x45","0x00","0x00",$keymap{$key});
}
sub simple_command {
if (defined(dss_command(@_))) {
return(1);
} else {
return(undef);
}
}
sub dss_command {
sendbytes("0xFA", at _);
return get_reply();
}
sub sendbytes {
(@send)=@_;
foreach (@send) { s/^0x//g; $_=hex($_); }
print "SEND: " if ($verbose);
foreach $num (@send) {
$str=pack('C',$num);
printf("0x%X [%s] ", $num, $str) if ($verbose);
syswrite($serial,$str,length($str));
}
print "\n" if ($verbose);
}
sub get_reply {
my $starttime=time();
my ($last,$ok, at ret);
print "RECV: " if ($verbose);
while (1) {
$ret=sysread($serial,$buf,1);
$str=sprintf("0x%2.2X", ord($buf));
# busy wait bad!
die ("Error ($str)\n") if (time() - $starttime > 8);
next if $str eq "0x00";
if ($pkt_decode{$str}) {
print $str if ($verbose);
print "[$pkt_decode{$str}] " if ($verbose);
} else {
$_=$str; s/^0x//g; $_=hex($_);
printf("$str(%3.3s) ",$_) if ($verbose);
push (@ret,$_);
}
$ok=1 if ($terminal{$str} > 0);
last if ($terminal{$str});
last if ($last eq "0xFB" && $str eq "0xFB");
$last=$str;
}
print "\n\n" if ($verbose);
return @ret if ($ok);
return undef;
}
sub init_serial {
my($port,$baud)=@_;
my($termios,$cflag,$lflag,$iflag,$oflag);
my($voice);
my $serial=new FileHandle("+>$port") || die "Could not open $port:
$!\n";
$termios = POSIX::Termios->new();
$termios->getattr($serial->fileno()) || die "getattr: $!\n";
$cflag= 0 | CS8 | HUPCL | CREAD | CLOCAL;
$lflag= 0;
$iflag= 0 | IGNBRK | IGNPAR | IXON | IXOFF;
$oflag= 0;
$termios->setcflag($cflag);
$termios->setlflag($lflag);
$termios->setiflag($iflag);
$termios->setoflag($oflag);
$termios->setattr($serial->fileno(),TCSANOW) || die "setattr: $!\n";
eval qq[
\$termios->setospeed(POSIX::B$baud) || die "setospeed:
\$!\n";
\$termios->setispeed(POSIX::B$baud) || die "setispeed:
\$!\n";
];
die $@ if $@;
$termios->setattr($serial->fileno(),TCSANOW) || die "setattr: $!\n";
# This gets rid of all the special characters..
$termios->getattr($serial->fileno()) || die "getattr: $!\n";
for (0..NCCS) {
if ($_ == NCCS) { last; }
# Dont mess up XON/XOFF..
if ($_ == VSTART || $_ == VSTOP) { next; }
$termios->setcc($_,0);
}
$termios->setattr($serial->fileno(),TCSANOW) || die "setattr: $!\n";
return $serial;
}
----------------- snip here too ------------------
More information about the mythtv-users
mailing list