O'Reilly Hacks
oreilly.comO'Reilly NetworkSafari BookshelfConferences Sign In/My Account | View Cart   
Book List Learning Lab PDFs O'Reilly Gear Newsletters Press Room Jobs  


 
Buy the book!
Smart Home Hacks
By Gordon Meyer
October 2004
More Info

HACK
#68
Adapt Sprinkler Schedules and Solar Water Heating to Available Sunlight
If you have a solar-assisted water heater, or if you want to adapt your garden watering schedule to the day's conditions, this hack will get you started in the right direction.
The Code
[Discuss (0) | Link to this hack]

The Code

This code demonstrates the heuristics discussed in the previous sections, but it is only an illustration of how to approach the problem and implement your own threshold and logic. You must tailor it to your site to get the results you want. It's written in Visual Basic for use with a home automation program that I've written for my own use (shown in ), so you can't just cut and paste the code. But it will get you started, and that's all it is intended to do.

Figure 1. The forecast and calculated events

TIP

I'm not a professional programmer, so please don't contact me with questions about coding and style.

Here's the procedure that implements the algorithms discussed earlier. To begin, irrigation and boiler events that are already scheduled are removed. This is an important step to remember when you implement your own system, particularly if you'll be polling for new weather data more than once a day.

	Public Sub IrrigationAndHotWater() 
	RemoveEvent "Irrigation"
	RemoveEvent "Boiler"

This code segment schedules irrigation based on the current month:

	Select Case Month(Now) 
	Case 6, 7 'Summer: Irrigation every day, HW boiler off During June, July–irrigate every day: 
	For Wkday = 1 To 7 
	ScheduleDrippers (Wkday) 'Drip every day 
	Next 
	ScheduleBotSprinklers (vbMonday) 'sub to irrigate turn bottom sprinkler
	zone on Monday, Wed, Sat 
	ScheduleBotSprinklers (vbWednesday) 
	ScheduleTopSprinklers (vbSaturday) 
	ScheduleMidSprinklers (vbSaturday) 'similarly, turn middle sprinklers zone on 
Saturday etc. 
	ScheduleBotSprinklers (vbSaturday) 
	Case 8 'Summer: Irrigation every day, HW boiler off 'On August, the hottest 
	month here, do some extra irrigation 
	For Wkday = 1 To 7 
	ScheduleDrippers (Wkday) 'Drip every day 
	Next 
	ScheduleTopSprinklers (vbSaturday)

	ScheduleTopSprinklers (vbWednesday)
	ScheduleMidSprinklers (vbSaturday)
	ScheduleMidSprinklers (vbWednesday)
	For Wkday = 1 To 5
	If DaysForecast(Wkday).Hi > 32 Or _
	DaysForecast(Wkday).Day = "2" Or _
	DaysForecast(Wkday).Day = "4" Or _
	DaysForecast(Wkday).Day = "7" Then
	ScheduleBotSprinklers (DaysForecast(Wkday).Day)
	End If
	Next

During December, January, and February, turn on the boiler every day for which the forecast contains the word rain, shower, cold, or cloud. If the forecast contains hot, warm, or pleasant, the boiler is not turned off, as the solar panel takes over on those days:

	Case 12, 1, 2 'Winter: HW on every day, irrigation off

	For Wkday = 1 To 5 'For each day forecasted:

	If DaysForecast(Wkday).Hi < 10 Or _
	CBool(InStr(1, DaysForecast(Wkday).Condition, "rain",
	vbTextCompare)) Or _
	CBool(InStr(1, DaysForecast(Wkday).Condition, "shower",
	vbTextCompare)) Or _
	CBool(InStr(1, DaysForecast(Wkday).Condition, "cold",
	vbTextCompare)) Or _
	CBool(InStr(1, DaysForecast(Wkday).Condition, "cloud",
	vbTextCompare)) And Not _
	CBool(InStr(1, DaysForecast(Wkday).Condition, "warm",
	bTextCompare)) And Not _
	CBool(InStr(1, DaysForecast(Wkday).Condition, "hot",
	vbTextCompare)) And Not _
	DaysForecast(Wkday).Hi > 25 And Not _
	CBool(InStr(1, DaysForecast(Wkday).Condition, "pleasant",
	vbTextCompare)) Then 'If its cold, raining or cloudy:
	ScheduleHotWater DaysForecast(Wkday).Day 'schedule the hot water for this
	day
	End If
	Next
	' For Wkday = 1 To 7
	' ScheduleHotWater (Wkday)
	' Next
	Case Else 'Check weather. Base irrigation and HW on weather
	'The following code creates a schedule for hot water boiler and lawn
	irrigation
	'based on the weather data

	'First, the HW boiler:
	NumOfRainDays = 0 'used for irrigation algorithm.
	NumOfCloudyDays = 0

	For Wkday = 1 To 5 'For each day forecasted:
	If DaysForecast(Wkday).Hi < 10 Or _
	CBool(InStr(1, DaysForecast(Wkday).Condition, "rain",
	vbTextCompare)) Or _
	CBool(InStr(1, DaysForecast(Wkday).Condition, "shower",
	vbTextCompare)) Or _
	CBool(InStr(1, DaysForecast(Wkday).Condition, "cold",
	vbTextCompare)) Or _
	CBool(InStr(1, DaysForecast(Wkday).Condition, "cloud",
	vbTextCompare)) And Not _
	CBool(InStr(1, DaysForecast(Wkday).Condition, "warm",
	vbTextCompare)) And Not _
	CBool(InStr(1, DaysForecast(Wkday).Condition, "hot",
	vbTextCompare)) And Not _
	DaysForecast(Wkday).Hi > 25 And Not _
	CBool(InStr(1, DaysForecast(Wkday).Condition, "pleasant",
	vbTextCompare)) Then 'If its cold, raining or cloudy:
	ScheduleHotWater DaysForecast(Wkday).Day 'schedule the hot
	water for this day
	End If
	If CBool(InStr(1, DaysForecast(Wkday).Condition, "rain",
	vbTextCompare)) Or _
	CBool(InStr(1, DaysForecast(Wkday).Condition, "shower",
	vbTextCompare)) Then
	NumOfRainDays = NumOfRainDays + 1
	End If
	If CBool(InStr(1, DaysForecast(Wkday).Condition, "cloud",
	vbTextCompare)) Then
	NumOfCloudyDays = NumOfCloudyDays + 1
	End If
	If DaysForecast(Wkday).Hi > 27 Then
	NumOfCloudyDays = NumOfCloudyDays - 1
	End If
	Next

Here is a formula I found useful if it is expected to rain. The number of rain days in the five-day forecast, multiplied by 3, plus the number of cloudy days reduces the amount of irrigation needed:

	IrrigationCoefficient = NumOfRainDays * 3 + NumOfCloudyDays
	'Number ranges between 0 (no rain, no clouds) and 15 (five days
	of rain).
	'Inbetween we have a mix of rainy days and cloudy days.
	'3 cloudy days are equivalent to 1 rain day.

	Select Case IrrigationCoefficient
	Case Is <= 0 'Clear, dry.
	For Wkday = 1 To 5
	ScheduleDrippers (DaysForecast(Wkday).Day)
	If DaysForecast(Wkday).Day = vbSaturday Then 
	'Sprinklers	ON Saturday
	ScheduleTopSprinklers (vbSaturday)
	ScheduleMidSprinklers (vbSaturday)
	End If

	If DaysForecast(Wkday).Day = vbMonday Or
	DaysForecast(Wkday).Day = vbSaturday _
	Or DaysForecast(Wkday).Hi > 30 Then
	ScheduleBotSprinklers (DaysForecast(Wkday).Day)
	End If
	Next
	Case 1, 2, 3
	' dry to cloudy
	For Wkday = 1 To 5
	If Not CBool(InStr(1, DaysForecast(Wkday).Condition,
	"cloud", vbTextCompare)) Or _
	CBool(InStr(1, DaysForecast(Wkday).Condition, "hot",
	vbTextCompare)) Then 'no clouds
	ScheduleDrippers (DaysForecast(Wkday).Day)
	If DaysForecast(Wkday).Day = vbSaturday Then
	'Sprinklers ON Saturday
	ScheduleTopSprinklers (vbSaturday)
	ScheduleMidSprinklers (vbSaturday)
	ScheduleBotSprinklers (vbSaturday)
	End If
	End If
	If Not CBool(InStr(1, DaysForecast(Wkday).Condition,
	"cloud", vbTextCompare)) Or _
	CBool(InStr(1, DaysForecast(Wkday).Condition,
	"hot", vbTextCompare)) Or _
	DaysForecast(Wkday).Hi > 30 Then
	ScheduleBotSprinklers (DaysForecast(Wkday).Day)
	End If
	Next

	Case 4, 5, 6, 7, 8
	' 1 day rainy and others cloudy
	For Wkday = 1 To 5
	If Not CBool(InStr(1, DaysForecast(Wkday).Condition,
	"Rain", vbTextCompare)) And _
	Not CBool(InStr(1, DaysForecast(Wkday).Condition,
	"Shower", vbTextCompare)) And _
	Not CBool(InStr(1, DaysForecast(Wkday).Condition, "cold",
	vbTextCompare)) And _
	Not CBool(InStr(1, DaysForecast(Wkday).Condition,
	"cloud", vbTextCompare)) Then
	If DaysForecast(Wkday).Day = vbSaturday Then
	Sprinklers ON Saturday
	ScheduleTopSprinklers (vbSaturday)
	ScheduleMidSprinklers (vbSaturday)
	ScheduleBotSprinklers (vbSaturday)
	End If

	If DaysForecast(Wkday).Day = vbMonday Then
	'Sprinklers ON Saturday
	ScheduleBotSprinklers (vbMonday)
	End If

	If DaysForecast(Wkday).Day = vbWednesday Then
	'Sprinklers ON Saturday
	ScheduleBotSprinklers (vbWednesday)
	End If
	End If
	Next

	'Other cases have enough rain
	End Select
	End Select
	' Now add manual irrigation
	For Wkday = vbSunday To vbSaturday
	If CBool((Val(GetSetting("Homer", "Forecast", "Add" &
	CWeekDay(Wkday))) And 1) = 1) Then ScheduleTopSprinklers (Wkday)
	If CBool((Val(GetSetting("Homer", "Forecast", "Add" &
	CWeekDay(Wkday))) And 2) = 2) Then ScheduleMidSprinklers (Wkday)
	If CBool((Val(GetSetting("Homer", "Forecast", "Add" &
	CWeekDay(Wkday))) And 4) = 4) Then ScheduleBotSprinklers (Wkday)
	If CBool((Val(GetSetting("Homer", "Forecast", "Add" &
	CWeekDay(Wkday))) And 8) = 8) Then ScheduleDrippers (Wkday)
	If CBool((Val(GetSetting("Homer", "Forecast", "Add" &
	CWeekDay(Wkday))) And 16) = 16) Then ScheduleHotWater (Wkday)
	Next Wkday
	End Sub


O'Reilly Home | Privacy Policy

© 2007 O'Reilly Media, Inc.
Website: | Customer Service: | Book issues:

All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.