Weather.com Plug-in
-
- HouseBot Guru
- Posts: 757
- Joined: Wed Apr 02, 2003 8:10 pm
- Location: Pelham AL
Re: Weather.com Plug-in
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
Re: Weather.com Plug-in
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
Osler
-
- HouseBot Guru
- Posts: 757
- Joined: Wed Apr 02, 2003 8:10 pm
- Location: Pelham AL
Re: Weather.com Plug-in
I haven't looked at the Yahoo data yet. I figured it would need to be two different VBScript parsing routines anyway.
Steve
Re: Weather.com Plug-in
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:
Osler
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
Re: Weather.com Plug-in
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
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
-
- HouseBot Guru
- Posts: 757
- Joined: Wed Apr 02, 2003 8:10 pm
- Location: Pelham AL
Re: Weather.com Plug-in
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.
(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
Re: Weather.com Plug-in
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.
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.
Re: Weather.com Plug-in
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
Osler
Re: Weather.com Plug-in
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
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
-
- HouseBot Guru
- Posts: 757
- Joined: Wed Apr 02, 2003 8:10 pm
- Location: Pelham AL
Re: Weather.com Plug-in
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.
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
Re: Weather.com Plug-in
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.
-
- HouseBot Guru
- Posts: 757
- Joined: Wed Apr 02, 2003 8:10 pm
- Location: Pelham AL
Re: Weather.com Plug-in
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
Re: Weather.com Plug-in
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:
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
Re: Weather.com Plug-in
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
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
Re: Weather.com Plug-in
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.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.