/* $Id: sprinkle.c,v 1.1 2004/12/29 00:27:21 grog Exp $ */
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <syslog.h>
#include <unistd.h>
#ifdef __FreeBSD__
/* PPI interface */
#include <dev/ppbus/ppi.h>
#include <dev/ppbus/ppbconf.h>
#endif

int relayfd;						    /* relay port */

/*
 * Open relay line.
 * Return 1 on failure.
 */
int openrelayline (char *relayline)
{
  if (relayfd)
    close (relayfd);

  /* Now open the files.  */
  relayfd = open (relayline, O_WRONLY);
  if (relayfd < 0)
    {
    fprintf (stderr,
             "Can't open relay controller %s: %s (%d)\n",
             relayline,
             strerror (errno),
             errno );
    return 1;
    }
  return 0;
  }

/* Talk to the relay board */
void setrelay (int bits)
{
#ifdef __FreeBSD__
  ioctl (relayfd, PPISDATA, &bits);                         /* just output the bits */
#else
  /* This kludge to work around potential endianness problems */
  char cbits [8];

  cbits [0] = bits;                                         /* only last byte */

  if (write (relayfd, cbits, 1) < 1)
    fprintf (stderr,
             "Can't write to relay board: %s (%d)\n",
             strerror (errno),
             errno );
#endif
  }

/* $0 relayline valve valve ... */
int main (int argc, char *argv [])
{
  int i;
  int duration;

  if (argc < 3)						    /* no relay line, can't continue */
    {
    /* Too little to do anything.  Give up. */
    syslog (LOG_ERR,
	    "Insufficient parameters to do anything: %d (must be at least 2)\n",
	    argc - 1 );
    exit (1);
    }
  if (argc > 9)
    {
    /*
     * Invalid number of valves.  We'll do what we can anyway.
     *
     * We have 8 relays, but the eighth (bit 0x80) is for the pump, so
     * we can only support 7 valves.
     */
    syslog (LOG_WARNING,
	    "Too many valves: %d (must be between 1 and 7)\n",
	    argc - 2 );
    argc = 9;
    }
  if (openrelayline (argv [1]))				    /* can't open relay */
    {
    /* Too little to do anything.  Give up. */
    syslog (LOG_ERR,
	    "Can't open relay line %s: %s (%d)\n",
	    argv [1],
	    strerror (errno),
	    errno );
    exit (1);
    }
  for (i = 2; i < argc; i++)				    /* each valve */
    {
    duration = atoi (argv [i]) * 60;			    /* duration in seconds */

    if (duration)
      {
      setrelay ((1 << (i - 2)) | 0x80);
      sleep (duration);
      }
    }
  setrelay (0);						    /* all off now, including pump */
  return 0;
  }
