[mythtv-users] Re: add skybox to my MythTV system
Neil Bird
neil at fnxweb.com
Tue Aug 9 11:09:12 UTC 2005
Around about 09/08/05 02:29, Craig Tinson typed ...
> I use redeye serial too.. but with a *very* simple one line bash
> script.. would be interested in what you've done with redeye.c and the
> script too..
Okey-doke. I make no pretention that I'm the original author/modifier!
The 'digibox.c' [née red_eye.c] and its Makefile I purloined from somewhere
and then fine-tuned to speed it up (near-instant channel changes now).
The skychannel bash script (which does the deed from Myth & uses digibox)
is pretty much my own, but with some file-locking thrown in. I did purloin
the file locking originally, but I think I completely re-wrote the mechanism
after a while.
usage: skychannel <channum> [100 <= channum <= 999]
Copes with turning on the digibox if its off, and also (as it's once
happened to me while I was hammering another remote at the exact same time the
script ran) tries turning it on a second time in case the first power-on got
missed.
Also blats the zap-banner upon channel change (as Myth provides one).
[don't forget Sky now has a setup option to timeout the little red dot
interactive logo things]
Also hangs about for a little over 4 hours and turns the box off (unless
called again in the meantime) to 'reduce' power and ensure the box gets resets
to cope with S/W updates, etc. It's a timeout as I couldn't easily tell when
progs. finished and deserved a power-off. 4 hours seemed enough (if you think
you'll record individual progs. longer that that, change the timeout).
--
[neil at fnx ~]# rm -f .signature
[neil at fnx ~]# ls -l .signature
ls: .signature: No such file or directory
[neil at fnx ~]# exit
-------------- next part --------------
#include <unistd.h>
#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <asm/ioctls.h>
#include <asm/termios.h> /* POSIX terminal control definitions */
#include <time.h>
#ifndef COM_PORT
# define COM_PORT "/dev/ttyS0"
#endif
#ifndef WAIT_TIME
# define WAIT_TIME 2
#endif
#ifndef DEBUG
# define DEBUG 0
#endif
static int debug = DEBUG;
/* the "RTS" line is actually the DTR line in linux */
#ifdef linux
# define BIT_TO_TWIDDLE TIOCM_DTR
#else
# define BIT_TO_TWIDDLE TIOCM_RTS
#endif
/*
* open_port() - Open serial port
* returns the file descriptor on success or -1 on error
*/
int open_port(char *com_port)
{
int fd; /* file descriptor for the port */
struct termios options;
fd = open (com_port, O_WRONLY | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
/* Could not open the port. */
perror ("open_port(): unable to open com port");
exit (-1);
}
else
{
fcntl (fd, F_SETFL, 0);
}
/* get the current options for the port */
tcgetattr (fd, &options);
/* Set the baud rates to 9600 */
cfsetispeed (&options, B9600);
cfsetospeed (&options, B9600);
/* enable the receiver and set local mode */
options.c_cflag |= (CLOCAL);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~CREAD;
options.c_cflag &= ~CRTSCTS;
options.c_iflag &= ~(IXON | IXOFF | IXANY);
/* set the new options for the port */
tcsetattr (fd, TCSANOW, &options);
return (fd);
}
void set_rts(int fd)
{
int status;
int bitset = BIT_TO_TWIDDLE;
ioctl (fd, TIOCMGET, &status);
if (debug)
{
if (status & bitset)
{
printf("RTS bit is set\n");
}
else
{
printf("RTS bit is unset\n");
}
}
status |= bitset;
ioctl (fd, TIOCMSET, &status);
ioctl (fd, TIOCMGET, &status);
if (status & bitset)
{
if (debug) printf("RTS bit set ok\n");
}
else
{
perror("set_rts(): failed to set RTS bit");
exit(-1);
}
}
int main (int argc, char **argv)
{
int fd;
char *com_port = COM_PORT;
int n;
char *data;
int wait_time = WAIT_TIME;
if (argc == 1 || argc > 4)
{
printf("usage: digibox codestring [waittime [device]]\n");
return -1;
}
data = argv[1];
if (argc > 2)
wait_time = atoi(argv[2]);
if (argc > 3)
com_port = argv[3];
if (debug) printf("opening port for %s and setting RTS\n", com_port);
fd = open_port(com_port);
set_rts (fd);
/* needed to power up the IR system */
{
int done = 0;
struct timespec poweruptime;
poweruptime.tv_sec = 0;
poweruptime.tv_nsec = 20000000;
while (!done)
{
int status = nanosleep(&poweruptime,&poweruptime);
if (status == 0)
{
done = 1;
}
else if (status == -1)
{
if (errno != EINTR)
{
sleep(1);
done = 1;
}
}
}
}
if (debug) printf("writing data (\"%s\") now\n",data);
n = write (fd, data, strlen (data));
if (n < 0)
{
perror("main(): write failed");
exit(-1);
}
if (debug) printf("data written\n");
tcdrain (fd);
if (wait_time > 0)
{
if (debug) printf("sleeping for %d seconds\n",wait_time);
sleep (wait_time);
}
if (debug) printf("start close\n");
close (fd);
if (debug) printf("finished\n");
return 0;
}
-------------- next part --------------
#
# Makefile to build digibox interface
#
#
# where to install binary
#
INSTALLDIR=/usr/local/bin
#
# which serial port the device is connected to
#
COM_PORT=\"/dev/ttyS0\"
#
# seconds to wait after sending the command before finishing
# see comment about about milliseconds
#
WAIT_TIME=2
#
# this should be fairly obvious!
# do you want debugging output
# 0=none, 1=some
#
DEBUG=0
CFLAGS=-DCOM_PORT=${COM_PORT} -DWAIT_TIME=${WAIT_TIME} -DDEBUG=${DEBUG}
all: digibox
digibox: digibox.o
cc -o digibox digibox.o
install: digibox
install digibox ${INSTALLDIR}
clean:
rm digibox.o
-------------- next part --------------
#!/bin/bash
# Debug
##exec 1>/tmp/skychannel.dbg
##exec 2>&1
##set -x -v
##chmod a+rw /tmp/skychannel
# Locking functions
LOCKFILE=/tmp/skychannel.lock
function locksc() {
if lockfile -1 -r 10 $LOCKFILE >/dev/null 2>&1; then
return 0
else
exit 1
fi
}
function unlocksc() {
rm -f $LOCKFILE >/dev/null 2>&1;
}
# Exit if no args.
[ -z "$1" ] && exit 1
# Jump into b/g for Myth
(
subpid=$!
STAT=/tmp/skychannel
PATH=${PATH}:/usr/local/bin
# Turn off?
if [ "$1" = "off" ]; then
# Wait 4 mins., then find out time
sleep $((4*30))
now=`date '+%s'`
# Get last channel-change
locksc
. $STAT
echo "$2" > /tmp/skychannel-off
# Is it more than 25 mins, ago?
# TBD
unlocksc
# Cope with Sky channels
elif [ $1 -ge 100 -a $1 -lt 1000 ]; then
# Break down channel digits
channel=`printf '%03d' $1`
chno=$channel
d1=$((chno/100))
chno=$(( chno-(d1*100) ))
d2=$((chno/10))
chno=$(( chno-(d2*10) ))
d3=$chno
# Assert ownership
locksc
[ -f $STAT ] && . $STAT
echo -e "SCPID=$subpid\nSCCHAN=$channel\nSCTIME=`date '+%s'`" > $STAT
# Kill previous script
[ "$SCPID" != "" -a -d /proc/$SCPID ] && kill -9 $SCPID >/dev/null 2>&1
# Change channel, or power up
digibox "${d1}${d2}${d3}KT"
unlocksc
# Wait a bit then check to see if we've been called since
sleep 1
locksc
. $STAT
# Called again since?
if [ $SCPID -ne $subpid ]; then
# Yep; abort
unlocksc
exit 0
fi
# Nope, our channel still stands (also try powering up again just in case last code got missed)
digibox "K${d1}${d2}${d3}KT"
unlocksc
# Wait a bit more then check to see if we've been called since
sleep 5
locksc
. $STAT
# Called again since?
if [ $SCPID -ne $subpid ]; then
# Yep; abort
unlocksc
exit 0
fi
# Nope, our channel still stands
digibox "K${d1}${d2}${d3}K"
unlocksc
# Turn off in 4:05
sleep $((4*60*60+5*60))
locksc
. $STAT
# Called again since?
if [ $SCPID -eq $subpid ]; then
# Nope; turn off box (4 s. sequence)
digibox 'T!!!!K!!!!P' 4
fi
unlocksc
fi
) &
# vim: set et sts=4 ts=4 sw=4 ai :
More information about the mythtv-users
mailing list