Weather.com Plug-in

HouseBot Plugin Development Discussions.
Steve Horn
HouseBot Guru
Posts: 747
Joined: Wed Apr 02, 2003 8:10 pm
Location: Pelham AL

Re: Weather.com Plug-in

Post by Steve Horn »

That's the one I've been using. Yes, only LAT & Long. I tried others (city, zip) but they did not yield any XML. And this one does not list current conditions. The URL that does (http://www.weather.gov/xml/current_obs/KEET.xml (where KEET is the local weather station here)is not an XML output... at least not that I can see unless I view source.
Steve
Osler
HouseBot Guru
Posts: 742
Joined: Fri Feb 03, 2006 11:18 pm

Re: Weather.com Plug-in

Post by Osler »

Well, Yahoo does give current conditions. Perhaps we can use the Yahoo site for the current conditions and use the NOAA site for forecast data. I just switched back to Yahoo last night and it only gives me tomorrows forecast.

Osler
Steve Horn
HouseBot Guru
Posts: 747
Joined: Wed Apr 02, 2003 8:10 pm
Location: Pelham AL

Re: Weather.com Plug-in

Post by Steve Horn »

I haven't looked at the Yahoo data yet. I figured it would need to be two different VBScript parsing routines anyway.
Steve
Osler
HouseBot Guru
Posts: 742
Joined: Fri Feb 03, 2006 11:18 pm

Re: Weather.com Plug-in

Post by Osler »

Ok, I've got this working in a rudimentary fashion. It is not complete, but I'll throw out what I've got. The script first gets data from Yahoo using your zip. Yahoo actually returns your lat/long with their data so I turn around and use that to plug into the NOAA url and get the 7 day forecast. I need to get everything put into a variable, but it is close:

Code: Select all

'==========================================================================================================================
' Title: Yahoo Weather Device
' Author: Osler
' Language: VBScript
' Description: A script to gather weather data from the Yahoo RSS feed. Provides current weather conditions and a 1 day
' forecast. WeatherNumber and ForecastWeatherNumber correspond to one of the included .gif files to provide an image
' representation of the current or forecasted weather. All images are from Yahoo's website. Please see the terms and
' conditions of using the YahooWeather RSS feed at http://developer.yahoo.com/weather/
' Device Name: CurrentWeather
' Properties:			CWZipCode (should be populated with your 5-digit zipcode prior to running script)
'				CWUnits	(should be populated with either f for Farenheight or c for Celsius prior to running script)
'				CWWindChill
'				CWWindSpeed
'				CWWindDirection
'				CWHumidity
'				CWBarometer
'				CWRising
'				CWWeather
'				CWTemperature
'				CWLocation
'				CWTime
'				CWWeatherNumber
'				CWDay
'				CWDate
'				CWHigh
'				CWLow
'				CWForecastDay
'				CWForecastDate
'				CWForecastLow
'				CWForecastHigh
'				CWForecastWeather
'				CWForecastWeatherNumber
'==========================================================================================================================
'On Error Resume Next

Dim XMLHTTP
Dim YahooURL, NOAAURL
Dim ZipCode
Dim Units
Dim I
Dim YahooXML, NOAAXML
Dim xmlData
Dim City, State, Country
Dim Units_Temp, Units_Dist, Units_Pres, Units_Spd
Dim WindChill, WindDirection, WindSpeed
Dim Humidity, Visibility, Pressure, Rising
Dim Sunrise, Sunset
Dim Latitude, Longitude
Dim Condition, Code, Temperature, LastUpdate
Dim Forecast(6,5)

YahooURL = "http://xml.weather.yahoo.com/forecastrss"
ZipCode = "75022"
Units = "f"
'ZipCode = GetPropertyValue("CurrentWeather.CWZipCode")
'Units = GetPropertyValue("CurrentWeather.CWUnits")
YahooURL = YahooURL & "?p=" & ZipCode & "&u=" & Units

Main

Private Sub Main()
	YahooXML = GetXMLData(YahooURL)
	If YahooXML <> "" Then
		ParseYahooXML
		'SetHouseBotValues
	End If
	If Latitude <> "" And Longitude <> "" Then
		NOAAURL = "http://forecast.weather.gov/MapClick.php?lat=" & Latitude & "&lon=" & Longitude & "&FcstType=dwml"
		NOAAXML = GetXMLData(NOAAURL)
		'Debug.Write NOAAXML
		ParseNOAAXML
	End If
End Sub

Private Function GetXMLData(ByVal URL)
	Set XMLHTTP = CreateObject("microsoft.xmlhttp")
	XMLHTTP.Open "GET", URL, True
	XMLHTTP.send
	I = 0
	Do
		WScript.Sleep(500)
		If XMLHTTP.readyState = 4 Then
			Exit Do
		End If
		If I = 8 Then
			Exit Function
		End If
		I = I + 1
	Loop
	GetXMLData = XMLHTTP.responseText
	Set XMLHTTP = Nothing
End Function

Private Sub ParseNOAAXML()
	On Error Resume Next
	Set xmlData = CreateObject("Microsoft.XMLDom")
	xmlData.async = "false"
	xmlData.loadXML(NOAAXML)
	
	Dim Node
	Dim ChildNode
	
	For Each Node In xmlData.getElementsByTagName("data").item(0).childNodes
		Select Case Node.nodeName
			Case "location"
				For Each ChildNode In Node.childNodes
					Select Case ChildNode.nodeName
						Case "location-key"
						
						Case "description"
						
						Case "point"
						
						Case "city"
						
						Case "height"
					End Select
				Next
				
			Case "time-layout"
				If Node.firstChild.nodeName = "layout-key" And InStr(Node.firstChild.text, "n13-1") Then
					For Each ChildNode In Node.childNodes
						Select Case ChildNode.nodeName
							Case "start-valid-time"
								'Debug.WriteLine ChildNode.attributes.getNamedItem("period-name").text
						End Select
					Next
				End If
				If Node.firstChild.nodeName = "layout-key" And InStr(Node.firstChild.text, "n7-1") Then
					For Each ChildNode In Node.childNodes
						Select Case ChildNode.nodeName
							Case "start-valid-time"
								'Debug.WriteLine ChildNode.attributes.getNamedItem("period-name").text
						End Select
					Next
				End If
				If Node.firstChild.nodeName = "layout-key" And InStr(Node.firstChild.text, "n6-2") Then
					For Each ChildNode In Node.childNodes
						Select Case ChildNode.nodeName
							Case "start-valid-time"
								'Debug.WriteLine ChildNode.attributes.getNamedItem("period-name").text
						End Select
					Next
				End If
				
			Case "parameters"
				For Each ChildNode In Node.childNodes
					Select Case ChildNode.nodeName
						Case "temperature"
							If ChildNode.attributes.getNamedItem("type").text = "maximum" Then
								'Debug.WriteLine "Maximum Temperature"
								For I = 1 To 7
									'Debug.WriteLine ChildNode.childNodes.item(I).text & Chr(176) & "F"
								Next
								
							ElseIf ChildNode.attributes.getNamedItem("type").text = "minimum" Then
								'Debug.WriteLine "Minimum Temperature"
								For I = 1 To 6
									'Debug.WriteLine ChildNode.childNodes.item(I).text & Chr(176) & "F"
								Next
							End If
						
						Case "probability-of-precipitation"
							For I = 1 To 13
								If ChildNode.childNodes.item(I).text <> "" Then
									'Debug.WriteLine ChildNode.childNodes.item(I).text & " %"
								Else
									'Debug.WriteLine "0 %"
								End If
							Next
							
						Case "weather"
							For I = 1 To 13
								Debug.WriteLine ChildNode.childNodes.item(I).attributes.getNamedItem("weather-summary").text
							Next
					End Select
				Next
		End Select
	Next
	
	
	

End Sub

Private Sub ParseYahooXML()
	On Error Resume Next
	Set xmlData = CreateObject("Microsoft.XMLDom")
	xmlData.async = "false"
	xmlData.loadXML(YahooXML)

	City = xmlData.getElementsByTagName("yweather:location").item(0).getAttribute("city")
	State = xmlData.getElementsByTagName("yweather:location").item(0).getAttribute("region")
	Country = xmlData.getElementsByTagName("yweather:location").item(0).getAttribute("country")
	Units_Temp = xmlData.getElementsByTagName("yweather:units").item(0).getAttribute("temperature")
	Units_Dist = xmlData.getElementsByTagName("yweather:units").item(0).getAttribute("distance")
	Units_Pres = xmlData.getElementsByTagName("yweather:units").item(0).getAttribute("pressure")
	Units_Spd = xmlData.getElementsByTagName("yweather:units").item(0).getAttribute("speed")
	WindChill = xmlData.getElementsByTagName("yweather:wind").item(0).getAttribute("chill") & Chr(176) & Units_Temp
	WindSpeed = xmlData.getElementsByTagName("yweather:wind").item(0).getAttribute("speed") & " " & Units_Spd
	WindDirection = xmlData.getElementsByTagName("yweather:wind").item(0).getAttribute("direction")
	Humidity = xmlData.getElementsByTagName("yweather:atmosphere").item(0).getAttribute("humidity") & " %"
	Visibility = xmlData.getElementsByTagName("yweather:atmosphere").item(0).getAttribute("visibility")
	Pressure = xmlData.getElementsByTagName("yweather:atmosphere").item(0).getAttribute("pressure") & " " & Units_Pres
	Rising = xmlData.getElementsByTagName("yweather:atmosphere").item(0).getAttribute("rising")
	If CInt(Rising) = 0 Then
		Rising = "Steady"
	ElseIf CInt(Rising) = 1 Then
		Rising = "Rising"
	ElseIf CInt(Rising) = 2 Then
		Rising = "Falling"
	End If
	Sunrise = xmlData.getElementsByTagName("yweather:astronomy").item(0).getAttribute("sunrise")
	Sunset = xmlData.getElementsByTagName("yweather:astronomy").item(0).getAttribute("sunset")
	Latitude = xmlData.getElementsByTagName("geo:lat").item(0).text
	Longitude = xmlData.getElementsByTagName("geo:long").item(0).text
	Condition = xmlData.getElementsByTagName("yweather:condition").item(0).getAttribute("text")
	Code = xmlData.getElementsByTagName("yweather:condition").item(0).getAttribute("code")
	If Len(Code) <> 2 Then
		Code = "0" & Code
	End If
	Temperature = xmlData.getElementsByTagName("yweather:condition").item(0).getAttribute("temp") & Chr(176) & Units_Temp
	LastUpdate = xmlData.getElementsByTagName("yweather:condition").item(0).getAttribute("date")
	For I = 0 To 1
		Forecast(I, 0) = xmlData.getElementsByTagName("yweather:forecast").item(I).getAttribute("day")
		Forecast(I, 1) = xmlData.getElementsByTagName("yweather:forecast").item(I).getAttribute("date")
		Forecast(I, 2) = xmlData.getElementsByTagName("yweather:forecast").item(I).getAttribute("low")
		Forecast(I, 3) = xmlData.getElementsByTagName("yweather:forecast").item(I).getAttribute("high")
		Forecast(I, 4) = xmlData.getElementsByTagName("yweather:forecast").item(I).getAttribute("text")
		Forecast(I, 5) = xmlData.getElementsByTagName("yweather:forecast").item(I).getAttribute("code")
		If Len(Forecast(I,5)) <> 2 Then
			Forecast(I,5) = "0" & Forcast(I,5)
		End If
	Next
	Set xmlData = Nothing
End Sub

Private Sub SetHouseBotValues()
	Call SetPropertyValue(".CWVisibility", Visibility)
	Call SetPropertyValue(".CWWindChill", WindChill)
	Call SetPropertyValue(".CWWindSpeed", WindSpeed)
	Call SetPropertyValue(".CWWindDirection", WindDirection)
	Call SetPropertyValue(".CWHumidity", Humidity)
	Call SetPropertyValue(".CWBarometer", Pressure)
	Call SetPropertyValue(".CWRising", Rising)
	Call SetPropertyValue(".CWWeather", Condition)
	Call SetPropertyValue(".CWTemperature", Temperature)
	Call SetPropertyValue(".CWLocation", City & ", " & State & " (" & Country & ")")
	Call SetPropertyValue(".CWTime", LastUpdate)
	Call SetPropertyValue(".CWWeatherNumber", "C:\Program Files\HouseBot\Config\Themes\Weather Images\" & Code & ".png")
	Call SetPropertyValue(".CWDay", Forecast(0,0))
	Call SetPropertyValue(".CWDate", Forecast(0,1))
	Call SetPropertyValue(".CWLow", Forecast(0,2) & Chr(176) & Units_Temp)
	Call SetPropertyValue(".CWHigh", Forecast(0,3) & Chr(176) & Units_Temp)
	Call SetPropertyValue(".CWForecastDay", Forecast(1,0))
	Call SetPropertyValue(".CWForecastDate", Forecast(1,1))
	Call SetPropertyValue(".CWForecastLow", Forecast(1,2) & Chr(176) & Units_Temp)
	Call SetPropertyValue(".CWForecastHigh", Forecast(1,3) & Chr(176) & Units_Temp)
	Call SetPropertyValue(".CWForecastWeather", Forecast(1,4))
	Call SetPropertyValue(".CWForecastWeatherNumber", "C:\Program Files\HouseBot\Config\Themes\Weather Images\" & Forecast(1,5) & ".png")
End Sub
Osler
markd
Advanced Member
Posts: 234
Joined: Fri Jul 21, 2006 4:32 pm

Re: Weather.com Plug-in

Post by markd »

Wow, your vbscript is pretty different from what will run on my system. . . is it dependent on the OS? (Win2k for me)

edit- ok, had a couple things that got me. . . your debug and sleep statements were different, and I missed the lack of a device name where you were assigning the properties.. . . I think I have it now! A good start.

Thanks!

Markd
Steve Horn
HouseBot Guru
Posts: 747
Joined: Wed Apr 02, 2003 8:10 pm
Location: Pelham AL

Re: Weather.com Plug-in

Post by Steve Horn »

Cool! Still digesting it but I see a potential problem with the NOAA parse: The 'n13-1' layout key isn't always 13. Right now its 14 - "Tonight" thru "Tues". And based on some of the "snapshots" I took last week, the n7 and n6 are moving targets too:

(pasted from an XLS I had started)
--------------------------------------
Day Pull Time Time Series 1 Data 1 (label) Time Series 2 Data 2 Time Series 3 Data 3
Tues ? pm N14 Tonite->Tue N7-1 Min temps N7-2 Max temps

Wed 11am N13 This Aft->Sun N7-1 Max temps N6-2 Min temps

Wed 6pm N14 Tonite->Wed N7-1 Min temps N7-2 Max temps
Wed 10pm N14 Overnite->Wed N7-1 Min temps N7-2 Max temps

Thu 7am N13 Today->Wed N7-1 Max temps N6-2 Min temps
Thu 9:30am N13 Today->Wed N7-1 Max temps N6-2 Min temps
Thu 11am N13 This Aft->Wed N7-1 Max temps N6-2 Min temps

Thu 12noon N13 This Aft->Wed N7-1 Max temps N6-2 Min temps
2pm N13 This Aft->Wed N7-1 Max temps N6-2 Min temps
5pm N15 late aft, tonight->fri…thurs N8 Max temps N7-2 Min temps

Fri 830am N13 Today-tonite-thurs N7-1 Max temps N6-2 Min temps
------------------------------------------------------------------

There's a pattern based on time-of-day (or possibly when the forecast is updated), but I wasn't able to see it yet.

But this is certainly much further than I've gotten. I'm still on a XML parsing learning curve. Way down on it.
I need to build the HB device and see how it acts with the Yahoo data.
Steve
markd
Advanced Member
Posts: 234
Joined: Fri Jul 21, 2006 4:32 pm

Re: Weather.com Plug-in

Post by markd »

This works to dynamically get all the values-

Case "parameters"
For Each ChildNode In Node.childNodes
Select Case ChildNode.nodeName
Case "temperature"
If ChildNode.attributes.getNamedItem("type").text = "maximum" Then
'Debug.WriteLine "Maximum Temperature"
i=0
For Each text in ChildNode.childNodes
i=i+1
msgbox ChildNode.childNodes.item(i).text
'Debug.WriteLine ChildNode.childNodes.item(i).text & Chr(176) & "F"
Next

and when you exit the loop, you can check the value of i to find out how many items there were.
Osler
HouseBot Guru
Posts: 742
Joined: Fri Feb 03, 2006 11:18 pm

Re: Weather.com Plug-in

Post by Osler »

Very nice, gentlemen. I just got home so don't think I will work on it tonight. I had seen the the n13 thingy was inconsistent as you pointed out. MarkD's solution is elegant and I will incorporate it. If you all come up with anything else, throw it here. No point in us duplicating work.

Osler
markd
Advanced Member
Posts: 234
Joined: Fri Jul 21, 2006 4:32 pm

Re: Weather.com Plug-in

Post by markd »

Hi Osler-

Ok, not more code, but studying a little this morning. . . I think I have this right. ..
The layout keys are going to change node names- you have

InStr(Node.firstChild.text, "n13-1")
InStr(Node.firstChild.text, "n7-1")
InStr(Node.firstChild.text, "n6-2")

in your case statement, but those aren't consistent. There is also redundancy- n13 is just a complete list of n7 and n6, interleaved.
I suggest ignoring the n13 section, and changing to n*-1 and n*-2, ie, don't match on the count. The true counts of those will come from my method above, if you need it. (starting to think you don't though- which case you could do the opposite and just read n1*-1)

It seems like -1 is always the max and -2 is the min- but I will need to check the data for the middle of the night, to see if it returns a min first there. that would throw a wrench in the works! Otherwise, I would just interleave the time-layout data back together, -1 into the evens, and -2 the odds.

I am leaning towards making the array large enough to hold the maximum number of slots returned (14?). I will only display a couple on my interface, and avoid having to deal with empty slots at the end.

Ok, time to hit the showers and go to work!

Markd
Steve Horn
HouseBot Guru
Posts: 747
Joined: Wed Apr 02, 2003 8:10 pm
Location: Pelham AL

Re: Weather.com Plug-in

Post by Steve Horn »

markd,
Nice catch - it does seem that the long time series (N13,14,15) can be eliminated by just dealing with the two short ones. I had totally missed that. Not sure about the min/max always being -1 and -2; will have to check it a few times. But that would also simplify locating the min and max in a consistent way. About the total collection range... I personally don't think it needs to go past what the old weather.com view did (Current conditions, Today + 4 days). If we get CC from Yahoo, then Today+4 from NOAA. that is enough. I doubt the forecasts beyond that are worth much anyway. But that's just me.
Steve
markd
Advanced Member
Posts: 234
Joined: Fri Jul 21, 2006 4:32 pm

Re: Weather.com Plug-in

Post by markd »

Agree about the length of data, but since someone else might want more, I figured why not write the script that way up front. . . I only show current and tomorrow, myself. . . for longer forecasts I'm online on a computer all the time anyways.
Steve Horn
HouseBot Guru
Posts: 747
Joined: Wed Apr 02, 2003 8:10 pm
Location: Pelham AL

Re: Weather.com Plug-in

Post by Steve Horn »

Works for me. But if the script is limited to the scope of the current weather.com feed the current HB device and properties can be "reused", thus not having to create a new HB device and properties (and redo panel controls for those new properties). Just a thought. Adding a bunch of new properties to a device is cumbersome IMO.
Steve
Osler
HouseBot Guru
Posts: 742
Joined: Fri Feb 03, 2006 11:18 pm

Re: Weather.com Plug-in

Post by Osler »

Ok, the script is working...for now. I'm not sure if it will break this evening.

I think what they are doing is swapping the order in which max and min temp data is being delivered. For instance, when the first entry is "This Afternoon", maximum temperature data has a layout key of k-p24-n[X entries]-1. At some point, "This Afternoon" rolls out of the forecast and then you are left with "Tonight" as the most current temperature forecast. When this happens, the maximum temperature data layout key turns into k-p24-n[X entries]-2 and the minimum temperature data layout key becomes k-p24-n[X entries]-1 (the final digit in the key appears to give the order that things are supposed to be displayed). It took a bit more code, but I am keeping maximum and minimum data seperate and keeping track of the order they're supposed to be displayed in (as indicated by the key). I'll have to see precisely how this works tonight.

Next up, I need to make a dictionary to convert the weather summary that is delivered into a standardized weather number that corresponds to the weather .png images most of us use.

Osler

Edit:

Added script for you to look at . It's not ready to plug into HB just yet, but you can follow the code:

Code: Select all

'==========================================================================================================================
' Title: Yahoo Weather Device
' Author: Osler
' Language: VBScript
' Description: A script to gather weather data from the Yahoo RSS feed. Provides current weather conditions and a 1 day
' forecast. WeatherNumber and ForecastWeatherNumber correspond to one of the included .gif files to provide an image
' representation of the current or forecasted weather. All images are from Yahoo's website. Please see the terms and
' conditions of using the YahooWeather RSS feed at http://developer.yahoo.com/weather/
' Device Name: CurrentWeather
' Properties:			CWZipCode (should be populated with your 5-digit zipcode prior to running script)
'				CWUnits	(should be populated with either f for Farenheight or c for Celsius prior to running script)
'				CWWindChill
'				CWWindSpeed
'				CWWindDirection
'				CWHumidity
'				CWBarometer
'				CWRising
'				CWWeather
'				CWTemperature
'				CWLocation
'				CWTime
'				CWWeatherNumber
'				CWDay
'				CWDate
'				CWHigh
'				CWLow
'				CWForecastDay
'				CWForecastDate
'				CWForecastLow
'				CWForecastHigh
'				CWForecastWeather
'				CWForecastWeatherNumber
'==========================================================================================================================
'On Error Resume Next

Dim XMLHTTP
Dim YahooURL, NOAAURL
Dim ZipCode
Dim Units
Dim I, D, N, P
Dim YahooXML, NOAAXML
Dim xmlData
Dim City, State, Country
Dim Units_Temp, Units_Dist, Units_Pres, Units_Spd
Dim WindChill, WindDirection, WindSpeed
Dim Humidity, Visibility, Pressure, Rising
Dim Sunrise, Sunset
Dim LayoutKey(1)
Dim Latitude, Longitude
Dim Condition, Code, Temperature, LastUpdate
Dim ForecastEntries(1)
Dim ForecastLayout0(6,4)	'0=Day, 1=Temp, 2=Precip, 3=WeatherDescription, 4=WeatherCode
Dim ForecastLayout1(6,4)
Dim Maximum, Minimum

YahooURL = "http://xml.weather.yahoo.com/forecastrss"
ZipCode = "75022"
Units = "f"
'ZipCode = GetPropertyValue("CurrentWeather.CWZipCode")
'Units = GetPropertyValue("CurrentWeather.CWUnits")
YahooURL = YahooURL & "?p=" & ZipCode & "&u=" & Units

Main

Private Sub Main()
	YahooXML = GetXMLData(YahooURL)
	If YahooXML <> "" Then
		ParseYahooXML
		'SetHouseBotValues
	End If
	If Latitude <> "" And Longitude <> "" Then
		NOAAURL = "http://forecast.weather.gov/MapClick.php?lat=" & Latitude & "&lon=" & Longitude & "&FcstType=dwml"
		NOAAXML = GetXMLData(NOAAURL)
		'Debug.Write NOAAXML
		ParseNOAAXML
		ProcessWeatherSummary
							Debug.WriteLine "Layout"
							Debug.WriteLine ForecastEntries(0)
							Debug.WriteLine ForecastEntries(1)
							For I = 0 To 6
								Debug.WriteLine CStr(I)
								Debug.WriteLine ForecastLayout0(I, 0) & ": " & ForecastLayout0(I, 1) & " " & ForecastLayout0(I, 2) & " " & ForecastLayout0(I, 3)
								Debug.WriteLine ForecastLayout1(I, 0) & ": " & ForecastLayout1(I, 1) & " " & ForecastLayout1(I, 2) & " " & ForecastLayout1(I, 3)
								Debug.WriteLine 
							Next

	End If
End Sub

Private Function GetXMLData(ByVal URL)
	Set XMLHTTP = CreateObject("microsoft.xmlhttp")
	XMLHTTP.Open "GET", URL, True
	XMLHTTP.send
	I = 0
	Do
		WScript.Sleep(500)
		If XMLHTTP.readyState = 4 Then
			Exit Do
		End If
		If I = 8 Then
			Exit Function
		End If
		I = I + 1
	Loop
	GetXMLData = XMLHTTP.responseText
	Set XMLHTTP = Nothing
End Function

Private Sub ParseNOAAXML()
	On Error Resume Next
	Set xmlData = CreateObject("Microsoft.XMLDom")
	xmlData.async = "false"
	xmlData.loadXML(NOAAXML)
	
	Dim Node
	Dim ChildNode
	
	For Each Node In xmlData.getElementsByTagName("data").item(0).childNodes
		Select Case Node.nodeName
			Case "location"
				For Each ChildNode In Node.childNodes
					Select Case ChildNode.nodeName
						Case "location-key"
						
						Case "description"
						
						Case "point"
						
						Case "city"
						
						Case "height"
					End Select
				Next
				
			Case "time-layout"
				If Node.firstChild.nodeName = "layout-key" And InStr(Node.firstChild.text, "k-p24h") > 0 And InStr(Node.firstChild.text, "-1") > 0 Then
					LayoutKey(0) = Node.firstChild.text
					ForecastEntries(0) = CInt(Right(Left(LayoutKey(0), 9), 1)) - 1
					I = 0
					For Each ChildNode In Node.childNodes
						Select Case ChildNode.nodeName
							Case "start-valid-time"
								ForecastLayout0(I, 0) = ChildNode.attributes.getNamedItem("period-name").text
						I = I + 1
						End Select
					Next
				End If
				
				If Node.firstChild.nodeName = "layout-key" And InStr(Node.firstChild.text, "k-p24h") > 0 And InStr(Node.firstChild.text, "-2") > 0 Then
					LayoutKey(1) = Node.firstChild.text
					ForecastEntries(1) = CInt(Right(Left(LayoutKey(1), 9), 1)) - 1
					I = 0
					For Each ChildNode In Node.childNodes
						Select Case ChildNode.nodeName
							Case "start-valid-time"
								ForecastLayout1(I, 0) = ChildNode.attributes.getNamedItem("period-name").text
						I = I + 1
						End Select
					Next
				End If
				
			Case "parameters"
				For Each ChildNode In Node.childNodes
					Select Case ChildNode.nodeName
						Case "temperature"
							If ChildNode.attributes.getNamedItem("type").text = "maximum" Then
								I = 0
								For Each A In ChildNode.childNodes
									If ChildNode.attributes.getNamedItem("time-layout").text = LayoutKey(0) Then
										Maximum = 0
										If A.nodeName = "value" Then
											ForecastLayout0(I, 1) = A.text
											If Units = "f" Then
												ForecastLayout0(I, 1) = ForecastLayout0(I, 1) & Chr(176) & "F"
											Else
												ForecastLayout0(I, 1) = Left(CStr((CInt(ForecastLayout0(I, 1)) - 32)*5/9), InStr(CStr((CInt(ForecastLayout0(I, 1)) - 32)*5/9), ".") - 1) & Chr(176) & "C"
											End If 
											I = I + 1
										End If
									End If
								Next
								I = 0
								For Each A In ChildNode.childNodes
									If ChildNode.attributes.getNamedItem("time-layout").text= LayoutKey(1) Then
										Maximum = 1
										If A.nodeName = "value" Then
											ForecastLayout1(I, 1) = A.text
											If Units = "f" Then
												ForecastLayout1(I, 1) = ForecastLayout1(I, 1) & Chr(176) & "F"
											Else
												ForecastLayout1(I, 1) = Left(CStr((CInt(ForecastLayout1(I, 1)) - 32)*5/9), InStr(CStr((CInt(ForecastLayout1(I, 1)) - 32)*5/9), ".") - 1) & Chr(176) & "C"
											End If 
											I = I + 1
										End If
									End If
								Next
							End If
								
							If ChildNode.attributes.getNamedItem("type").text = "minimum" Then
								I = 0
								For Each A In ChildNode.childNodes
									If ChildNode.attributes.getNamedItem("time-layout").text = LayoutKey(0) Then
										Minimum = 0
										If A.nodeName = "value" Then
											ForecastLayout0(I, 1) = A.text
											If Units = "f" Then
												ForecastLayout0(I, 1) = ForecastLayout0(I, 1) & Chr(176) & "F"
											Else
												ForecastLayout0(I, 1) = Left(CStr((CInt(ForecastLayout0(I, 1)) - 32)*5/9), InStr(CStr((CInt(ForecastLayout0(I, 1)) - 32)*5/9), ".") - 1) & Chr(176) & "C"
											End If 
											I = I + 1
										End If
									End If
								Next
								I = 0
								For Each A In ChildNode.childNodes
									If ChildNode.attributes.getNamedItem("time-layout").text = LayoutKey(1) Then
										Minimum = 1
										If A.nodeName = "value" Then
											ForecastLayout1(I, 1) = A.text
											If Units = "f" Then
												ForecastLayout1(I, 1) = ForecastLayout1(I, 1) & Chr(176) & "F"
											Else
												ForecastLayout1(I, 1) = Left(CStr((CInt(ForecastLayout1(I, 1)) - 32)*5/9), InStr(CStr((CInt(ForecastLayout1(I, 1)) - 32)*5/9), ".") - 1) & Chr(176) & "C"
											End If 
											I = I + 1
										End If
									End If
								Next
							End If

						
						Case "probability-of-precipitation"
							I = 0
							P = 0
							For Each A In ChildNode.childNodes
								If Maximum  = 0 Then
									If A.nodeName = "value" Then
										If I <= ForecastEntries(0) Then
											If A.text <> "" Then
												ForecastLayout0(I, 2) = A.text & "%"
											Else
												ForecastLayout0(I, 2) = "0%"
											End If
										Else
											If A.text <> "" Then
												ForecastLayout1(P, 2) = A.text & "%"
											Else
												ForecastLayout1(P, 2) = "0%"
											End If
											P = P + 1
										End If
										I = I + 1
									End If
								Else
									If A.nodeName = "value" Then
										If I <= ForecastEntries(1) Then
											If A.text <> "" Then
												ForecastLayout1(I, 2) = A.text & "%"
											Else
												ForecastLayout1(I, 2) = "0%"
											End If
										Else
											If A.text <> "" Then
												ForecastLayout0(P, 2) = A.text & "%"
											Else
												ForecastLayout0(P, 2) = "0%"
											End If
											P = P + 1
										End If
										I = I + 1
									End If
								End If
							Next
							
						Case "weather"
							I = 0
							P = 0
							For Each A In ChildNode.childNodes
								If Maximum  = 0 Then
									If A.nodeName = "weather-conditions" Then
										If I <= ForecastEntries(0) Then
											ForecastLayout0(I, 3) = A.attributes.getNamedItem("weather-summary").text
										Else
											ForecastLayout1(P, 3) = A.attributes.getNamedItem("weather-summary").text
											P = P + 1
										End If
										I = I + 1
									End If
								Else
									If A.nodeName = "value" Then
										If I <= ForecastEntries(1) Then
											ForecastLayout1(I, 3) = A.attributes.getNamedItem("weather-summary").text
										Else
											ForecastLayout0(P, 3) = A.attributes.getNamedItem("weather-summary").text
											P = P + 1
										End If
										I = I + 1
									End If
								End If
							Next
					End Select
				Next
		End Select
	Next	
End Sub

Private Sub ProcessWeatherSummary()
	For I = 0 To ForecastEntries(0)
		ForecastLayout0(I, 3) = Replace(ForecastLayout0(I, 3), "Chc", "Chance")
		ForecastLayout0(I, 3) = Replace(ForecastLayout0(I, 3), "Tstms", "T-storms")
	Next
	For I = 0 To ForecastEntries(0)
		ForecastLayout1(I, 3) = Replace(ForecastLayout1(I, 3), "Chc", "Chance")
		ForecastLayout1(I, 3) = Replace(ForecastLayout1(I, 3), "Tstms", "T-storms")
	Next
End Sub

Private Sub ParseYahooXML()
	On Error Resume Next
	Set xmlData = CreateObject("Microsoft.XMLDom")
	xmlData.async = "false"
	xmlData.loadXML(YahooXML)

	City = xmlData.getElementsByTagName("yweather:location").item(0).getAttribute("city")
	State = xmlData.getElementsByTagName("yweather:location").item(0).getAttribute("region")
	Country = xmlData.getElementsByTagName("yweather:location").item(0).getAttribute("country")
	Units_Temp = xmlData.getElementsByTagName("yweather:units").item(0).getAttribute("temperature")
	Units_Dist = xmlData.getElementsByTagName("yweather:units").item(0).getAttribute("distance")
	Units_Pres = xmlData.getElementsByTagName("yweather:units").item(0).getAttribute("pressure")
	Units_Spd = xmlData.getElementsByTagName("yweather:units").item(0).getAttribute("speed")
	WindChill = xmlData.getElementsByTagName("yweather:wind").item(0).getAttribute("chill") & Chr(176) & Units_Temp
	WindSpeed = xmlData.getElementsByTagName("yweather:wind").item(0).getAttribute("speed") & " " & Units_Spd
	WindDirection = xmlData.getElementsByTagName("yweather:wind").item(0).getAttribute("direction")
	Humidity = xmlData.getElementsByTagName("yweather:atmosphere").item(0).getAttribute("humidity") & " %"
	Visibility = xmlData.getElementsByTagName("yweather:atmosphere").item(0).getAttribute("visibility")
	Pressure = xmlData.getElementsByTagName("yweather:atmosphere").item(0).getAttribute("pressure") & " " & Units_Pres
	Rising = xmlData.getElementsByTagName("yweather:atmosphere").item(0).getAttribute("rising")
	If CInt(Rising) = 0 Then
		Rising = "Steady"
	ElseIf CInt(Rising) = 1 Then
		Rising = "Rising"
	ElseIf CInt(Rising) = 2 Then
		Rising = "Falling"
	End If
	Sunrise = xmlData.getElementsByTagName("yweather:astronomy").item(0).getAttribute("sunrise")
	Sunset = xmlData.getElementsByTagName("yweather:astronomy").item(0).getAttribute("sunset")
	Latitude = xmlData.getElementsByTagName("geo:lat").item(0).text
	Longitude = xmlData.getElementsByTagName("geo:long").item(0).text
	Condition = xmlData.getElementsByTagName("yweather:condition").item(0).getAttribute("text")
	Code = xmlData.getElementsByTagName("yweather:condition").item(0).getAttribute("code")
	If Len(Code) <> 2 Then
		Code = "0" & Code
	End If
	Temperature = xmlData.getElementsByTagName("yweather:condition").item(0).getAttribute("temp") & Chr(176) & Units_Temp
	LastUpdate = xmlData.getElementsByTagName("yweather:condition").item(0).getAttribute("date")
	For I = 0 To 1
		Forecast(I, 0) = xmlData.getElementsByTagName("yweather:forecast").item(I).getAttribute("day")
		Forecast(I, 1) = xmlData.getElementsByTagName("yweather:forecast").item(I).getAttribute("date")
		Forecast(I, 2) = xmlData.getElementsByTagName("yweather:forecast").item(I).getAttribute("low")
		Forecast(I, 3) = xmlData.getElementsByTagName("yweather:forecast").item(I).getAttribute("high")
		Forecast(I, 4) = xmlData.getElementsByTagName("yweather:forecast").item(I).getAttribute("text")
		Forecast(I, 5) = xmlData.getElementsByTagName("yweather:forecast").item(I).getAttribute("code")
		If Len(Forecast(I,5)) <> 2 Then
			Forecast(I,5) = "0" & Forcast(I,5)
		End If
	Next
	Set xmlData = Nothing
End Sub

Private Sub SetHouseBotValues()
	Call SetPropertyValue(".CWVisibility", Visibility)
	Call SetPropertyValue(".CWWindChill", WindChill)
	Call SetPropertyValue(".CWWindSpeed", WindSpeed)
	Call SetPropertyValue(".CWWindDirection", WindDirection)
	Call SetPropertyValue(".CWHumidity", Humidity)
	Call SetPropertyValue(".CWBarometer", Pressure)
	Call SetPropertyValue(".CWRising", Rising)
	Call SetPropertyValue(".CWWeather", Condition)
	Call SetPropertyValue(".CWTemperature", Temperature)
	Call SetPropertyValue(".CWLocation", City & ", " & State & " (" & Country & ")")
	Call SetPropertyValue(".CWTime", LastUpdate)
	Call SetPropertyValue(".CWWeatherNumber", "C:\Program Files\HouseBot\Config\Themes\Weather Images\" & Code & ".png")
	Call SetPropertyValue(".CWDay", Forecast(0,0))
	Call SetPropertyValue(".CWDate", Forecast(0,1))
	Call SetPropertyValue(".CWLow", Forecast(0,2) & Chr(176) & Units_Temp)
	Call SetPropertyValue(".CWHigh", Forecast(0,3) & Chr(176) & Units_Temp)
	Call SetPropertyValue(".CWForecastDay", Forecast(1,0))
	Call SetPropertyValue(".CWForecastDate", Forecast(1,1))
	Call SetPropertyValue(".CWForecastLow", Forecast(1,2) & Chr(176) & Units_Temp)
	Call SetPropertyValue(".CWForecastHigh", Forecast(1,3) & Chr(176) & Units_Temp)
	Call SetPropertyValue(".CWForecastWeather", Forecast(1,4))
	Call SetPropertyValue(".CWForecastWeatherNumber", "C:\Program Files\HouseBot\Config\Themes\Weather Images\" & Forecast(1,5) & ".png")
End Sub
Osler
HouseBot Guru
Posts: 742
Joined: Fri Feb 03, 2006 11:18 pm

Re: Weather.com Plug-in

Post by Osler »

Need to add all of these to the condition code library:

http://www.nws.noaa.gov/xml/xml_fields_ ... itions.php

Link to current copy of file in process:

http://dl.dropbox.com/u/6349054/Yahoo_NOAA_Weather.vbs

Osler
markd
Advanced Member
Posts: 234
Joined: Fri Jul 21, 2006 4:32 pm

Re: Weather.com Plug-in

Post by markd »

Steve Horn wrote:Works for me. But if the script is limited to the scope of the current weather.com feed the current HB device and properties can be "reused", thus not having to create a new HB device and properties (and redo panel controls for those new properties). Just a thought. Adding a bunch of new properties to a device is cumbersome IMO.
At one point I was hacking the files in the import to allow much quicker adds. I'll have to do that again- it was way tedious to build the device for just the few fields it has. Once the import is ready, we can put it up here along with the script and icons, one nice neat package.
Post Reply