From: Sife3o <si...@fa...> - 2007-05-13 19:04:24
|
Following is some code heuristic that so far seems to work for me in cooling my two story masonry house. I wanted something simple that would just turn on a fan and then turn it off when the desired temperature was reached. It was not to be. Over the last four cooling seasons, it kept getting more and more complicated. Anyway, here is the code, warts and all: Steve OK, attachment blocked, here it is inline: # fans.pl # fan times and conditions # Category=HVAC # # #### =begin comment fans.pl 1.0 Created by Steve (si...@ya...) 6/1/02, submitted 5/14/07 This script operates a modified three speed window fan and a single speed attic/gable fan to cool during the summer and provide additional warmth late spring/early fall (Northeast USA). It makes use of three temperature readings; outside temperature (shaded), inside temperature near the air intake window and inside temperature near the air exhaust window with the 3 speed fan, and an indoor humidity indicator (a thermostat type on/off). The humidity indicator is to raise the minimum temperature above the local average dewpoint (set by experiment). No interior air conditioning is assumed. What I have found (at least in my 2 story masonary structure) is that pulling the heat out of the (well ventilated) attic by a fan in the summer actually raises the interior house temperature much faster then if left alone. (as observed by plotting all temperatures on a chart) I would never have guessed that outcome. The following is a heurestic based on experimental values over the last four cooling seasons. Use 4 appliance modules, one for the attic fan and one for each speed. The three speed fan is modified as follows: . (if you are not experienced with electrical components, . have someone else do this) . identify the common fan wire and the low, medium, and hight speed wires. . mark the wires . cut out the three speed switch . wire the low, medium, and high into 120V relays in the following fashion: . (Caution: ASCII art follows) . . . (fan wires) . . ____________________________________ common leg . | . | . | . | ______________________ low speed leg . | | . | | . | ________o__V (nc) . | | ___________ medium speed leg . | | ^ (no) | . | | | | . | | L_____o___V (nc) . | | . . | | . ^ (no) . | | . L_____________ high speed leg . | | . . . | | . . . | | |E| |E| (120V relay coils) . | | | | . _L_L_ __L__ __L__ . | | | | | | . | X10 | | X10 | | X10 | X10 Appliance Modules . |_____| |_____| |_____| . | | | . | | | ..120V.________L____________L_________| . . . relay 1 relay 2 . . . $HFanL $HFanM $HFanH . . wire in relay coils to AC cord to plug into x10 modules or hard wire . with x10 . set codes sequentially, attic first . =cut # Other variables used from outside this code fragment # ## $inside_t > MH inside temperature by exhaust (near 3 speed fan) ## $LR_t > temperature near air intake ## $outside_t > shaded outside temperature ## $diff_t > outside temp - inside temp ## $diff_t2 > current $LR_t - previous $LR_t ## $diff_t3 > current $inside_t - previous $inside_t #### additional variables # ## $warmer > local summer flag, e.g. windows are open. ## $heat_flag > heating flag, set by calendar/temperature ## $hot > hottest part of summer flag (set to your liking) ## (July and August) ## $humid_flag > set when humidity is > 65% ## ## $testlog > just a log used for testing, can be print.log ## $istest > turns test log on anf off ## ##### Fan Group names (in devices.mht) # ## $HFanH > high speed, $House_Fan + $House_Fan_2 ## + $House_Fan_3 + $Attic_Fan ## $HFanM > medium speed, $House_Fan + $House_Fan_2 ## + $Attic_Fan ## $HFanL > low speed, $House_Fan + $Attic_Fan ## $HFan > $HFanH ## $hFan > $House_Fan_3 + $HouseFan_2 ## ## X 10 module names ## $Attic_Fan > attic fan ## $House_Fan > low speed leg x10 unit, provides switched ## power to fan ## $House_Fan_2 > med speed leg x10 unit, operates relay 1 ## $House_Fan_3 > high speed leg x10 unit, operates relay 2 ## ######### #### if ($Startup or $Reload){ # set by experiment $timer_fans = new Timer(); my $mins = 60 ; # 60 seconds in a minute my $warmer ; # Summer weather if (($Month > 5 or ( $Month == 5 and $Mday > 10)) and ($Month < 9) and !$warmer) { $warmer = 1; } elsif ((($Month < 5) or ($Month > 8 )) and $warmer) { $warmer = 0 ; } my $hot ; # set to true July, August # Hot if ((($Month == 7 ) or ($Month == 8 )) and !$hot ) { $hot = 1; } elsif (!(($Month == 7 ) or ($Month == 8 )) and $hot ) { $hot = 0 ; } my $diff_high ; # fan high set point my $diff_med ; # fan medium set point my $diff_on ; # fan low/on set point my $diff_off ; # fan off set point temperature my $diff_2 = 0.3 ; # temperature differential to medium my $diff_3 = 0.7 ; # temperature differential to high my $diff_o = 0.5 ; # hysteresis differential offset my $diff_a = 2.1 ; # hysteresis differential offset my $tmin_inside = 76.0 ; # min inside temperature wanted my $tmax_inside = 78.0 ; # max inside temperature wanted my $diff_heat = 1.9 ; # hysteresis differential for heat my $diff_off_day = 1.8 ; # daytime hysteresis differential for cool my $diff_off_night = 0.5 ; # nighttime hysteresis differential for cool my $diff_warming = 0.1 ; my $outside_max_c = 80 ; my $outside_min_c = 62.5 ; my $outside_max_h = 76 ; my $outside_min_h = 65.5 ; # increase the the Tmin value if # temperature is less than this my $Tmin_i = 74 ; # values for tmin, tmax settings my $Tmin_i_L = 75.5 ; # determined by experiment (ymmv) my $Tmax_i_L = 77 ; my $Tmin_i_H = 77 ; # too low a value of the following settings my $Tmax_i_H = 78 ; # caused condensation on the walls when the my $HTmin_i_L = 74 ; # humidity increased. my $HTmax_i_L = 78 ; my $HTmin_i_H = 77 ; my $HTmax_i_H = 78 ; my $HHTmin_i_L = 75 ; my $HHTmax_i_L = 77 ; my $HHTmin_i_H = 75 ; my $HHTmax_i_H = 77 ; my $high = "HIGH" ; my $med = "MED" ; my $low = "LOW" ; my $fspeed = "OFF"; my $start_atticfan_cool ; my $start_atticfan_heat ; my $start_housefan_heat ; my $housefan_heat_high ; my $housefan_heat_med ; my $housefan_heat_low ; my $start_housefan_cool = 0 ; my $housefan_cool_high ; my $housefan_cool_med ; my $housefan_cool_low ; my $fan_test ; # test logging my $testlog = "test.log"; # additional test logging my $istest = 1; #my $istest = 0; } # Voice commands # $v_fans_test_on = new Voice_Cmd('test fans on'); $v_fans_test_off = new Voice_Cmd('test fans off'); $v_fans_manual_on = new Voice_Cmd('fans manually on'); $v_fans_manual_off = new Voice_Cmd('fans manually off'); if ( $state = said $v_fans_test_on ){ # start test log $fan_test = 1 ; log_fan_settings() if $fan_test ; } if ( $state = said $v_fans_test_off ){ # stop test log $fan_test = 0 ; } ############ ## Manual Fan Control ############ if ( $state = said $v_fans_manual_off ){ set_speed(OFF); $fanflag = 0; unset $timer_fans; # just in case print_log "log=$testlog Fans OFF, manual" if $istest; } if ( $state = said $v_fans_manual_on ){ set_speed($high); #$fanflag = 1; # do not set this flag here, bad things happen set $timer_fans 30*$mins; print_log "log=$testlog Fans ON, manual" if $istest; } if (expired $timer_fans and !$fanflag){ set $Fan OFF; print_log "log=$testlog Fans OFF, timer" if $istest; } # reset fanflag if needed if ($Reload or $Startup){ if(state_now $House_Fan eq ON){ fanflag = 1; } else { fanflag = 0; } } #### # change temperature differential values according to time of day # if ($Startup or $Reload or new_minute 10){ if ($warmer){ if ($isday and time_greater_than("8:30 AM")){ $diff_off = $diff_off_day ; } else { $diff_off = $diff_off_night ; } } elsif (!$winter){ if (time_greater_than("6:00 PM") or time_less_than("8:00 AM")){ $diff_off = $diff_off_night ; } else { $diff_off = $diff_heat; } } $diff_on = $diff_off + $diff_o ; $diff_med = $diff_on + $diff_2 ; $diff_high = $diff_med + $diff_3 ; log_fan_settings() if $fan_test ; } if (new_minute 10){ # only check every 10 minutes, after temperature # reading have completed # change tmin_inside and tmax_inside if ($warmer and !$hot and !$heat_flag){ run_after_delay 10, sub { if(($outside_t > $outside_max_c) and $tmin_inside != $Tmin_i_L){ $tmin_inside = $Tmin_i_L; $tmax_inside = $Tmax_i_L; print_log "I tmin_inside= $tmin_inside"; } if(($outside_t < $outside_min_c) and $tmin_inside != $Tmin_i_H){ $tmin_inside = $Tmin_i_H; $tmax_inside = $Tmax_i_H; print_log "II tmin_inside= $tmin_inside"; } } }elsif ($hot){ # change tmin_inside and tmax_inside, hot weather run_after_delay 10, sub { if (($outside_t > $outside_max_h) and ($tmin_inside > $Tmin_i) and !$humid_flag){ $tmin_inside = $HTmin_i_L; $tmax_inside = $HTmax_i_L; print_log "III tmin_inside= $tmin_inside"; } elsif (($outside_t < $outside_min_h) and ($tmin_inside < $HHTmin_i_H ) and $humid_flag){ $tmin_inside = $HHTmin_i_L; $tmax_inside = $HHTmax_i_L; print_log "IV tmin_inside= $tmin_inside (humid)"; } elsif (($outside_t < $outside_min_h) and ($tmin_inside < $HTmin_i_H ) and !$humid_flag){ $tmin_inside = $HTmin_i_H; $tmax_inside = $HTmax_i_H; print_log "V tmin_inside= $tmin_inside"; } elsif ($humid_flag and $tmin_inside != $HHTmin_i_H){ $tmin_inside = $HHTmin_i_H; $tmax_inside = $HHTmax_i_H; print_log "VI tmin_inside= $tmin_inside (humid)"; } } } else { if ( $tmin_inside < $Tmin_i_L ){ $tmin_inside = $Tmin_i_H; $tmax_inside = $Tmax_i_H; print_log "VII tmin_inside= $tmin_inside (humid)"; } } log_fan_settings() if $fan_test ; ############ ## Attic fan ############ # cool if ($hot ){ run_after_delay 25, sub { if (($inside_t > ($tmin_inside + $diff_o)) #and (($outside_t + $diff_a) < ($inside_t + $diff_2)) and (($outside_t + $diff_a) < $LR_t) ){ $start_atticfan_cool = 1; } if ((($inside_t < $tmin_inside) or ($outside_t+$diff_a > $LR_t) or ($isday and (($diff_t3 + $diff_off) > 0)) or ($outside_t + $diff_a > $inside_t))){ $start_atticfan_cool = 0; } if ( $start_atticfan_cool and (state $Attic_Fan eq OFF)){ set $Attic_Fan ON; print_log "log=$testlog Attic fan ON, cool" if $istest; } elsif ( !$start_atticfan_cool and (state $Attic_Fan eq ON) and (state $House_Fan eq OFF)){ set $Attic_Fan OFF; print_log "log=$testlog Attic fan OFF, cool" if $istest; } print_log "start_atticfan_cool= $start_atticfan_cool" if $fan_test ; } } ############ # warmup with outside air if (!$hot){ # don't warmup during this time run_after_delay 20, sub { if (( $diff_t > $diff_off ) and ($inside_t < $outside_t) and !($diff_t2 < 0) and ($inside_t < $tmin_inside ) and !$humid_flag ){ $start_atticfan_heat = 1; } if ((($diff_t < $diff_off ) or ($inside_t > $outside_t) or (($diff_t3 < 0) and ($diff_t2 < 0)) or ($inside_t > $tmin_inside ))){ $start_atticfan_heat = 0; } if ( $start_atticfan_heat and !(state $Attic_Fan eq ON)){ set $Attic_Fan ON; print_log "log=$testlog Attic Fan ON, heat" if $istest; }elsif ( !$start_atticfan_heat and (inactive $timer_fans) and !$fanflag and !(state $Attic_Fan eq OFF)){ set $Attic_Fan OFF; print_log "log=$testlog Attic Fan OFF, heat" if $istest; } print_log "start_atticfan_heat= $start_atticfan_heat" if $fan_test ; } # end delay loop } # ############### # House Fan # temperature control - warming ########### # start fan, warmup with outside air if ( !$hot ){ run_after_delay 15, sub { if (( $inside_t < $tmin_inside ) and ($diff_t > $diff_on) and !($diff_t2 < 0) and ($outside_t > $LR_t)){ $start_housefan_heat = 1; } if (( $diff_t < $diff_off ) or ($inside_t > $tmax_inside) or (($diff_t3 < 0) and ($diff_t2 < 0)) or ($outside_t < $LR_t )){ $start_housefan_heat = 0; } if (($diff_t > $diff_high) and ($inside_t < $tmin_inside)){ $housefan_heat_high = 1; }else{ $housefan_heat_high = 0; } if (($diff_t > $diff_med) and ($inside_t < $tmax_inside )){ $housefan_heat_med = 1; }else{ $housefan_heat_med = 0; } if ($diff_t < ($diff_med - $diff_off)){ $housefan_heat_low = 1; }else{ $housefan_heat_low = 0; } if ( $start_housefan_heat ){ if ( !$fanflag ){ $fanflag = 1; print_log "log=$testlog House Fan on, warmup"; } if ( $housefan_heat_high ){ set_speed($high); } elsif ( $housefan_heat_med ){ set_speed($med); } elsif ( $housefan_heat_low ){ set_speed($low); } }elsif ($fanflag or state $House_Fan eq ON ) { # turn fan off $fanflag = 0; set_speed(OFF); print_log "log=$testlog House Fan off, warmup"; } log_fan_settings() if $fan_test ; } # end delay loop } ############### # House Fan # temperature control - cool ########### # start fan if ( $warmer ){ # only cool during summer dates run_after_delay 15, sub { # Fan ON conditions if (( $inside_t > ($tmin_inside + $diff_off)) and ($diff_t < -$diff_on) and (($outside_t + $diff_o) < $LR_t)){ $start_housefan_cool = 1; } # Fan OFF conditions if (( $diff_t > -$diff_off ) or ($inside_t < $tmin_inside) or ($LR_t < $tmin_inside) or ($diff_t2 > $diff_warming # allow for warming trend and $diff_t3 > $diff_warming ) or ($outside_t > ($LR_t - $diff_o))){ $start_housefan_cool = 0; } # Fan speed conditions if (((( $diff_t < -$diff_high ) and ( $inside_t > $tmax_inside )) or ( $inside_t > ( $tmin_inside + $diff_high ))) and ( $inside_t > ( $tmin_inside + $diff_med ))){ $housefan_cool_high = 1; }else{ $housefan_cool_high = 0; } if (($diff_t < -$diff_med) and ($inside_t > ($tmin_inside + $diff_2))){ $housefan_cool_med = 1; }else{ $housefan_cool_med = 0; } # Run fan if ( $start_housefan_cool ){ if ( !$fanflag ){ $fanflag = 1; print_log "Fans on: Cooling"; } if ( $housefan_cool_high ){ set_speed($high); } elsif ( $housefan_cool_med){ set_speed($med); } else { set_speed($low); } }else { set_speed(OFF); $fanflag = 0; } log_fan_settings() if $fan_test ; } # end sub loop } # end summer if loop } # end new_minute sub set_speed { my $speed = $_[0] ; if (( $speed eq $high ) and ( $fspeed ne $high )){ set_high(); } elsif (( $speed eq $med ) and ( $fspeed ne $med )){ set_med(); } elsif (( $speed eq $low ) and ( $fspeed ne $low )){ set_low(); } elsif (( $speed eq OFF ) and ( $fspeed ne OFF )){ set_off(); } } sub set_high { set $HFanH ON; $fspeed = $high; print_log "log=$testlog House Fan on High"; } sub set_med { set $HFanM ON; $fspeed = $med; set $House_Fan_3 OFF; print_log "log=$testlog House Fan on Medium"; } sub set_low { set $HFanL ON; $fspeed = $low; set $hFanl OFF; print_log "log=$testlog House Fan on Low"; } sub set_off { set $HFan OFF ; $fspeed = OFF; print_log "log=$testlog House Fan OFF"; } sub log_fan_settings { print_log "Current values:"; print_log "diff_on= $diff_on, diff_med= $diff_med, diff_high= $diff_high"; print_log "start_housefan_cool= $start_housefan_cool"; print_log "housefan_cool_high= $housefan_cool_high"; print_log "housefan_cool_med= $housefan_cool_med"; } |