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; } _______________________________________________ mythtv-users mailing list [email protected] http://mythtv.org/cgi-bin/mailman/listinfo/mythtv-users
