#!/bin/bash # # gentuner.GCACHE # GenericTunerPlugin Connector to control Global Cache IR controllers # See gentuner.README for details on gentuner # # This script proxies commands from the Generic Tuner Plugin # to a GC IP2IR controller (should work for any GC device using API). # There are 3 IR ports that can be mapped for up to 3 STB tuners. Use # the controller web page to make sure each port is set for 'IR Out'. # # You must change the IP address below to indicate your particular # GC device. The GC family uses a unique IR encoding scheme. Check # their web site for help in translating your own device. This example is # for the ATT Uverse command set. The OK command is included so that you # can call this script from CRON to simulate the STB KeepAlive process. # if [ $# = 0 ] #error out if no command line then exit 32 fi gcipaddr='192.168.1.17/4998' #address and port of GC controller (might want to reserve in your DHCP server to prevent drift) delay=.2 #delay for Uverse to accept IR input lockfile=/tmp/gcachelock #if simultaneous calls (i.e. keepalive and sage tune cmd) then let one finish first # socket routine to transact command with controller transact () { exec 3<>/dev/tcp/$gcipaddr retmsg="" printf "$1\r" >&3 #bytewise pipe while IFS= read -N 1 byte <&3 do retmsg="$retmsg$byte" if [[ $byte =~ $'\r' ]]; then break; fi done sleep $delay if [ "${retmsg:0:3}" = "ERR" ] then return 0 else return 4 fi } #lower case for consistency cmd="$(echo $1 | tr '[A-Z]' '[a-z]')" remote="$(echo $2 | tr '[A-Z]' '[a-z]')" channel="$(echo $3 | tr '[A-Z]' '[a-z]')" declare -A tuners #enter the STBs for your installation tuners=([uverse1]=0 [uverse2]=1 [uverse3]=2) declare -A remoteCmd #add any extra keys here, place IR codes starting in 11th position in IRCode array remoteCmd=([ok]=10 [enter]=11) IRPort=('sendir,2:1' 'sendir,2:2' 'sendir,2:3') #GC command for each IR port (make sure they are set as IR Out in controller web page) IRPreamble=',1,36000,3,1,15,10,6,10,6,22,6,10,6,28,6,16,6,10,6,10,6,10,6,22,6,22,6,16,6,22,6,' # codes for 0-9, ok, enter. add any new IR codes for any new keys you put in remoteCmd at the end IRCode=('10,6,10,6,10,6,10' '10,6,10,6,10,6,16' '10,6,10,6,10,6,22' '10,6,10,6,10,6,28' '10,6,10,6,16,6,10' '10,6,10,6,16,6,16' '10,6,10,6,16,6,22' '10,6,10,6,16,6,28' '10,6,10,6,22,6,10' '10,6,10,6,22,6,16' '16,6,16,6,28,6,10' '28,6,22,6,10,6,16') IRPost=',6,3100' if [ "$cmd" = "remotes" ] then for i in "${!tuners[@]}" do echo $i done elif [ "$cmd" = "keys" ] then for i in 1 2 3 4 5 6 7 8 9 0 "${!remoteCmd[@]}" do echo $i done elif [ "$cmd" = "send" -o "$cmd" = "tune" ] #matters not which command received. send is the single unit case of tune. then SECONDS=0 while [ -f $lockfile ] do #echo "Waiting for lock" sleep $delay if ((SECONDS > 5)); then rm $lockfile; fi #brute force after 5 secs done touch $lockfile exitcode=0 if [ ${tuners[$remote]} <> " " ] #sanity check in case called outside sagetv then IRTuner=${IRPort[${tuners[$remote]}]} if [[ $channel =~ ^[0-9]+$ ]] #test for channel number or key command then #channel number for ((i=0; i<${#channel}; i++)) #iterate through each digit do IRString=$IRTuner$IRPreamble${IRCode[${channel:$i:1}]}$IRPost if (transact "$IRString"); then exitcode=16; fi #fail on error return done IRString=$IRTuner$IRPreamble${IRCode[${remoteCmd["ok"]}]}$IRPost if (transact "$IRString"); then exitcode=16; fi #fail on error return elif [ ${remoteCmd[$channel]} <> " " ] #sanity check if key command is in our list then IRString=$IRTuner$IRPreamble${IRCode[${remoteCmd[$channel]}]}$IRPost if (transact "$IRString"); then exitcode=16; fi #fail on error return else exitcode=8 fi else exitcode=4 fi rm $lockfile exit $exitcode elif [ "$cmd" = "can_tune" ] then echo "YES" else exit 1 fi