On Wednesday 16 November 2005 17:32, Robert Denier wrote: > I'm going to use the format [----FILENAME----] and then paste the file. > The only change to the perl script was just an edit to make it find the > file easier. Perhaps it wasn't even needed. I have everything in > /usr/local/bin. To use these you will need to copy paste these into files > and make the scripts executable. Myth calls the change_channel scripts. > > [Don't forget the alternate keys are for receiver remote code 2. This is > settable on the receiver, or at least the ones I have.] > > -Robert Denier > > [---/usr/local/bin/change_channel.sh---] > #!/bin/bash > perl /usr/local/bin/MyBlaster.pl $1 > > [---/usr/local/bin/change_channel2.sh---] > #!/bin/bash > cd /usr/local/bin > perl /usr/local/bin/MyBlaster.pl changechannel d2.keys $1 > > [---/usr/local/bin/d2.keys---] > power = 00001B008B0300C70C1700C7058900BE0354010091111121211111111100 > select = 00001B008C0300C90C1500C9058700C00352010091121111211111111100 > exit = 00001B008C0300C90C1400C9058600C00357010091121121211111111100 > 0 = 00001B008C0300C90C1400C9058700C00354010091121112211111111100 > 1 = 00001B008C0300C90C1500C9058700C00354010091111211211111111100 > 2 = 00001B008C0300C90C1400C9058700C00354010091111212211111111100 > 3 = 00001B008C0300C90C1400C9058700C00356010091111221211111111100 > 4 = 00001B008C0300C90C1500C9058700C9034A010091112111211111111100 > 5 = 00001B008C0300C90C1400C9058600C9034E010091112112211111111100 > 6 = 00001B008C0300C90C1400C9058600C90351010091112121211111111100 > 7 = 00001B008C0300C90C1400C9058700C9034D021091112211211111111100 > 8 = 00001B008C0300C90C1400C9058700C9034C010091112212211111111100 > 9 = 00001B008C0300C90C1400C9058700C9034C010091112221211111111100 > > [---/usr/local/bin/MyBlaster.pl---] > #!/usr/bin/perl > > # MyBlaster.pl: Controller for the MyBlaster serial IR blaster > (www.mytvstore.com) > # By William Munson [wmunson] (July 26, 2004, ver-1.4) > # > # This code is being released into the public domain for non-profit use. > # For commercial use please contact me at our support forum: > # http://www.mythtvtalk.com/forum/viewtopic.php?p=622#622 > # > # Version 1.0 - Initial release of code. > # Version 1.1 - Added macro feature. > # Version 1.2 - Fixed some timing issues in the data transfer to MyBlaster. > # Version 1.3 - Fixed output for devices other than DSS/Satellite > receivers. # - Added support for port locking which keeps a > second instance # suspended until the 1st has completed. > # Version 1.4 - Public Release #1 - Updated documentation for release. > # Version 1.4.1 - Added Learing and emitting learned keys - Vlado > > > $|=1; > use POSIX qw(:termios_h); > use FileHandle; > use Time::HiRes qw( sleep ); > > > # Defaults to standard COM2 port, 19200 baud. > my $serial=init_serial("/dev/ttyS0","19200"); # Com 1 > # my $serial=init_serial("/dev/ttyS1","19200"); # Com 2 > > # Device code for the piece of equipment you want to control. This info can > # be found in the MyBlaster Library folder. > # > # 775 controls a standard Dishnet receiver. > $remote_code="775"; > > # Device Type is a hex value from 0 to A and represents the type of device > you # want to control. Below is a list of the available device type codes. > # 0=TV, 1=CABLE, 2=Video Acc, 3=DSS/Satellite, 4-VCR, 5=Laser Disk, 6=DVD # > 7=Tuner/Amp, 8=Amplifier, 9=CD, A=Home Control > $Device_Type="3"; > > # Duplicate process protection. Enable this if you use the same blaster to > control > # multiple devices. With this enabled, multiple instances of the program > will each > # sleep until the blaster port is free. Uses a lock file. > $Use_Locking=0; > > # Lock File name. > $LockFile="/tmp/MyBlaster.lock"; > > # remote file prefix. The file name will be $prefix_<remote>.keys > $remote_prefix = "/home/mythtv/MyBlaster_"; > > # Use verbose output mode for debugging. > $verbose=0; > > # Time delay between each channel digit. > $inter_key_delay=0.1; > > # Emit time. This is the length of time the command is sent. Probably a > # good idea to leave this alone but if you are getting repeats of buttons > # then you can shorten it a little bit. > $Emit_Time=0.333; > > # Learn Time. This is the length of time we let MyBlaster to try to learn a > command. > $Learn_Time=3.0; > > # Enable to press a key to finalize channel entry > $finalize=1; > > # Key used to finalize channel entry > $finalize_key="select"; > > # Enable to clear the on screen display more quickly. > $quick_clear=1; > > # Key used to clear the display. Taken from keymap below. > $quick_clear_key="exit"; > > # Time to wait until clearing the display > $clear_delay=2.0; > > # Misc variables needed by the program > $Count=0; > > # These keys should be common to all device codes. The remote buttons > # may have different names. Feel free to change the name but not the value. > %keymap=(1 => "0x01", > 2 => "0x02", > 3 => "0x03", > 4 => "0x04", > 5 => "0x05", > 6 => "0x06", > 7 => "0x07", > 8 => "0x08", > 9 => "0x09", > 0 => "0x0a", > vol_up => "0x0b", > vol_dn => "0x0c", > mute => "0x0d", > ch_up => "0x0e", > ch_dn => "0x0f", > power => "0x10", > enter => "0x11", > ch_100 => "0x11", > last_chan => "0x12", > tv_sat => "0x13", > input => "0x13", > play => "0x14", > stop => "0x15", > page_up => "0x16", > ffwd => "0x16", > rew => "0x17", > page_dn => "0x17", > pause => "0x18", > record => "0x19", > menu => "0x1a", > up => "0x1b", > down => "0x1c", > left => "0x1d", > right => "0x1e", > select => "0x1f", > exit => "0x20", > display => "0x21", > guide => "0x22"); > > #config file vars > my %rem_keys; > my @rem_lines; > > > > # Start of main code. > # > # Pull the command line info into the program > $input_cmd=$ARGV[0]; > > if ($Use_Locking) { > if (-e $LockFile) { #found a lock file so sleep > sleep(5.0); > } > open(OUTFILE, ">$LockFile") || die "cannot open file"; # create our > lock file > } > > # These bits define which remote control protocol to use and the device > type. # > # Convert remote code to MyBlaster format > $hex_remote_code = sprintf("%X", $remote_code); > > if ($remote_code > 255) { > $hi_bit="0x" . $Device_Type . substr($hex_remote_code, 0, 1); > $lo_bit="0x" . substr($hex_remote_code, 1, 2); > } else { > $hi_bit="0x" . $Device_Type . "0"; > if ($remote_code > 15) { > $lo_bit="0x" . substr($hex_remote_code, 0, 2); > } else { > $lo_bit="0x0" . substr($hex_remote_code, 0, 1); > } > } > print "hi bit = " if ($verbose); > print $hi_bit if ($verbose); > print "\n" if ($verbose); > print "lo bit = " if ($verbose); > print $lo_bit if ($verbose); > print "\n" if ($verbose); > > > # Start of command decoding > > if (length($input_cmd)) { > # Check to see if a channel number was entered. > if ($input_cmd != 0) { > change_channel($input_cmd); > if ($Use_Locking) { > close(OUTFILE); > unlink($LockFile); > } > exit; > } > if ($input_cmd eq "macro") { > # Do macro command. Use your own key sequence here. > # Change it around as required for your needs. > mb_key("down"); > sleep(1.0); > mb_key("up"); > sleep(1.0); > mb_key("select"); > sleep(1.0); > mb_key("display"); > if ($Use_Locking) { > close(OUTFILE); > unlink($LockFile); > } > exit; > } > # Attempt to learn a command > if ($input_cmd eq "learn") { > $remote = $ARGV[1] || die "No remote name"; > $keyname = $ARGV[2] || die "No key name to learn"; > $keydata = learn_key($keyname); > > # WILL CREATE DUPLICATES and use the first (old one) > open (FH, ">>" . $remote_prefix . $remote . ".keys"); > printf (FH "$keyname = $keydata\n"); > close (FH); > print "$keyname = $keydata\n"; > exit; > } > # Emit learned key (raw or by name) > if ($input_cmd eq "send") { > $key_data = $ARGV[1] || die "No key data\n"; > if (length($key_data) > 29) { #this > should be a raw data - just send it > emit_learned_key ($key_data); > $stat = get_mb_status(); > } > else { > $remote = $key_data; > #this is a remote, and we should have a key name > $key_name = $ARGV[2] || die "No Key name\n"; > $key_data = lookup_key ($remote, $key_name); > emit_learned_key($key_data); > } > exit; > } > if ($input_cmd eq "changechannel") { > $remote = $ARGV[1] || die "No remote specified\n"; > $chan = $ARGV[2] || die "No channel number\n"; > change_channel_learned ($remote, $chan); > exit; > } > # No special processing required. Send a single command. > mb_key($input_cmd); > if ($Use_Locking) { > close(OUTFILE); > unlink($LockFile); > } > } > > # begin subroutines. > > sub emit_learned_key { > $key_data = shift; > my @bytes; > $len = length ($key_data); > die "Invalid key data" if ($len % 2 != 0); #@@@ TODO: check for > non hex symbols with a regexp > $t_len = sprintf("0x%2.2X", 4 + $len / 2); > > @bytes = ("0xBC","0xAC","0x0D","0x00",$t_len,"0x0B","0x00","0x00", > "0x10"); > $i=0; > while ($i < length($key_data) ) { > push (@bytes,"0x" . substr($key_data,$i,2)); > $i++; $i++; > } > print "Will send bytes [EMAIL PROTECTED]" if ($verbose); > > > simple_command("0x00"); #wake up > sleep(0.1); > simple_command(@bytes); > sleep(0.333); > simple_command("0x00"); #wake up > > return; > } > > sub emit_learned_key_byname { > $remote = shift; > $key_name = shift; > > print "elkn $remote/$key_name\n"; > } > > sub learn_key { > my $keyname=shift; > > simple_command("0x00"); #wake up > sleep(0.1); > simple_command("0xBC","0xAC","0x0D","0x00","0x02","0x06","0x01"); > # reset > sleep(0.3); > > print "*** Press and hold '$keyname' on the remote for 5 seconds... > \n"; simple_command("0x00"); #wake up > sleep(0.1); > # send the data packet > > simple_command("0xBC","0xAC","0x0D","0x00","0x03","0x0C","0x00","0x00"); > #learn in buf 0 (always use buf 0) > sleep($Learn_Time); > > $stat = get_mb_status(); > die "Learning failed with status code $stat\n" if ($stat != 0); > simple_command("0x00"); #wake up > sleep(0.1); > > simple_command("0xBC","0xAC","0x0D","0x00","0x03","0x0D","0x00","0x00"); > #read buf 0 (always use buf 0) > sleep(0.1); > $stat = get_mb_status(); > die "Reading learn code failed with status code $stat\n" if ($stat > != 0); > > > $len = get_ser_byte(); > $stat = get_ser_byte(); > $len--; #status was in the length the rest is the key > $count = 0; > $str = ""; > while ($count < $len) { > $b = get_ser_byte(); > $count++; > $str = sprintf("%s%2.2X", $str, $b); > } > print "Learned Key $keyname: $str\n" if ($verbose); > print " Length: $count\n" if ($verbose); > print " (Suspicious = less then 30)\n" if ($verbose && $len < 30); > return $str; > } > > sub get_mb_status { > $ret = get_ser_byte(); # get length > return if ($ret ne 1); > return get_ser_byte(); > } > > sub get_ser_byte { > my $starttime=time(); > print "RECVB: " if ($verbose); > > $size = 0; > while (!$size) { > $size=sysread($serial,$buf,1); > if (time() - $starttime > 5) { > print "time...\n" if ($verbose); > return; > } > next; > } > print ord($buf),"\n" if ($verbose); > return ord($buf); > } > > sub change_channel_learned { > # Send a command for each digit of the channel number > my ($remote) = shift; > my ($channel_num)=shift; > my ($position)=0; > my ($digit)=""; > > 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"; > } > #@@@ look up name > $key_data = lookup_key ($remote, $digit); > emit_learned_key($key_data); > $position++; > sleep($inter_key_delay); > } > # wait a little bit and press enter to finalize channel entry > if ($finalize){ > print "Finalize Entry:\n" if ($verbose); > $key_data = lookup_key ($remote, $finalize_key); > emit_learned_key($key_data); > } > > #If enabled, clear the display after sleeping one second > if ($quick_clear){ > sleep($clear_delay); > print "Clear Display:\n" if ($verbose); > $key_data = lookup_key ($remote, $quick_clear_key); > emit_learned_key($key_data); > } > } > > > sub lookup_key { > $remote = shift; > $key_name = shift; > if (!%rem_keys) { > #read it from the file > print "Reading remote config file > $remote_prefix$remote.keys\n" if ($verbose); > open (FH, $remote); > @rem_lines = <FH>; > foreach $l (@rem_lines) { > chomp($l); > next if ($l =~ /^#/); > next if ($l =~ /^\s*$/); > next if ($l =~ /!=/); > @val = split(/\s*=\s*/, $l); > [EMAIL PROTECTED] = @val[1]; > } > close (FH); > } > $key_data = $rem_keys{$key_name}; > print "$key_name -> $key_data\n" ;#if ($verbose); > return $key_data; > } > > > sub change_channel { > # Send a command for each digit of the channel number > my ($channel_num)[EMAIL PROTECTED]; > my ($position)=0; > my ($digit)=""; > > 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"; > } > mb_key($digit); > $position++; > sleep($inter_key_delay); > } > # wait a little bit and press enter to finalize channel entry > if ($finalize){ > print "Finalize Entry:\n" if ($verbose); > mb_key($finalize_key); > } > > #If enabled, clear the display after sleeping one second > if ($quick_clear){ > sleep($clear_delay); > print "Clear Display:\n" if ($verbose); > mb_key($quick_clear_key); > } > } > > > sub mb_key { > my ($key)[EMAIL PROTECTED]; > my ($Count)=0; > my ($Looping)=1; > return undef unless $keymap{$key}; > simple_command("0x00"); > sleep(0.1); > # send the data packet > simple_command("0xBC","0xAC","0x0D","0x00","0x06","0x01", > $hi_bit,$lo_bit,$keymap{$key},"0x00","0x00"); > sleep($Emit_Time); #Execution delay > simple_command("0x00"); > print "\n" if ($verbose); > get_reply(); > } > > sub simple_command { > if (defined(sendbytes(@_))) { > return(1); > } else { > return(undef); > } > } > > sub mb_command { > sendbytes(@_); > } > > > sub sendbytes { > (@send)[EMAIL PROTECTED]; > foreach (@send) { s/^0x//g; $_=hex($_); } > print "SEND: " if ($verbose); > foreach $num (@send) { > $str=pack('C',$num); > printf("0x%X ", $num, $str) if ($verbose); > syswrite($serial,$str,length($str)); > } > print "\n" if ($verbose); > } > > sub get_reply { > my $starttime=time(); > my ($last,$ok,@ret); > my ($Expected_Count)[EMAIL PROTECTED]; > my ($Count)=0; > print "RECV: " if ($verbose); > > while (1) { > $ret=sysread($serial,$buf,1); > $str=sprintf("0x%2.2X", ord($buf)); > > # busy wait bad! > die ("\n") if (time() - $starttime > 5); > next if $str eq "0x00"; > $Count++; > 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 $str eq "0x31"; > last if $str eq "0x01"; > next; > } > print "\n\n" if ($verbose); > > return @ret if ($ok); > return undef; > } > > > sub init_serial { > my($port,$baud)[EMAIL PROTECTED]; > 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 | IGNCR; > #$iflag= 0 | IGNBRK | IGNPAR | IGNCR; > $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; > } >
You should add a TRAC for inclusion in the contrib folder. Steve _______________________________________________ mythtv-users mailing list [email protected] http://mythtv.org/cgi-bin/mailman/listinfo/mythtv-users
