#!/bin/env python # This python script can be used to change the channel # of a RCA DirecTV satellite receiver. I have # personally used it with my RCA that has a # "low speed" dataport on the back. # # Use this script "AS IS". I make NO garantees. # If you fry your system, don't blame me. # # The tech control information needed to create this script # was taken from http://www.pcmx.net/dtvcon/cmds.htm # # This script requires pyserial (pyserial.sf.net) # # Run as "./channel.py 296" # # Version 0.3 by Barry Grussling (webmaster@barrygrussling.com) # # Changelog # # version 0.3 # Fixed Hex convert bug that made it impossilbe to goto channel 269. # Rewrite of hex convert function. # Added on/off abilities # Other Various fixes # # version 0.2 # Added check for pyserial, print message if it is not found. # # version 0.1 # Initial release import os, sys, math, struct, string, re, time # -- User Configuration #Specify your serial port that is hooked to the RCA receiver here Port = "/dev/ttyS0" # -- End User Configuration try: import serial except ImportError: print "You must have python serial installed to use this script" print "see http://pyserial.sourceforge.net" sys.exit(1) ser = serial.Serial(Port, 9600, timeout=1) channelfilter = re.compile('\d+') RCODES = {\ '0xf0': 'Valid command received',\ '0xf1': 'Invalid command received',\ '0xf2': 'Command is being processed',\ '0xf3': 'Timeout waiting for complete command',\ '0xf4': 'Command has completed successfully',\ '0xf5': 'Command has failed',\ '0xfb': 'Illegal character received',\ '0xfd': 'Buffer underflow',\ '0xff': 'Buffer overflow'} SCODES = {\ 'Off': '0xfa01',\ 'On': '0xfa02',\ 'SetChannel': '0xfa46'} Want = {\ 'Verbose': 0, \ 'Help': 0,\ 'NoAutoOn': 0,\ 'Off': 0,\ 'Chan': 0} NEEDDATA = '0xf0' DATAGOOD = '0xf4' SENDLIMIT = 25 for arg in sys.argv: if arg == "-v": Want['Verbose'] = 1 elif arg == "-h": Want['Help'] = 1 elif arg == "-noautoon": Want['NoAutoOn'] = 1 elif arg == "-off": Want['Off'] = 1 elif channelfilter.match(arg): Want['Chan'] = 1 nchannel = arg if Want['Verbose']: for a, b in Want.items(): print a + ":", b print "NChannel:", nchannel def PrintHelp(): print "Usage:", sys.argv[0], "[-v] [-h] [-noautoon] [-off] [channel]" print "\nOPTIONS:" print "-v: Verbose" print "-h: Help and Usage" print "-noautoon: Don't automatically turn receiver on" print "-off: Turn receiver off (channel not needed/omitted)\n\n" sys.exit(2) def SendCommand(command): global nchannel, SCODES if SCODES.has_key(command): sending = SCODES[command] else: sending = command if command == 'SetChannel': sending = '0xfa46' + string.split(str(hex(int(nchannel))),'x')[1].zfill(4) if Want['Verbose']: print "Sending command", sending, "due to requested command", command SendTillGet(sending, DATAGOOD) def SendTillGet(send, need): global RCODES sendtry = 0 rdata = '' Changed = 0 while(Changed == 0 ): if Want['Verbose']: print "Sending:", send, "Until we receive", need, "(Try", sendtry, "out of", str(SENDLIMIT) + ")" ser.write(struct.pack('>i', eval(send))) s = ser.read(70) if len(s) == 0: rdata = "NULL DATA" else: rdata = [hex(ord(k)) for k in s] for a in rdata: if a == need: Changed = 1 if Want['Verbose']: print "Received", a, if RCODES.has_key(a): print "(" + RCODES[a] + ")" else: print "" sendtry=sendtry+1 if(sendtry == SENDLIMIT): print "Too Many Send Tries without valid responce" sendtry = 0 # If we get here, rdata must have done what we wanted... if Want['Verbose']: print "Success" if Want['Help']: PrintHelp() if len(sys.argv)==1: PrintHelp() if Want['Off']: SendCommand('Off') sys.exit(0) if not Want['NoAutoOn']: SendCommand('On') if Want['Chan']: SendCommand('SetChannel') #ser = serial.Serial(Port, 9600, timeout=1) #rdata = ["0xf2"] #[hex(ord(k)) for k in s] # s = ser.read(5) ser.close()