/*** Beginheader */ #ifndef __AIT_HVAC_LIB #define __AIT_HVAC_LIB #define HVAC_INTERVAL_SEC 6 #define HVAC_DELAY_SEC 30 #define HVAC_NODES 8 #define HVAC_Z1_CIRCULATOR 7 #define HVAC_Z2_CIRCULATOR 6 #define HVAC_Z3_CIRCULATOR 5 #define HVAC_Z4_CIRCULATOR 4 #define HVAC_MASTER_CIRCULATOR 3 #define HVAC_ERV 2 #define HVAC_FAN 1 #define HVAC_WW_GSHP 0 /*** Endheader */ /* START LIBRARY DESCRIPTION ********************************************* AIT_HVACERAL.LIB Copyright (c) 2004, Adaptive Internet Technologies DESCRIPTION: AIT General purpose utilities SUPPORT LIBS: REVISION HISTORY: 1.1 12/04/03 Original Issue END DESCRIPTION **********************************************************/ //--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--// /*** BeginHeader HVAC_Init, HVAC_Cycle, HVAC_CheckSetpoint, HVAC_Off */ // ----------------------------------------------- // Control variables // ----------------------------------------------- int HVAC_Enable; int HVACNodeIndex[HVAC_NODES]; // int HVACNodeState[HVAC_NODES]; // 0 = Off float * pA0; float * pT1; float * pT2; float * pT3; float * pT4; float * pTWT; // Temp Hot Water Top float * pTWB; // Temp Hot Water Bottom float TWAvg; // Average Water Temp int HVAC_Init(SENSOR * Devices, int ActiveDevices); void HVAC_Cycle(SENSOR * Devices); int HVAC_AddServerVars(SENSOR * Devices); int HVAC_CheckSetpoint(float * pTemp, int Node, float Setpoint, float Delta); void HVAC_Off(); /*** EndHeader */ /* START _FUNCTION DESCRIPTION ******************************************** HVAC_Init SYNTAX: int HVAC_Init(SENSOR * Devices, int ActiveDevices) PARAMETER1: The array of Sensor data structures PARAMETER2: Number of sensors currently defined DESCRIPTION: Sets up Control Variables RETURNS: New number of Active devices SEE ALSO: END DESCRIPTION **********************************************************/ int HVAC_Init(SENSOR * Devices, int ActiveDevices) { int Node; // Add Zone Controls to Device list for (Node = 0; Node < HVAC_NODES; Node++ ) { HVACNodeState[Node] = 0; HVACNodeIndex[Node] = ActiveDevices; sprintf(Devices[ActiveDevices].Name, "H%d", Node); Devices[ActiveDevices].Type = DEV_RELAY; Devices[ActiveDevices].FilterTC = 1.0 ; Devices[ActiveDevices].Valid = 1; ActiveDevices++; } HVAC_Enable = 1; return (ActiveDevices); } /* START _FUNCTION DESCRIPTION ******************************************** HVAC_Cycle SYNTAX: void HVAC_Cycle(SENSOR * Devices) PARAMETER1: The array of Sensor data structures DESCRIPTION: Processes control cycle RETURNS: SEE ALSO: END DESCRIPTION **********************************************************/ void HVAC_Cycle(SENSOR * Devices) { int Node; int Time; int Setback; int DHW_Priority; long int Min ; double HouseAvg ; double SetpointAvg ; // Abort if HVAC not running; if (HVAC_Enable != 1) return; Time = AIT_GetTime24(); Setback = ( (Time < UB.Comfort_Start ) || (Time > UB.Comfort_Stop ) ); DHW_Priority = ( (Time >= UB.DHW_Priority_Start ) && (Time <= UB.DHW_Priority_Stop ) ); TWAvg = (*pTWT + *pTWB) / 2.0 ; // Run Hot Water control loop HVAC_CheckSetpoint(&TWAvg, HVAC_WW_GSHP, UB.WW_Setpoint, UB.WATER_Delta); // Run zone loops: Unless: // HW Priority is on AND GSHP is on // or // Water temp is below Lower Limit if (((DHW_Priority == 0) || (HVACNodeState[HVAC_WW_GSHP] == 0)) && (*pTWT >= UB.WW_LowerLimit) ) { HVAC_CheckSetpoint(pT1, HVAC_Z1_CIRCULATOR, Setback ? UB.Z1_Setback : UB.Z1_Setpoint, UB.AIR_Delta); HVAC_CheckSetpoint(pT2, HVAC_Z2_CIRCULATOR, Setback ? UB.Z2_Setback : UB.Z2_Setpoint, UB.AIR_Delta); HVAC_CheckSetpoint(pT3, HVAC_Z3_CIRCULATOR, Setback ? UB.Z3_Setback : UB.Z3_Setpoint, UB.AIR_Delta); HVAC_CheckSetpoint(pT4, HVAC_Z4_CIRCULATOR, Setback ? UB.Z4_Setback : UB.Z4_Setpoint, UB.AIR_Delta); } else { HVACNodeState[HVAC_Z1_CIRCULATOR] = 0 ; HVACNodeState[HVAC_Z2_CIRCULATOR] = 0 ; HVACNodeState[HVAC_Z3_CIRCULATOR] = 0 ; HVACNodeState[HVAC_Z4_CIRCULATOR] = 0 ; } // Run the circulator if any zone is on (for heat) HVACNodeState[HVAC_MASTER_CIRCULATOR] = HVACNodeState[HVAC_Z1_CIRCULATOR] || HVACNodeState[HVAC_Z2_CIRCULATOR] || HVACNodeState[HVAC_Z3_CIRCULATOR] || HVACNodeState[HVAC_Z4_CIRCULATOR] ; // On a 10 Minute cycle : // Run the ERV at 100% when the house is 3° hotter than the setpoint // and 8° hotter than the outside temp. // or Run it at 60% during Shower Priority otherwise // or Run it at 40% if the outside temp is between 50 and 80 (outside of Setback) // or Run it at 20% if non of above Min = (SEC_TIMER / 60) % 10 ; HVACNodeState[HVAC_ERV] = 0; // HouseAvg = (*pT2 + *pT3 + *pT4) / 3.0 ; // SetpointAvg = (UB.Z2_Setpoint + UB.Z3_Setpoint + UB.Z4_Setpoint) / 3.0 ; if ( // ((HouseAvg > (*pA0 + 8.0)) && (HouseAvg > (SetpointAvg + 3.0))) || (DHW_Priority && (Min < 6)) || ((*pA0 >= 50.0) && (*pA0 <= 80.0) && (!Setback) && (Min < 4)) || (Min < 2) ) { HVACNodeState[HVAC_ERV] = 1; } // send Node states to output channel & Device array for (Node = 0; Node < HVAC_NODES; Node++ ) { digOut(Node, HVACNodeState[Node]); Devices[HVACNodeIndex[Node]].Raw = HVACNodeState[Node]? 1.0 : 0.0; Devices[HVACNodeIndex[Node]].Scaled = HVACNodeState[Node]? 1.0 : 0.0; } } /* START _FUNCTION DESCRIPTION ******************************************** HVAC_AddServerVars SYNTAX: int HVAC_AddServerVars(SENSOR * Devices) PARAMETER1: The array of Sensor data structures DESCRIPTION: Load the Web Server with Setpoint Values RETURNS: SEE ALSO: END DESCRIPTION **********************************************************/ int HVAC_AddServerVars(SENSOR * Devices) { int var; var = sspec_addvariable("Z1_SP", &(UB.Z1_Setpoint), FLOAT32, "%.2f", SERVER_HTTP); if (var < 0) return (var); var = sspec_addvariable("Z2_SP", &(UB.Z2_Setpoint), FLOAT32, "%.2f", SERVER_HTTP); if (var < 0) return (var); var = sspec_addvariable("Z3_SP", &(UB.Z3_Setpoint), FLOAT32, "%.2f", SERVER_HTTP); if (var < 0) return (var); var = sspec_addvariable("Z4_SP", &(UB.Z4_Setpoint), FLOAT32, "%.2f", SERVER_HTTP); if (var < 0) return (var); var = sspec_addvariable("WW_SP", &(UB.WW_Setpoint), FLOAT32, "%.2f", SERVER_HTTP); if (var < 0) return (var); var = sspec_addvariable("WW_LL", &(UB.WW_LowerLimit), FLOAT32, "%.2f", SERVER_HTTP); if (var < 0) return (var); var = sspec_addvariable("A_D", &(UB.AIR_Delta), FLOAT32, "%.2f", SERVER_HTTP); if (var < 0) return (var); var = sspec_addvariable("W_D", &(UB.WATER_Delta), FLOAT32, "%.2f", SERVER_HTTP); if (var < 0) return (var); var = sspec_addvariable("Z1_SB", &(UB.Z1_Setback), FLOAT32, "%.2f", SERVER_HTTP); if (var < 0) return (var); var = sspec_addvariable("Z2_SB", &(UB.Z2_Setback), FLOAT32, "%.2f", SERVER_HTTP); if (var < 0) return (var); var = sspec_addvariable("Z3_SB", &(UB.Z3_Setback), FLOAT32, "%.2f", SERVER_HTTP); if (var < 0) return (var); var = sspec_addvariable("Z4_SB", &(UB.Z4_Setback), FLOAT32, "%.2f", SERVER_HTTP); if (var < 0) return (var); var = sspec_addvariable("COMF_Start", &(UB.Comfort_Start), INT16, "%4d", SERVER_HTTP); if (var < 0) return (var); var = sspec_addvariable("COMF_Stop", &(UB.Comfort_Stop), INT16, "%4d", SERVER_HTTP); if (var < 0) return (var); var = sspec_addvariable("DHW_Start", &(UB.DHW_Priority_Start), INT16, "%4d", SERVER_HTTP); if (var < 0) return (var); var = sspec_addvariable("DHW_Stop", &(UB.DHW_Priority_Stop), INT16, "%4d", SERVER_HTTP); if (var < 0) return (var); pA0 = (float *)WEB_GetVarAddr("A0"); pT1 = (float *)WEB_GetVarAddr("T1"); pT2 = (float *)WEB_GetVarAddr("T2"); pT3 = (float *)WEB_GetVarAddr("T3"); pT4 = (float *)WEB_GetVarAddr("T4"); pTWT = (float *)WEB_GetVarAddr("D7"); pTWB = (float *)WEB_GetVarAddr("D6"); return (OW_VARS_OK); } int HVAC_CheckSetpoint(float * pTemp, int Node, float Setpoint, float Delta) { // Turn on the circulator if the temp is below the setpoint (use hysteresis) if (HVACNodeState[Node]) { if (*pTemp >= (Setpoint + Delta / 2.0)) { // printf("\n%d-T%d >= Sp (%f, %f)\n", HVACNodeState[Node], Node, *pTemp, (Setpoint + Delta / 2.0) ); HVACNodeState[Node] = 0; } } else { if (*pTemp <= (Setpoint - Delta / 2.0)) { // printf("\n%d-T%d <= Sp (%f, %f)\n",HVACNodeState[Node], Node, *pTemp, (Setpoint - Delta / 2.0) ); HVACNodeState[Node] = 1; } } } int HVAC_Circulate(float * pTemp, int Node, float Setpoint, float Delta) { // Turn on the circulator if the temp is above the setpoint + delta if (*pTemp >= (Setpoint + Delta)) { HVACNodeState[Node] = 1; } } /* START _FUNCTION DESCRIPTION ******************************************** HVAC_Off SYNTAX: void HVAC_Off() RETURNS: SEE ALSO: END DESCRIPTION **********************************************************/ void HVAC_Off() { auto Node; HVAC_Enable = 0; for (Node = 0; Node < HVAC_NODES; Node++ ) { HVACNodeState[Node] = 0; digOut(Node, 0); } } /*** BeginHeader */ #endif /*** EndHeader */