Object-Oriented Device Networking
by Michael Howard

Listing One
/* Heat Control Input.  This input represents the heat on/off 
** control from a thermostat.  
** EmergencyOff 
** The emergency off input requires that any activity should 
** be terminated as soon as possible, but in a way that will
** not damage equipment.  In this system, the cool down cycle
** is shortened when this is present.
** Heat
** The heat input from the thermostat.  The furnace must start
** heating as soon as possible and remain on until this is de-asserted.
*/  
typedef struct {
		BOOL EmergencyOff;
		BOOL Heat;
                BOOL Economy;
	       } HeatControlIn;
/* Furnace Status Output.
** This is an output specific to Furnace device types. The
** fault flag is used to indicate if there is a current fault to report.  
** FanOn        - indicates whether the fan is currently running.
** Heating      - Indicates if the furnace is currently active.  This
**                is true during the phases of warm-up, heat, cool-down.
** InternalTemp - The internal temperature.  This value is used to 
**                control the phase transitions as well as the
**                fault shut-down.
*/
typedef struct {
	        BOOL Fault;
                BOOL FanOn;
                BOOL Heating;
                TEMP InternalTemp;
               } FurnaceStatus;

/* Fault Output.  This is a generic equipment fault output.
** The Reason field is an ascii text description of the fault.
** The code is a device type specific fault value. The tuple 
** of (TypeId,code) will determine the fault meaning for other devices.
*/
typedef struct {
		char   *Reason;
                BYTE    Code;
		DEVID   Id;
                DevType TypeId;
               } FaultDesc;		
/* Sample State machine to go with these I/O on a furnace. */
    /* check internal temperature, maintain status  */
    status.InternalTemp = InternalTemp = ReadTemp();

    /* handle state transitions  */
    switch (FSTATE)
       {
       case idle:
		if (! EmergencyOff)
		    {
                    if (Heat)
			StartHeat();
		    }
                break;
       case starting:
                if (InternalTemp >= START_TEMP)
                    {
		    SetFan(ON);
		    FSTATE = heating;
                    }
 		break;
       case cooling:
                if ((EmergencyOff && (InternalTemp <= FAST_STOP_TEMP))
                    || (InternalTemp <= STOP_TEMP))
                    {
                    SetFan(OFF);
                    FSTATE = idle;
                    }
                break;
       case heating:
                if (! Heat)
                   {
                   StopHeat();
                   FSTATE = cooling;
                   }
                if (InternalTemp >= MAX_TEMP)
                   {
                   StopHeat();
                   FSTATE = cooling;
                   status.Fault = TRUE;
                   fault.Reason = "Internal temp exceeded, check filter";
                   fault.Code = FAULT_FURNACE_TEMP;
                   fault.Id = MyId;
                   fault.TypeId = Mytype;
                   } 
                break;
              
       }




2

