
 /*                     Filename: twx75.c

70:  combined twfuncx.c and twx69.c and added say(*char).
71:  added various announcements.
74:  added F and M Macros.
75:  changed times.
78:  added K6 (Coffee Pot) and M5 (curlers) on for 30 min. at 6:14 AM
82:  added talk and telephone responder events
               ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
               º     TW523 Control Program      º
               º      for an IBM PC Clone       º
               º      Jonathan M. Chattin       º
               º         Copyright 1993         º
               ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼
*/

#include "conio.h"
#include "string.h"
#include "time.h"
#include "tw523.c"
#include <stdio.h>
#include <process.h>

/* X-10 Functions */                    /* After ANDing with 0xf */

#define All_Units_Off     0x10          /* 0x0 */
#define All_Lights_On     0x18          /* 0x8 */
#define On                0x14          /* 0x4 */
#define Off               0x1c          /* 0xc */
#define Dim               0x12          /* 0x2 */
#define Bright            0x1a          /* 0xa */

/* the following are future X-10 functions (only Hail in TW523 now) */

#define All_Lights_Off    0x16
#define Extended_Code     0x1e
#define Hail_Request      0x11          /* Any TW523's out there? */
#define Hail_Ack          0x19          /* Yes */
#define Extended_Data     0x13
#define Status_On         0x1b
#define Status_Off        0x17
#define Status_Request    0x1f

#define Midnight            24
#define Bedtime             23
#define TimeOut             15
#define LeaveHome            9
#define GetHome             16


#define TRUE    1
#define FALSE   0


static char *portname[8] = { "COM1","COM2","COM3","COM4","LPT1","LPT2","LPT3","
?  " };
static char *seasonname[4] = { "Winter","Spring","Summer","Fall " };

static int sunriset[2][12] = {
{ 6,  6,  6,  6,  6,  5,  5,  5,  6,  6,  6,  6},
{17, 17, 18, 19, 19, 20, 20, 20, 19, 17, 17, 17}  };
/*J   F   M   A   M   J   J   A   S   O   N   D*/

static int FirstDayOff =  6;  /* first Julian date off (start w/0) */
static int DaysInYear    = 365;
static char *dayname[7] = {"Sunday   ","Monday   ","Tuesday  ","Wednesday","Thu
rsday ","Friday   ","Saturday "};
static char *TimeOfDay[3] = {"Day    ","Evening","Night  "};
static char housechar[] = {"ABCDEFGHIJKLMNOP"};
static int SchoolStartDay   = 249;      /* Julian date for Sept 6, 1994 */
static int SchoolEndDay     = 167;       /* Julian date for June 16, 1995 */


int yearindex;
int Status[16][16];             /* House, Unit, Intensity 0-15 */
int ChangeStatus[16][16];
int S1change;
int S2change;
int FirstTimeThru[20];
int FirstBriSent[16][16];
int Emergency   = 0;
int IntruderFlag = 1;
int Intruder    = 0;
int Alarm_On    = 0;
int NoInit      = 0;
int Auto        = 0;
int Color       = 0;
int NotHomeFlag = 0;
int S1change    = 0;
int S2change    = 0;
int J_On_Travel = 0;
int Override    = 0;
int house       = 'A';
int unit        = 1;
int inthouse    = 0;
int intunit     = 1;
int NRaDDayOff  = 0;
int School      = 0;
int Vacation    = 0;
int daytotal    = 0;
int Day         = 0;
int Evening     = 0;
int Night       = 0;
int Home        = 0;
int J_Work      = 0;
int G_Work      = 0;
int Weekday     = 0;
int Sunrise     = 0;
int Sunset      = 0;
int season      = 0;
int CoffeeTime  = 0;
int index       = 1;
int TODindex    = 0;
int houseindex  = 0;
int unitindex   = 0;
int Debug       = 0;
int turn_units_off = 0;
int i;
int key;
int repeat;
int rfunc;
int runfu;
int argindex;
int barindex;
int index;
int portforce = 0;
int unitint;
int selunit;
int intenint;
int AddInten  = 0;
int rhouse = 'A';
int runit = 1;
int retc = 0;
int unitindex;
int Timer[20];

char c, ch, dummy, *ptr;
char hsestr[81];
char IObuffer[1500];  /* ((80cols - 50cols) * 25rows * 2bytes/char) */
char S2buffer[1700];  /* ((50cols) * 17rows * 2bytes/char)  */
char *hcp;                      /* pointer to above */
char *port = "    ";
char *pathnams = "c:\\tc15\\say.exe";
char *pathnamt = "c:\\tc15\\talk.exe";

char *funcmsg[] = {                     /* function messages */
        "All U Off",
        "Hail Req",
        "Dim",
        "Ext Data",
        "On",
        "Preset Dim",
        "All L Off",
        "Stat = Off",
        "All L On",
        "Hail Ack",
        "Bright",
        "Stat = On",
        "Off",
        "Pre-set Dim",
        "Ext Code",
        "Status Req"
        };



time_t curtime;
struct tm *jmctime;

/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³          getjmctime            ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

getjmctime()

{
 curtime = time(&curtime);
 jmctime = localtime(&curtime);
}

/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³         getNRaDDayOff          ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

getNRaDDayOff()
{
 if ((jmctime->tm_yday == FirstDayOff)
 || !((jmctime->tm_yday - FirstDayOff) % 14))
  NRaDDayOff = 1;
 else
  NRaDDayOff = 0;
}

/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³          getSchool             ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

getSchool()
{
  if (!Vacation && ((jmctime->tm_yday < SchoolEndDay) || (jmctime->tm_yday > Sc
hoolStartDay))) School = 1;
  else School = 0;
}


/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³          getWeekday            ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

getWeekday()
{
 if ((jmctime->tm_wday != 0) && (jmctime->tm_wday != 6))
  Weekday = 1;
 else
  Weekday = 0;
}

/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³         getCoffeeTime          ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

getCoffeeTime()
{
 if (Weekday && !NRaDDayOff && J_Work  && !J_On_Travel) CoffeeTime = 5;
 else CoffeeTime = 7;
}


/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³          getsunriset           ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

getsunriset()
{
 Sunrise = sunriset[0][jmctime->tm_mon];
 Sunset =  sunriset[1][jmctime->tm_mon];
 if ((jmctime->tm_mon >= 11) || (jmctime->tm_mon < 2)) season = 0;      /* Wint
er */
 else if ((jmctime->tm_mon >= 2) && (jmctime->tm_mon < 5)) season = 1;  /* Spri
ng */
 else if ((jmctime->tm_mon >= 5) && (jmctime->tm_mon < 8)) season = 2; /* Summe
r */
 else season = 3;                                                       /* Fall
 */
}

/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³             getTOD             ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

getTOD()

{
 if (jmctime->tm_hour == 0)
 {
  if (jmctime->tm_mday == 0) getsunriset();
  getSchool();
  getNRaDDayOff();
  getWeekday();
  getCoffeeTime();
  S1change = 1;
 }
 if ((jmctime->tm_hour >= Sunrise) && (jmctime->tm_hour < Sunset))
 {
  Day = 1;
  Night = 0;
  Evening = 0;
  TODindex = 0;
  S1change = 1;
 }
 else if ((jmctime->tm_hour >= Sunset) && (jmctime->tm_hour < Bedtime))
 {
  Day = 0;
  Evening = 1;
  Night = 0;
  TODindex = 1;
  S1change = 1;
 }
 else
 {
  Day = 0;
  Evening = 0;
  Night = 1;
  TODindex = 2;
  S1change = 1;
 }
}
/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³        spawnout(int val)       ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

spawnout(int val)    /* used with spawn */
   {
    if (val == -1)
    {
     cprintf("failed child start\n");
     gettext(51,1,80,25,IObuffer);
    }
    else if (val > 0)
    {
     cprintf("child died abnormally\n");
     gettext(51,1,80,25,IObuffer);
    }
   }

/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³        say(char *msg)          ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/
say(char *msg)
{
 house = 'J';
 unit = 6;
 DoFunc(On);
 gettext(51,1,80,25,IObuffer);
 spawnout(spawnl(P_WAIT, pathnams, "say.exe", msg, NULL));
 InitScreen();
 puttext(51,1,80,25,IObuffer);
 DoFunc(Off);
}

/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³        talk(char *msg)         ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/
talk(char *msg)
{
 house = 'J';
 unit = 6;
 DoFunc(On);
 gettext(51,1,80,25,IObuffer);
 spawnout(spawnl(P_WAIT, pathnamt, "talk.exe", msg, NULL));
 InitScreen();
 puttext(51,1,80,25,IObuffer);
 DoFunc(Off);
}

/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³        WriteStatusFile()       ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/
WriteStatusFile()
{
 int anyon;
 char temphouse[2];
 char tempunit[3];
 char statbuff[256];
 FILE *statf;

 temphouse[1] = 0;
 statf = fopen("status.txt", "w");
 fputs("The following modules are on,", statf);
 for (houseindex = 0; houseindex < 16; houseindex++)
 {
  anyon = 0;
  temphouse[0] = 0;
  for (i = 0; i < 256; i++) statbuff[i] = 0;
  for (unitindex = 0; unitindex < 16; unitindex++)
   if (Status[houseindex][unitindex] != 0) anyon = 1;
  if (anyon)
  {
   fputc('\n', statf);
   temphouse[0] = houseindex + 'A';
   strcat(statbuff, temphouse);
  }
  for (unitindex = 0; unitindex < 16; unitindex++)
  {
   if (Status[houseindex][unitindex] != 0)
   {
    strcat(statbuff, " ");
    sprintf(tempunit, "%d", 1 + unitindex);
    strcat(statbuff, tempunit);
   }
  }
   fputs(statbuff, statf);
 }
 fclose(statf);
}


/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³        EverythingOff()         ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

EverythingOff()
{
 hcp = housechar;                 /* beginning of house chars */
 while(*hcp)
 {
  house = *hcp;
  gotoxy(1, 25);
  DoFunc(All_Units_Off);
  ++hcp;
 }
}


/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³        DoFunc(int func)        ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

DoFunc(int func)                        /* xmit an x10 command */
{
 int unitindex, thouse, tunit;
 getjmctime();
 gotoxy(1,25);
 cprintf("%02d:%02d:%02d ", jmctime->tm_hour, jmctime->tm_min, jmctime->tm_sec)
;
 cprintf("XMIT:%c-%d ", house, unit);
 cprintf("%s\n", funcmsg[func & 0xf]);
 inthouse = house - 'A';
 intunit = unit - 1;
 thouse = tbltx[inthouse];
 tunit  = tbltx[intunit];

 if (Debug) delay(750);

 if ((func == Dim) && (Status[inthouse][intunit] > 0))
 {
  if (!Debug)
  {
   sendx10(thouse, tunit);
   sendx10(thouse, func);
  }
  if (!FirstBriSent[inthouse][intunit])
  {
   Status[inthouse][intunit] = 15;
   ChangeStatus[inthouse][intunit] = 1;
   FirstBriSent[inthouse][intunit]= 1;
  }
  else
  {
   Status[inthouse][intunit]--;
   ChangeStatus[inthouse][intunit] = 1;
  }
 }

  if ((func == Bright) && (Status[inthouse][intunit] < 15))
  {
   if (!Debug)
   {
    sendx10(thouse, tunit);
    sendx10(thouse, func);
   }
   if (!FirstBriSent[inthouse][intunit])
   {
    Status[inthouse][intunit] = 15;
    ChangeStatus[inthouse][intunit] = 1;
    FirstBriSent[inthouse][intunit]= 1;
   }
   else
   {
    Status[inthouse][intunit]++;
    ChangeStatus[inthouse][intunit] = 1;
   }
  }

  if ((func == On) && (Status[inthouse][intunit] > 0) && (Status[inthouse][intu
nit] < 16))
  {
   if (!Debug) sendx10(thouse, tunit);                  /* select device */
   if (!Debug) sendx10(thouse, Off);                    /* Reset Dimmer */
   if (!Debug) sendx10(thouse, tunit);                  /* select device */
   if (!Debug) sendx10(thouse, func);                   /* perform function */
   Status[inthouse][intunit] = 15;
   ChangeStatus[inthouse][intunit] = 1;
   FirstBriSent[inthouse][intunit]= 1;
  }

  else if ((func != Bright) && (func != Dim))   /* not Bright and not Dim */
  {
   if (!Debug) sendx10(thouse, tunit);                  /* select device */
   if (!Debug) sendx10(thouse, func);                   /* perform function */
  }

 if (func == Off)
 {
  Status[inthouse][intunit] = 0;
  ChangeStatus[inthouse][intunit] = 1;
  FirstBriSent[inthouse][intunit]= 0;
 }

 if (func == On)
 {
  Status[inthouse][intunit] = 15;
  ChangeStatus[inthouse][intunit] = 1;
  FirstBriSent[inthouse][intunit]= 1;
 }

 if (func == All_Units_Off)
  for (unitindex = 0; unitindex < 16; unitindex++)
  {
   Status[inthouse][unitindex] = 0;
   ChangeStatus[inthouse][unitindex] = 1;
   FirstBriSent[inthouse][unitindex]= 0;
  }

 if (func == All_Lights_On)
  for (unitindex = 0; unitindex < 16; unitindex++)
  {
   Status[inthouse][unitindex] = 15;
   ChangeStatus[inthouse][unitindex] = 1;
   FirstBriSent[inthouse][unitindex]= 1;
  }
  S2change = 1;
}

/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³      Intensity(int inten)      ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

Intensity(int inten)
{
 while (Status[inthouse][intunit] != inten)
 {
  if (Status[inthouse][intunit] > inten) DoFunc(Dim);
  if (Status[inthouse][intunit] < inten) DoFunc(Bright);
 }
}
/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³          Reset_Hall()          ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

Reset_Hall()
{
 if (Evening || Night)
 {
  house = 'H';
  unit = 4;
  DoFunc(Off);
  Intensity(9);
  FirstTimeThru[4] = 1;
 }
}
/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³         Reset_Outside()        ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

Reset_Outside()
{
 house = 'O';
 for (unit = 1; unit < 4; unit++)
 {
  DoFunc(Off);
  DoFunc(On);
 }
 if (!Home)
 {
  unit = 4;
  DoFunc(Off);
  Intensity(9);
 }
 FirstTimeThru[5] = 1;
}

/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³           initest()            ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

int initest()
{
 int i;
 gotoxy(1, 25);
 cprintf("\nScanning Ports for TW523");
 for(i = 0; i < 7; i++)
 {
  if(!tw523ok(i))
  {
   index = i;
   strcpy(port, portname[i]);
   cprintf("\nTW523 Responding\n");
   return(0);
  }
 }
    index = -1;
    cprintf("\nTW523 Not Working\n");
    return(1);                          /* oops bad port */
}



/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³             Menu1              ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

menu1()
   {
    window(1,1,49,5);
    if (Color) textattr(31);
    clrscr();
    cprintf(  " A - Automatic S - Sel Addr R - Restore Settings");
    cprintf("\n F - Unit Off  D - Dim      U - All Units Off   ");
    cprintf("\n N - Unit On   B - Bright   L - All Lights On   ");
    cprintf("\n T - Travel    X - All Off  H - Home V- Vacation");
    cprintf("\n I - Intensity J,G - Work   O - Off Every 15 Min");
   }
/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³            Status1             ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

   Status1()
   {
    window(1,6,49,7);
    if (Color) textattr(47);
    else textattr(15);
    clrscr();
    cprintf(" %s rise=%d set=%d %d-%d-%d %s %s", seasonname[season], Sunrise, S
unset, jmctime->tm_mon+1, jmctime->tm_mday , jmctime->tm_year, dayname[jmctime-
>tm_wday], TimeOfDay[TODindex]);
    cprintf("\n %s %c-%2d ",port, house, unit);

    if (!Auto)
    {
     if (Color) textattr(40);
     else textattr(10);
    }
    cprintf(" Auto");
    if (Color) textattr(47);
    else textattr(15);

    if (!Home)
    {
     if (Color) textattr(40);
     else textattr(10);
    }
    cprintf(" Home");
    if (Color) textattr(47);
    else textattr(15);


    if (!J_On_Travel)
    {
     if (Color) textattr(40);
     else textattr(10);
    }
    cprintf(" Travel");
    if (Color) textattr(47);
    else textattr(15);

    if (!Weekday)
    {
     if (Color) textattr(40);
     else textattr(10);
    }
    cprintf(" Wkdy");
    if (Color) textattr(47);
    else textattr(15);

    if (!School)
    {
     if (Color) textattr(40);
     else textattr(10);
    }
    cprintf(" Sch");
    if (Color) textattr(47);
    else textattr(15);

    if (!Vacation)
    {
     if (Color) textattr(40);
     else textattr(10);
    }
    cprintf(" Vac");
    if (Color) textattr(47);
    else textattr(15);

    if (!turn_units_off)
    {
     if (Color) textattr(40);
     else textattr(10);
    }
    cprintf(" O");
    if (Color) textattr(47);
    else textattr(15);

    if (!G_Work)
    {
     if (Color) textattr(40);
     else textattr(10);
    }
    cprintf(" G");
    if (Color) textattr(47);
    else textattr(15);

    if (!J_Work)
    {
     if (Color) textattr(40);
     else textattr(10);
    }
    cprintf(" J");
    if (Color) textattr(47);
    else textattr(15);

    if (!NRaDDayOff)
    {
     if (Color) textattr(40);
     else textattr(10);
    }
    cprintf("N");
    if (Color) textattr(47);
    else textattr(15);

    S1change = 0;
    }
/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³            InitS2              ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/
   InitS2()
   {
    window(1,8,50,24);
    if (Color) textattr(63);
    else textattr(15);
    cprintf("   1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16");
    for (houseindex = 0; houseindex < 16; houseindex++)
    {
     if (Color) textattr(63);
     else textattr(15);
     cprintf("\n%c", housechar[houseindex]);
     for(unitindex = 0; unitindex < 16; unitindex++)
     {
      if (Color)
      {
       if (Status[houseindex][unitindex] == 0) textattr(56);    /* Black */
       else if (Status[houseindex][unitindex] == 15) textattr(63);      /* Whit
e */
       else if ((Status[houseindex][unitindex] > 0) && (Status[houseindex][unit
index] < 15)) textattr(62); /* Yellow */
      }
      else /* LCD */
      {
       if (Status[houseindex][unitindex] == 0) textattr(9);     /* Light Gray *
/
       else textattr(15);                                       /* Black */
      }
      cprintf("%3d", Status[houseindex][unitindex]);
     }
    }
    gettext(1,8,50,25,S2buffer);
   }

/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³            Status2             ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

   Status2()
   {
    window(1,8,50,24);
    gettext(1,8,50,25,S2buffer);
        for (houseindex = 0; houseindex < 16; houseindex++)
    {
     for(unitindex = 0; unitindex < 16; unitindex++)
     {
      if (ChangeStatus[houseindex][unitindex])
      {
       if (Color)
       {
        if (Status[houseindex][unitindex] == 0) textattr(56);   /* Black */
        else if (Status[houseindex][unitindex] == 15) textattr(63);     /* Whit
e */
        else if ((Status[houseindex][unitindex] > 0) && (Status[houseindex][uni
tindex] < 15)) textattr(62); /* Yellow */
       }
       else /* LCD */
       {
        if (Status[houseindex][unitindex] == 0) textattr(9);    /* Light Gray *
/
        else textattr(15);                                      /* Black */
       }
       gotoxy((unitindex * 3) + 2, houseindex + 2);
       cprintf("%3d", Status[houseindex][unitindex]);
       ChangeStatus[houseindex][unitindex] = 0;
       S2change = 0;
      }
     }
    }
   }

/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³           IOwindow             ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

   IOwindow()
   {
    window(51,1,80,25);   /* Input/Output Window */
    if (Color) textattr(79);
    else textattr(15);
    clrscr();
    gotoxy(1,25);
   }

/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³          InitScreen()          ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/
InitScreen()
{
 window(1,1,80,25);
 clrscr();
 highvideo();
 if (Color) textattr(47);
 gotoxy(1,25);
 cprintf(" Esc to exit                     Press Selection:");
 menu1();
 Status1();
 InitS2();
 Status2();
 gettext(1,8,50,25,S2buffer);
 IOwindow();
}


/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³               bye              ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/
bye()
{
 window(1,1,80,25);
 textattr(14);
 clrscr();
 gotoxy(1,5);
 cprintf("      ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
ÍÍÍÍ»\n");
 cprintf("      º ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
ÍÍ» º\n");
 cprintf("      º º
  º º\n");
 cprintf("      º º               Wireless Home Control Program
  º º\n");
 cprintf("      º º             using an X-10 TW523 two-way module
  º º\n");
 cprintf("      º º                  and an IBM PC or clone
  º º\n");
 cprintf("      º º               with a serial or parallel port
  º º\n");
 cprintf("      º º
  º º\n");
 cprintf("      º º                   Jonathan M. Chattin
  º º\n");
 cprintf("      º º                     2711 Grade Place
  º º\n");
 cprintf("      º º                  Spring Valley, CA 91977
  º º\n");
 cprintf("      º º                      (619) 462-1860
  º º\n");
 cprintf("      º º                      Copyright 1993
  º º\n");
 cprintf("      º º                        74017,3725
  º º\n");
 cprintf("      º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
ÍÍ¼ º\n");
 cprintf("      ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
ÍÍÍÍ¼\n");
}
/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³            showargs            ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/
showargs()
{
 window(1,1,80,25);
 textattr(31);
 clrscr();
 gotoxy(1,1);
 cprintf("      ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
ÍÍÍÍ»\n");
 cprintf("      º    Wireless Home Control Program using an X-10 TW523 and a PC
    º\n");
 cprintf("      º ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
ÍÍ» º\n");
 cprintf("      º º        Command Line Arguments: (example: tw g j h a)
  º º\n");
 cprintf("      º º                1: force port to COM1
  º º\n");
 cprintf("      º º                2: force port to COM2
  º º\n");
 cprintf("      º º                3: force port to COM3
  º º\n");
 cprintf("      º º                4: force port to COM4
  º º\n");
 cprintf("      º º                5: force port to LPT1
  º º\n");
 cprintf("      º º                6: force port to LPT2
  º º\n");
 cprintf("      º º                7: force port to LPT3
  º º\n");
 cprintf("      º º                A: Automatic Schedule
  º º\n");
 cprintf("      º º                C: Color
  º º\n");
 cprintf("      º º                D: Debug
  º º\n");
 cprintf("      º º                H: Home
  º º\n");
 cprintf("      º º                V: Vacation
  º º\n");
 cprintf("      º º                J: J Work  G: G Work
  º º\n");
 cprintf("      º º                N: No Initialization
  º º\n");
 cprintf("      º º                O: J On Travel
  º º\n");
 cprintf("      º º                T: Turn Off Lights Every 15 Minutes
  º º\n");
 cprintf("      º º         Press any key to continue
  º º\n");
 cprintf("      º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
ÍÍ¼ º\n");
 cprintf("      º   Copyright 1992 Jonathan M. Chattin 74017,3725 (619) 462-186
0   º\n");
 cprintf("      ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
ÍÍÍÍ¼\n");
 while (!kbhit());
 key = getch();
}

/*           ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
             º ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º
             º º                                º º
             º º             MAIN               º º
             º º                                º º
             º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼ º
             ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼
*/
main(int argc, char *argv[])
{
 daylight = 0;
 for (argindex = 1; argindex < argc; argindex++)
 {
  c = toupper(*argv[argindex]);
  switch(c)
  {
   case '1': portforce      = 0; break;  /* COM1 */
   case '2': portforce      = 1; break;  /* COM2 */
   case '3': portforce      = 2; break;  /* COM3 */
   case '4': portforce      = 3; break;  /* COM4 */
   case '5': portforce      = 4; break;  /* LPT1 */
   case '6': portforce      = 5; break;  /* LPT2 */
   case '7': portforce      = 6; break;  /* LPT3 */
   case 'A': Auto           = 1; break;
   case 'C': Color          = 1; break;
   case 'D': Debug          = 1; break;
   case 'H': Home           = 1; break;
   case 'N': NoInit         = 1; break;
   case 'J': J_Work         = 1; break;
   case 'G': G_Work         = 1; break;
   case 'V': Vacation       = 1; break;
   case 'T': J_On_Travel    = 1; break;
   case 'O': turn_units_off = 1;
  }
 }
 if (argc < 2) showargs();
 memset(&IObuffer,' ',sizeof(IObuffer));
 memset(&S2buffer,' ',sizeof(S2buffer));
 memset(&Timer, 0, sizeof(Timer));
 memset(&FirstTimeThru, 0, sizeof(FirstTimeThru));
 memset(&Status, 0, sizeof(Status));
 memset(&ChangeStatus, 0, sizeof(ChangeStatus));
 memset(&FirstBriSent, 0, sizeof(FirstBriSent));

 strcpy(port, portname[portforce]);
 getjmctime();
 getsunriset();
 getSchool();
 getTOD();
 if (jmctime->tm_wday == 5) getNRaDDayOff();
 getWeekday();
 getCoffeeTime();


 InitScreen();

 if (!Debug) if (tw523ok(portforce)) if (initest()) exit(0);

 if (!NoInit) EverythingOff();

 if (!Home) say("security.v3s");

 while(1)                       /* main loop */
 {
  if (S1change)
  {
   gettext(51,1,80,25,IObuffer);
   Status1();
   IOwindow();
   puttext(51,1,80,25,IObuffer);
  }
  if (S2change)
  {
   gettext(51,1,80,25,IObuffer);
   Status2();
   gettext(1,8,50,25,S2buffer);
   IOwindow();
   puttext(51,1,80,25,IObuffer);
  }
  retc = 1;
  if (kbhit())                  /* Keyboard Input */
  {
   key = toupper(getch());      /* get character and change to uppercase */

   if (Intruder) Intruder = 0;

   if(key == 0x1b)
   {
    bye();
    exit(0);     /* Esc ? if so, exit */
   }
   switch(key)                  /* look at input key */
   {
    case 'A':                   /* automatic */
      if (Auto) Auto = 0;
      else Auto = 1;
      S1change = 1;
      retc = 1;
      break;

    case 'B':                   /* bright function */
      inthouse = house - 'A';
      intunit = unit - 1;
      if (Status[inthouse][intunit] < 15) DoFunc(Bright);
      retc = 1;
      break;

    case 'D':                   /* dim function */
      inthouse = house - 'A';
      intunit = unit - 1;
      if (Status[inthouse][intunit] > 0) DoFunc(Dim);
      retc = 1;
      break;

    case 'F':                   /* off function */
      DoFunc(Off);
      retc = 1;
      break;

    case 'G':                   /* G's Work */
      if (!G_Work)
        G_Work = 1;
      else G_Work = 0;
      retc = 0;
      S1change = 1;
      break;

    case 'H':                   /* toggle Home/Not Home */
      if ((!Home)||(NotHomeFlag))
      {
       NotHomeFlag = 0;
       say("homeagin.v3s");
       Home = 1;
       FirstTimeThru[8] = 0;
       Timer[8] = 0;
       if (Intruder == 1)
       {
        Intruder = 0;
        FirstTimeThru[1] = 0;
        Timer[1] = 0;
        }
       S1change = 1;
      }
      else
      {
       Timer[8] = jmctime->tm_min;
       NotHomeFlag = 1;
       if (Auto)
       {
        cprintf("3 minutes to get out\n");
        say("getout.v3s");
       }
       else cprintf("Auto must be 1\n");
       for (i = 50; i < 300; i++)
       {
        delay(1);
        sound(i * 10);
       }
       for (i = 300; i > 50; i--)
       {
        delay(1);
        sound(i * 10);
       }
       nosound();
      }
      retc = 0;
      break;

    case 'I':
      cprintf("Enter Intensity (0-15): ");
      cscanf("%d", &intenint);
      cprintf("\n");
      if ((intenint < 0)||(intenint >= 16)) retc = -1;
      else
      {
       Intensity(intenint);
       retc = 1;
      }
      dummy = getch();
      break;

    case 'J':                   /* J's Work */
      if (!J_Work)
        J_Work = 1;
      else J_Work = 0;
      retc = 0;
      S1change = 1;
      break;

    case 'L':                   /* all lights on */
      DoFunc(All_Lights_On);
      retc = 1;
      break;

    case 'N':                   /* on function */
      DoFunc(On);
      retc = 1;
      break;

    case 'T':                   /* J On Travel */
      if(!J_On_Travel)
        J_On_Travel = 1;
      else J_On_Travel = 0;
      S1change = 1;
      retc = 0;
      break;

    case 'R':                   /* Restore Settings */
      Reset_Hall();
      Reset_Outside();
      retc = 1;
      break;

    case 'S':                   /* selection */
      retc = 1;
      cprintf("Enter House & Unit: ");
      cscanf("%c%2d", hsestr, &unitint);
      c = toupper(hsestr[0]);
      index = c - 'A';
      if ((index < 0)||(index >= 16)) retc = -1;
      else
      {
       house = c;
       index = unitint - 1;
      }
      if ((index < 0)||(index >= 16)) retc = -1;
      else
      {
       unit = index + 1;
       S1change = 1;
      }
      dummy = getch();
      break;

    case 'O':                   /* toggle turn off units every 5 minutes */
      if (!turn_units_off)
        turn_units_off = TRUE;
      else turn_units_off = FALSE;
      retc = 0;
      S1change = 1;
      break;

    case 'U':                   /* all units off */
      DoFunc(All_Units_Off);
      retc = 1;
      break;

    case 'V':                   /* Vacation */
      if (Vacation) Vacation = 0;
      else Vacation = 1;
      getSchool();
      retc = 0;
      S1change = 1;
      break;

    case 'X':
      EverythingOff();
      talk("alloff.txt");
      retc = 0;
      break;

    case 'Y':
    /*  say("yes.v3s"); */
      WriteStatusFile();
      talk("status.txt");
      retc = 1;

      break;

    case 'Z':
      cprintf("01234567890123456789FirstTime\n");
      for (i = 0; i < 20; i++) cprintf("%d", FirstTimeThru[i]);
      cprintf("\n");
      for (i = 0; i < 20; i++) cprintf("Timer %2d: %2d\n", i, Timer[i]);
      cprintf("CoffeeTime = %d\n", CoffeeTime);
      retc = 0;
      break;

    default:
      retc = -1;                /* set for error */
      break;
   } /* end switch */

   if(retc < 0)                 /* if error */
   {
    gotoxy(1, 25);
    clreol();
    cprintf("Try Again\n");
   } /* end if (retc <0) */
   gotoxy(1,25);
   clreol();

  } /* end if (kbhit) */

/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³      automatic schedule        ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

  if (Auto)
  {

/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³          Flag Action           ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/

/* Emergency - Flash Outside and Inside Lights for 3 minutes */




   if (Emergency)
   {
    unit = 16;                          /* Chime */
    house = 'H';
    DoFunc(On);
    DoFunc(Off);
    DoFunc(All_Units_Off);
    DoFunc(All_Lights_On);
    house = 'M';                        /* Master  */
    DoFunc(All_Units_Off);
    DoFunc(All_Lights_On);
    say("emergenc.v3s");
    house = 'O';                        /* Outside */
    DoFunc(All_Units_Off);
    DoFunc(All_Lights_On);
    if (FirstTimeThru[2] == 0) Timer[2] = jmctime->tm_min;
    FirstTimeThru[2] = 1;
    if (abs(jmctime->tm_min - Timer[2]) >= 3)
    {
     Emergency = 0;
     Timer[2] = 0;
     FirstTimeThru[2] = 0;
    }
   }

/* IntruderFlag */

   if (IntruderFlag)
   {
    if (!FirstTimeThru[16])
    {
     Timer[16] = jmctime->tm_min;
     FirstTimeThru[16] = 1;
    }
    if (abs(jmctime->tm_min - Timer[16]) >= 3)   /* Check for Timeout */
    {
     IntruderFlag = 0;
     FirstTimeThru[16] = 0;
    }
   }


/* Intruder - */
/* Flash Hall and Outside Lights and Outside Alarm for 3 Minutes */

   if (Intruder)
   {
    rhouse = 'A';
    house ='F';
    DoFunc(All_Lights_On);
    house = 'M';
    unit = 3;                           /* TV Camera */
    DoFunc(On);
    house = 'H';                        /* Hall  */
    DoFunc(On);
    unit = 16;                          /* Chime */
    DoFunc(On);
    DoFunc(Off);
    DoFunc(All_Units_Off);
    DoFunc(All_Lights_On);
    house = 'O';                        /* Outside */
    DoFunc(All_Units_Off);
    DoFunc(All_Lights_On);
    unit = 15;                          /* Dog Bark */
    DoFunc(On);
    unit = 16;                          /* Alarm */
    DoFunc(On);
    say("resistan.v3s");
    if (!FirstTimeThru[1]) Timer[1] = jmctime->tm_min;
    FirstTimeThru[1] = 1;
    if (abs(jmctime->tm_min - Timer[1]) >= 3)   /* Check for Timeout */
    {
     Intruder = 0;
     Timer[1] = 0;
     IntruderFlag = 0;
     Timer[16] = 0;
     FirstTimeThru[16] = 0;
     FirstTimeThru[1] = 0;
     FirstTimeThru[4] = 0;
     FirstTimeThru[6] = 0;
     house = 'O';
     unit = 16;
     DoFunc(Off);
     house = 'F';
     DoFunc(All_Units_Off);
     house = 'M';
     unit = 3;
     DoFunc(Off);
    } /* end if Timeout */
   } /* end if Intruder */



/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³         Time Functions         ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/
   getjmctime();
   if ((jmctime->tm_min == 0) && (!FirstTimeThru[14]))
   {
    getTOD();
    FirstTimeThru[14] = 1;
    FirstTimeThru[15] = 0;
   }

   if ((jmctime->tm_min == 1) && (!FirstTimeThru[15]))
   {
    FirstTimeThru[14] = 0;
    FirstTimeThru[15] = 1;
   }

   if ((jmctime->tm_hour == 0) && (jmctime->tm_min == 0) && (jmctime->tm_sec >
57))
   {
    /* if (!J_On_Travel) */ getNRaDDayOff();
    getWeekday();
    S1change = 1;
   }


   if (!(jmctime->tm_min % TimeOut)) FirstTimeThru[0] = 0;

   if (Day)
   {
    if (FirstTimeThru[4]) FirstTimeThru[4] = 0;
    if (FirstTimeThru[5]) FirstTimeThru[5] = 0;
    if (!FirstTimeThru[11])     /* Turn Off Lights at Dawn */
    {
     house = 'O';               /* Outside */
     DoFunc(All_Units_Off);
     house = 'H';               /* Hall */
     DoFunc(All_Units_Off);
     FirstTimeThru[11] = 1;
    }

/* Turn Off All Outside, Master Bedroom, and Hall Every 15 Minutes in Daytime *
/
   if ((turn_units_off) && !(FirstTimeThru[0]) && (jmctime->tm_sec > 58))
   {
    if (!Home)
    {
     house = 'F';
     DoFunc(All_Units_Off);
     house = 'M';               /* Master Bedroom */
     DoFunc(All_Units_Off);
     house = 'K';
     DoFunc(All_Units_Off);
     house = 'O';               /* Outside */
     DoFunc(All_Units_Off);
     house = 'H';               /* Hall */
     DoFunc(All_Units_Off);
     FirstTimeThru[0] = 1;
    }
    }
   }
   else  /* Evening || Night */
   {
    FirstTimeThru[11] = 0;      /* reset lights off in morning */

    if (!FirstTimeThru[4])
    {
     house = 'H';               /* Turn on Hanging Hall Light at Night */
     unit = 4;
     DoFunc(Off);
     DoFunc(On);
     FirstTimeThru[4] = 1;
    }
     /* Turn on Outside Lights at Night */
    if (!FirstTimeThru[5])
    {
     Reset_Outside();

    }
    if (!FirstTimeThru[7] && Evening)
    {
     if ((Home) && (jmctime->tm_wday == 4)) say("trashday.v3s");
     house = 'F';       /* Turn on Desk Light */
     unit = 2;
     DoFunc(On);
     FirstTimeThru[7] = 1;
    }

    if (FirstTimeThru[7] && Night)
    {
     house = 'F';
     DoFunc(All_Units_Off);
     FirstTimeThru[7] = 0;
     house = 'G';
     unit = 6;
     DoFunc(On);
     DoFunc(Off);
     house = 'J';
     unit = 9;
     DoFunc(On);
     DoFunc(Off);
    }
   }

/* Turn on Dan's light and ring Hall Chime at 6:25 AM */
   if (School && Weekday && !NRaDDayOff && !J_On_Travel && (jmctime->tm_hour ==
 6) && (jmctime->tm_min == 24) && (jmctime->tm_sec > 57))
   {
    house = 'H';
    unit = 5;           /* Dan's Room */
    DoFunc(On);
   }

/* Turn on Nicole's light and ring Hall Chime at 7:00 AM */
   if (School && Weekday && !NRaDDayOff && !J_On_Travel && (jmctime->tm_hour ==
 6) && (jmctime->tm_min == 59) && (jmctime->tm_sec > 57))
   {
    unit = 6;           /* Nicole's Room */
    DoFunc(On);
    unit = 16;          /* Chime */
    DoFunc(On);
    DoFunc(Off);
    say("wakeup.v3s");
   }

/* Weekday Coffee Time 5 A.M. (Weekend or G_Work A.M.) */
/* Also ring Hall Chime to wake Jonathan for work */
   if ((jmctime->tm_hour == CoffeeTime) && (jmctime->tm_min < 30) && !FirstTime
Thru[3] && Home)
   {
    Timer[3] = jmctime->tm_min;
    house = 'K';        /* Coffee Relay */
    unit = 6;
    DoFunc(On);
    if ((jmctime->tm_mon == 7) && (jmctime->tm_mday == 13)) say("ginbirth.v3s")
;
    if (Weekday)
    {
     house = 'K';
     unit = 2;          /* Sink Light */
     DoFunc(On);
     house = 'F';       /* Dining */
     unit = 5;
     DoFunc(On);
    }
    if (Weekday & J_Work)
    {
     house = 'H';       /* Hall Chime */
     unit = 16;
     DoFunc(On);
     DoFunc(Off);
    }
    FirstTimeThru[3] = 1;
   }
   if ((abs(jmctime->tm_min - Timer[3]) > 30) && (FirstTimeThru[3]))
   {
    house = 'K';
    DoFunc(All_Units_Off);
    house = 'F';
    DoFunc(All_Units_Off);
    FirstTimeThru[3] = 0;
   }

/* Curlers and Coffee Pot on at 6:14 AM for 30 min. if G_Work and Weekday */
   if (Home && Weekday && G_Work && !FirstTimeThru[14] && (jmctime->tm_hour ==
6) && (jmctime->tm_min == 14))
   {
    FirstTimeThru[14] = 1;
    Timer[14] = jmctime->tm_min;
    house = 'K'; /* Coffee Pot */
    unit = 6;
    DoFunc(On);
    house = 'M'; /* Curlers */
    unit = 5;
    DoFunc(On);
   }

   if ((abs(jmctime->tm_min - Timer[14]) > 30) && (FirstTimeThru[14]))
   {
    house = 'K';
    unit = 6;
    DoFunc(Off);
    DoFunc(All_Units_Off);
    house = 'M';
    DoFunc(All_Units_Off);
    FirstTimeThru[14] = 0;
    Timer[14] = 0;
   }

/* Not Home Starting at 9 A.M. and Home Again at 4 P.M. */
   if (Weekday && !NRaDDayOff && J_Work && G_Work)
   {
    if (!FirstTimeThru[8] && (jmctime->tm_hour == LeaveHome) && (jmctime->tm_mi
n == 0) && (jmctime->tm_hour < GetHome))
    {
     Home = 0;
     say("security.v3s");
     turn_units_off = 1;
     FirstTimeThru[8] = 1;
     S1change = 1;
    }
    else if ((FirstTimeThru[8] && jmctime->tm_hour == GetHome) && (jmctime->tm_
min == 0))
    {
     Home = 1;
     turn_units_off = 0;
     FirstTimeThru[8] = 0;
     S1change = 1;
    }
   }

   if ((FirstTimeThru[6]) && (abs(jmctime->tm_min - Timer[6]) > 5))
   {
    house = 'H';
    unit = 3;  /* Upstairs Hall Lights */
    DoFunc(Off);
    FirstTimeThru[6] = 0;
    Timer[6] = 0;
   }
   if ((FirstTimeThru[13]) && (abs(jmctime->tm_min - Timer[13]) > 5))
   {
    house = 'J';
    unit = 1;
    DoFunc(Off);
    FirstTimeThru[13] = 0;
    Timer[13] = 0;
   }
   if ((FirstTimeThru[12]) && (abs(jmctime->tm_min - Timer[12]) > 5))
   {
    house = 'H';
    unit = 8;  /* Upstairs Bathroom */
    DoFunc(Off);
    FirstTimeThru[12] = 0;
    Timer[12] = 0;
   }


/* Set Home to 0 9 minutes after 'H' is pressed */
   if (NotHomeFlag && (abs(jmctime->tm_min - Timer[8]) > 9) && (!FirstTimeThru[
8]))
   {
    FirstTimeThru[8] = 1;
    Home = 0;
    say("security.v3s");
    NotHomeFlag = 0;
    S1change = 1;
   }

    if ((jmctime->tm_wday == 1) && (jmctime->tm_hour == 20) && (jmctime->tm_min
 == 49) && (jmctime->tm_sec > 57))
     say("northern.v3s");

    if ((jmctime->tm_wday == 6) && (jmctime->tm_hour == 18) && (jmctime->tm_min
 == 49) && (jmctime->tm_sec > 57))
     say("startrek.v3s");

    if (School && (jmctime->tm_wday == 3) && (jmctime->tm_hour == 17) && (jmcti
me->tm_min == 49) && (jmctime->tm_sec > 57))
     say("cubscout.v3s");

/*
               ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
               ³                                ³
               ³      Look for X-10 Inputs      ³
               ³                                ³
               ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
*/
   if (!Debug && !recvx10(&rhouse, &runfu))     /* check for receive */
   {
    rhouse = tblrx[rhouse & 0xf] + 'A'; /* convert to ascii */
    if(runfu <= 0xf) /* HOUSE and UNIT */
    {
     runit = tblrx[runfu & 0xf] + 1;   /* convert to decimal */
     cprintf("%02d:%02d:%02d ", jmctime->tm_hour, jmctime->tm_min, jmctime->tm_
sec);
     cprintf("RCV: %c-%d ", rhouse, runit);
     continue;
    }
                     /* HOUSE and FUNCTION */
     rfunc = runfu & 0xf;
     cprintf("%s\n ", funcmsg[rfunc]);
     inthouse = rhouse - 'A';
     intunit = runit - 1;

    /* Update Status */

    switch(rfunc)
    {
     case 0xc:                                  /* Off */
       Status[inthouse][intunit] = 0;
       ChangeStatus[inthouse][intunit] = 1;
       break;
     case 0x4:                                  /* On  */
       Status[inthouse][intunit] = 15;
       ChangeStatus[inthouse][intunit] = 1;
       break;
     case 0x0:                                  /* All_Units_Off */
       for (unitindex = 0; unitindex < 16; unitindex++)
        Status[inthouse][unitindex] = 0;
        ChangeStatus[inthouse][unitindex] = 1;
       break;
     case 0x8:                                  /* All_Lights_On */
       for (unitindex = 0; unitindex < 16; unitindex++)
        Status[inthouse][unitindex] = 15;
        ChangeStatus[inthouse][unitindex] = 1;
       break;
     case 0xa:                                  /* Bright */
       if (Status[inthouse][intunit] < 15)
       Status[inthouse][intunit]++;
       ChangeStatus[inthouse][intunit] = 1;
       break;
     case 0x2:                                  /* Dim */
       if (Status[inthouse][intunit] > 0)
       Status[inthouse][intunit]--;
       ChangeStatus[inthouse][intunit] = 1;
       break;
     } /* end switch */
     S1change = 1;
     S2change = 1;
   } /* end rcvx10 */
   else continue; /* back to top of auto if no rcvx10 */


/*           ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
             º ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º
             º º                                º º
             º º            MAIN I/O            º º
             º º                                º º
             º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼ º
             ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼
*/



   if (Home)
   {

    if (rfunc == 0x4)   /* On */
    {
     switch(rhouse)
     {
      case 'F':         /* Family Room */
       NotHomeFlag = 0;
       Home = 1;
       FirstTimeThru[8] = 0;
       S1change = 1;
       house = 'F';
       unit = runit;
       switch(runit)
       {
        case 7:         /* Heater */
         unit = 6;      /* Fan */
         DoFunc(On);
         break;
        case 8:         /* Hi-Fi Amplifier */

         break;

        /* F Macros */

        case 9:         /* Dinner */
         say("dinner.v3s");
         house = 'F';
         DoFunc(All_Units_Off); /* All Family Room Lights Off */
         unit = 5;      /* Dining Room Light to I12 */
         Intensity(12);
         house = 'H';
         unit = 5;      /* Dan */
         DoFunc(Off);
         unit = 6;      /* Nicole */
         DoFunc(Off);
         break;
        case 10:        /* Long Couch Halogens */
         unit = 3;
         Intensity(12);
         break;
        case 11:        /* Short Couch Halogens */
         unit = 4;
         Intensity(12);
         break;
        case 12:

         break;
        case 14:        /* Bedtime */
         say("bedtime.v3s");
         house ='H';
         unit = 5;      /* Dan */
         DoFunc(Off);
         unit = 6;      /* Nicole */
         DoFunc(Off);
         house = 'F';
         unit = 14;
         DoFunc(Off);   /* Reset F14 to Off */
         break;
        case 15:        /* Emergency */
         Emergency = 1;
         break;
        case 16:        /* Security Mode On */
         Timer[8] = jmctime->tm_min;
         NotHomeFlag = 1;
         cprintf("3 minutes to get out\n");
         say("getout.v3s");
         break;
       } /* end switch(runit) */
       if ((FirstTimeThru[9]) && (!FirstTimeThru[10]))
       {
        selunit = runit;
        FirstTimeThru[9] = 0;
        FirstTimeThru[10] = 1;
        runit = 1;
       }
       else if (!FirstTimeThru[9] && FirstTimeThru[10])
       {
        unit = selunit;
        Intensity(runit);
        FirstTimeThru[10] = 0;
       }
       break;
      case 'I':         /* Input from PIRs or XMTRs */
       unit = runit;
       if (Evening || Night)
       {
        if ((runit > 0) && (runit < 5))
        {
         house = 'O';
         DoFunc(Off);
         DoFunc(On);
        }
        if (Night)
        {
         if ((runit != 1) && (runit < 5))
         {
          unit = 15;    /* Dog Bark */
          DoFunc(On);
          delay(4000);
          DoFunc(Off);
         }
        }
       }

       switch(runit)
       {
        case 5:         /* J's Room */
         if (!FirstTimeThru[13])
         {
          house = 'J';
          unit = 1;
          DoFunc(On);
          FirstTimeThru[13] = 1;
          Timer[13] = jmctime->tm_min;
         }
         break;
        case 6:         /* Upstairs Hall */
         if (!Day && !FirstTimeThru[6])
         {
          house = 'H';
          unit = 3;
          DoFunc(On);
          house = 'A';
          FirstTimeThru[6] = 1;
          Timer[6] = jmctime->tm_min;
         }
         break;
        case 8:         /* Garage */
         house = 'G';
         unit = 1;
         if (!Day) DoFunc(On);
         break;
        case 15:
         house = 'H';
         unit = 16;
         if (Day || Evening)
         {
          delay(1000);
          DoFunc(On);
          delay(1000);
          DoFunc(Off);
         }
         break;
       } /* end switch(runit) */
       break;

      case 'J': /* Telephone Responder */
       switch(runit)
       {
        case 2:
        DoFunc(Off);
        talk("testj2.txt");
        break;
        case 16:
        DoFunc(Off);
        EverythingOff();
        talk("alloff.txt");
        break;
      }
      break;
      case 'K': /* Telephone Responder */
      switch(runit)
      {
       case 16:
       DoFunc(Off);
       WriteStatusFile();
       talk("status.txt");
       break;
      }
      break;
      case 'M': /* Master Bedroom */
       switch(runit)
       {
        /* Macros */
        case 5:
        FirstTimeThru[14] = 1;
        Timer[14] = jmctime->tm_min;
        break;
        case 7:         /* Emergency */
         Emergency = 1;
        break;
       } /* end switch(runit) */
       unit = 1;
       break;
     } /* end switch(rhouse) */
    } /* end if (On) */

    if (rfunc == 0xc) /* Off */
    {
     switch(rhouse)
     {
      case 'F':         /* Family Room */
       house = 'F';
       unit = runit;
       switch(runit)
       {
        case 9:         /* Dinner Over */
         unit = 2;      /* Desk */
         DoFunc(On);
         unit = 5;      /* Dining Room */
         DoFunc(Off);
         break;
        case 15:       /* Emergency Off */
         Emergency = 0;
         break;
        case 16:        /* Turn Off Security */
         if ((!Home)||(NotHomeFlag))
         {
          NotHomeFlag = 0;
          say("homeagin.v3s");
          Home = 1;
          FirstTimeThru[8] = 0;
          Timer[8] = 0;
          S1change = 1;
         }
         break;
       } /* end switch(runit) */
       break;
      case 'I':         /* Input from PIRs or XMTRs */
       unit = runit;
       if (Evening || Night)
       {
        if ((runit > 0) && (runit < 5))
        {
         house = 'O';
         Intensity(9);
        }
       }

       switch(runit)
       {
        case 5:       /* J's room */
         house = 'J';
         unit = 1;
         DoFunc(Off);
         FirstTimeThru[13] = 0;
         Timer[13] = 0;
         break;
        case 6:
         if (FirstTimeThru[6])
         {
          house = 'H';
          unit = 3;
          DoFunc(Off);
          house = 'A';
          FirstTimeThru[6] = 0;
          Timer[6] = 0;
         }
         break;
         case 8:                /* Garage Off */
          house = 'G';
          unit = 1;
          if (!Day) DoFunc(Off);
         break;
       } /* end switch(runit) */
       break; /* 'I' */
      case 'M':
       switch(runit)
       {
       } /* end Switch(runit) */
     } /* end switch(rhouse) */
    } /* end if (Off) */
   } /* end if (Home) */
   else /* !Home */
   {
    if (rfunc == 0x4)   /* On */
    {
     if (rhouse == 'I')         /* Input from PIRs or XMTRs */
     {
      if ((runit > 4) && (runit < 9) && (IntruderFlag)) Intruder = 1;
      if ((runit > 4) && (runit < 9)) IntruderFlag = 1;
      if (!Day && runit == 1)
      {
       Intensity(15);
      }
      if ((runit > 1) && (runit < 5))
      {
       house = 'O';
       if (!Day) DoFunc(All_Lights_On);
       unit = 15;               /* Dog Bark */
       DoFunc(On);
       delay(4000);
       DoFunc(Off);
      }
      if (!FirstTimeThru[12] && runit == 7) /* Family Room PIR */
      {
       Intruder = 1;
       house = 'M';
       unit = 3;
       DoFunc(On);
       house = 'F';
       DoFunc(All_Lights_On);
       FirstTimeThru[12] = 1;
       Timer[12] = jmctime->tm_min;
      }
      if (FirstTimeThru[8] && runit == 15)
      {
       Home = 1;
       FirstTimeThru[8] = 0;
      }
     } /* end if(rhouse == 'I') */
    } /* end On */

    if (rfunc == 0xc)   /* Off */
    {
     if (rhouse == 'I')
     {
      if (FirstTimeThru[12] && runit == 7 && rfunc == 0xf)
      {
       house = 'M';
       unit = 3;
       DoFunc(Off);
       house = 'F';
       DoFunc(All_Units_Off);
       FirstTimeThru[12] = 0;
       Timer[12] = 0;
      }

      /* Reset Outside after timeout */
      if ((runit > 0) && (runit < 5)) Intensity(9);

     }  /* end 'I' */
    }   /* end Off */
   } /* end if (!Home) */
  } /* end if (auto) */

  rfunc = 0xf;  /* reset rfunc until next x10rcv */

 } /* end while(1) */

} /* end main */


